10#include <ecl/dataobjects/ECLElementNumbers.h>
11#include <ecl/geometry/ECLNeighbours.h>
12#include <ecl/geometry/ECLGeometryPar.h>
15#include <framework/gearbox/Unit.h>
16#include <framework/logging/Logger.h>
19#include <Math/Vector3D.h>
20#include <Math/VectorUtil.h>
33 std::vector<short int> fakeneighbours;
34 fakeneighbours.push_back(0);
37 int parToInt = int(par);
40 if (neighbourDef ==
"N") {
41 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n: " << parToInt * 2 + 1 <<
" x " << parToInt * 2
43 if ((parToInt >= 0) and (parToInt < 11))
initializeN(parToInt, sorted);
44 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " <<
LogVar(
"parameter", parToInt) <<
"Invalid parameter (must be between 0 and 10)!");
45 }
else if (neighbourDef ==
"NC") {
46 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n (minus corners): " << parToInt * 2 + 1 <<
" x "
49 if ((parToInt >= 0) and (parToInt < 11))
initializeNC(parToInt);
50 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " <<
LogVar(
"parameter", parToInt) <<
"Invalid parameter (must be between 0 and 10)!");
51 }
else if (neighbourDef ==
"NLegacy") {
52 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n: " << parToInt * 2 + 1 <<
" x " << parToInt * 2
55 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " <<
LogVar(
"parameter", parToInt) <<
"Invalid parameter (must be between 0 and 10)!");
56 }
else if (neighbourDef ==
"NCLegacy") {
57 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n (minus corners): " << parToInt * 2 + 1 <<
" x "
61 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " <<
LogVar(
"parameter", parToInt) <<
"Invalid parameter (must be between 0 and 10)!");
64 else if (neighbourDef ==
"R") {
65 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", radius: " << par <<
" cm");
67 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << par <<
" is an invalid parameter (must be between 0 cm and 30 cm)!");
70 else if (neighbourDef ==
"F") {
71 double parChecked = par;
72 if (parChecked > 1.0) parChecked = 1.0;
73 else if (parChecked < 0.1) parChecked = 0.1;
74 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", fraction: " << parChecked);
79 B2FATAL(
"ECLNeighbours::ECLNeighbours (constructor via std::string): Invalid option: " << neighbourDef <<
80 " (valid: N(n), NC(n), NLegacy(n), NCLegacy(n), R ( with R<30 cm), F (with 0.1<f<1)");
93 std::vector<short int> fakeneighbours;
94 fakeneighbours.push_back(0);
105 ROOT::Math::XYZVector direction = geom->GetCrystalVec(i);
106 ROOT::Math::XYZVector position = geom->GetCrystalPos(i);
110 std::vector<short int> neighboursTemp;
113 for (
auto const&
id : neighbours) {
114 const ROOT::Math::XYZVector& directionNeighbour = geom->GetCrystalVec(
id - 1);
115 const double alpha = ROOT::Math::VectorUtil::Angle(
116 direction, directionNeighbour);
117 const double R = position.R();
120 if (distance <= radius) neighboursTemp.push_back(
id);
138 std::vector<short int> neighbours;
142 const short tid = geom->GetThetaID();
143 const short pid = geom->GetPhiID();
148 neighbours.push_back(geom->GetCellID(tid, pid) + 1);
149 neighbours.push_back(geom->GetCellID(tid, phiInc) + 1);
150 neighbours.push_back(geom->GetCellID(tid, phiDec) + 1);
155 short int tidinner = tid - 1;
166 const double dist = std::abs(fracPos - f);
171 n1 = geom->GetCellID(tidinner, inner);
173 }
else if (dist < dist2) {
175 n2 = geom->GetCellID(tidinner, inner);
185 neighbours.push_back(n1 + 1);
186 if (cov < frac - 1e-4) neighbours.push_back(n2 + 1);
190 short int tidouter = tid + 1;
191 if (tidouter <= 68) {
193 double disto1 = 999.;
194 short int pido1 = -1;
196 double disto2 = 999.;
200 const double dist = std::abs(fracPos - f);
205 no1 = geom->GetCellID(tidouter, outer);
207 }
else if (dist < disto2) {
209 no2 = geom->GetCellID(tidouter, outer);
218 neighbours.push_back(no1 + 1);
219 if (cov < frac - 1e-4) {
220 neighbours.push_back(no2 + 1);
236 std::vector<short int> neighbours;
237 neighbours.push_back(i + 1);
239 std::vector<short int> neighbours_temp;
242 for (
int idx = 0; idx < n; idx++) {
244 for (
const auto& nbr : neighbours) {
246 for (std::vector<EclNbr::Identifier>::const_iterator newnbr = aNbr.
nearBegin(); newnbr != aNbr.
nearEnd(); ++newnbr) {
247 neighbours_temp.push_back(((
short) *newnbr) + 1);
252 sort(neighbours_temp.begin(), neighbours_temp.end());
253 neighbours_temp.erase(unique(neighbours_temp.begin(), neighbours_temp.end()), neighbours_temp.end());
254 neighbours.insert(neighbours.end(), neighbours_temp.begin(), neighbours_temp.end());
258 sort(neighbours.begin(), neighbours.end());
259 neighbours.erase(unique(neighbours.begin(), neighbours.end()), neighbours.end());
262 if (sorted ==
true) {
276 std::vector<crystal> crystals;
277 for (
const auto& nbr : neighbours) {
278 geom->Mapping(nbr - 1);
279 crystals.push_back({nbr, geom->GetPhiID(), geom->GetThetaID(), n});
283 std::sort(crystals.begin(), crystals.end(), [](
const auto & left,
const auto & right) {
285 if (left.thetaid < right.thetaid) return true;
286 if (left.thetaid > right.thetaid) return false;
293 if (std::abs(left.phiid - right.phiid) > (2 * left.neighbourn + 1)) {
294 return right.phiid > left.phiid;
296 return left.phiid > right.phiid;
304 for (
int nbidx = 0; nbidx < int(neighbours.size()); nbidx++) {
305 neighbours[nbidx] = crystals[nbidx].cellid;
324 std::vector<short int> neighbours_temp;
327 const int centerthetaid = geom->GetThetaID();
329 for (
const auto& nbr : neighbours) {
330 geom->Mapping(nbr - 1);
331 const int thetaid = geom->GetThetaID();
333 if (std::abs(thetaid - centerthetaid) == n) {
334 const short int phiInc =
increasePhiId(geom->GetPhiID(), geom->GetThetaID(), 1);
335 const short int phiDec =
decreasePhiId(geom->GetPhiID(), geom->GetThetaID(), 1);
336 const int cid1 = geom->GetCellID(thetaid, phiInc) + 1;
337 const int cid2 = geom->GetCellID(thetaid, phiDec) + 1;
340 if (!((std::find(neighbours.begin(), neighbours.end(), cid1) != neighbours.end()) and
341 (std::find(neighbours.begin(), neighbours.end(), cid2) != neighbours.end()))) {
345 neighbours_temp.push_back(nbr);
365 std::vector<short int> neighbours;
369 const short tid = geom->GetThetaID();
370 const short pid = geom->GetPhiID();
375 const double fractionalPhiInc =
static_cast < double >(phiInc) /
m_crystalsPerRing [ tid ];
376 const double fractionalPhiDec =
static_cast < double >(phiDec) /
m_crystalsPerRing [ tid ];
379 for (
int theta = tid - n; theta <= tid + n; theta++) {
380 if ((theta > 68) || (theta < 0))
continue;
382 short int thisPhiInc = std::lround(fractionalPhiInc *
m_crystalsPerRing [ theta ]);
384 short int thisPhiDec = std::lround(fractionalPhiDec *
m_crystalsPerRing [ theta ]);
387 const std::vector<short int> phiList =
getPhiIdsInBetween(thisPhiInc, thisPhiDec, theta);
389 for (
unsigned int k = 0; k < phiList.size(); ++k) {
390 neighbours.push_back(geom->GetCellID(theta, phiList.at(k)) + 1);
411 std::vector<short int> neighbours;
415 const short tid = geom->GetThetaID();
416 const short pid = geom->GetPhiID();
421 const double fractionalPhiInc =
static_cast < double >(phiInc) /
m_crystalsPerRing [ tid ];
422 const double fractionalPhiDec =
static_cast < double >(phiDec) /
m_crystalsPerRing [ tid ];
425 for (
int theta = tid - n; theta <= tid + n; theta++) {
426 if ((theta > 68) || (theta < 0))
continue;
428 short int thisPhiInc = std::lround(fractionalPhiInc *
m_crystalsPerRing [ theta ]);
430 short int thisPhiDec = std::lround(fractionalPhiDec *
m_crystalsPerRing [ theta ]);
433 std::vector<short int> phiList;
434 if ((theta == tid - n) or (theta == tid + n)) phiList =
getPhiIdsInBetweenC(thisPhiInc, thisPhiDec, theta, corners);
435 else if (corners == 2 and ((theta == tid - n + 1)
436 or (theta == tid + n - 1))) phiList =
getPhiIdsInBetweenC(thisPhiInc, thisPhiDec, theta, 1);
439 for (
unsigned int k = 0; k < phiList.size(); ++k) {
440 neighbours.push_back(geom->GetCellID(theta, phiList.at(k)) + 1);
458 short int previousPhiId = ((phiid - n < 0) ?
m_crystalsPerRing[thetaid] + phiid - n : phiid - n);
459 return previousPhiId;
472 std::vector<short int> phiList;
473 short int loop = phi0;
476 phiList.push_back(loop);
477 if (loop == phi1)
break;
487 std::vector<short int> phiList;
488 if (phi0 == phi1)
return phiList;
491 if (loop == phi1)
return phiList;
496 phiList.push_back(loop);
497 if (loop == stop)
break;
506 return 2.0 *
R * TMath::Sin(alpha / 2.0);
The Class for ECL Geometry Parameters.
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
std::vector< short int > getPhiIdsInBetweenC(const short int phiInc, const short int phiDec, const short int theta, const int corners)
return a list of phi ids between two phi ids minus edges
ECLNeighbours(const std::string &neighbourDef, const double par, const bool sorted=false)
Constructor: Fix number of neighbours ("N") in the seed theta ring, fraction cross ("F"),...
const std::vector< short int > & getNeighbours(short int cid) const
Return the neighbours for a given cell ID.
const short m_crystalsPerRing[69]
Number of crystals in each theta ring.
void initializeNCLegacy(const int nneighbours, const int corners)
initialize the mask neighbour list, remove corners, legacy code.
void initializeF(const double fraction)
initialize the fractional cross neighbour list.
void initializeR(const double radius)
initialize the radius neighbour list.
std::vector< std::vector< short int > > m_neighbourMapTemp
temporary list of list of neighbour cids.
short int increasePhiId(const short int phiid, const short int thetaid, const short int n)
return the next phi id.
std::vector< std::vector< short int > > m_neighbourMap
list of list of neighbour cids.
std::vector< short int > getPhiIdsInBetween(const short int phiInc, const short int phiDec, const short int theta)
return a list of phi ids between two phi ids
void initializeNC(const int nneighbours)
initialize the mask neighbour list, remove corners.
~ECLNeighbours()
Destructor.
void initializeN(const int nneighbours, const bool sorted=false)
initialize the mask neighbour list.
void initializeNLegacy(const int nneighbours)
initialize the mask neighbour list, legacy code.
double getDistance(const double alpha, const double R)
return the chord length between cells
short int decreasePhiId(const short int phiid, const short int thetaid, const short int n)
return the previous phi id.
EclNbr getNbr(const Identifier aCellId)
get crystals nbr
const std::vector< Identifier >::const_iterator nearEnd() const
get crystals nearEnd
const std::vector< Identifier >::const_iterator nearBegin() const
get crystals nearBegin
static const double cm
Standard units with the value = 1.
Class to store variables with their name which were sent to the logging service.
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.