10 #include <ecl/geometry/ECLNeighbours.h>
11 #include <ecl/geometry/ECLGeometryPar.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/gearbox/Unit.h>
28 std::vector<short int> fakeneighbours;
29 fakeneighbours.push_back(0);
32 int parToInt = int(par);
35 if (neighbourDef ==
"N") {
36 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n: " << parToInt * 2 + 1 <<
" x " << parToInt * 2
38 if ((parToInt >= 0) and (parToInt < 11))
initializeN(parToInt);
39 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << parToInt <<
" is an invalid parameter (must be between 0 and 10)!");
40 }
else if (neighbourDef ==
"NC") {
41 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n (minus corners): " << parToInt * 2 + 1 <<
" x "
44 if ((parToInt >= 0) and (parToInt < 11))
initializeNC(parToInt);
45 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << parToInt <<
" is an invalid parameter (must be between 0 and 10)!");
46 }
else if (neighbourDef ==
"NLegacy") {
47 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n: " << parToInt * 2 + 1 <<
" x " << parToInt * 2
50 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << parToInt <<
" is an invalid parameter (must be between 0 and 10)!");
51 }
else if (neighbourDef ==
"NCLegacy") {
52 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", n x n (minus corners): " << parToInt * 2 + 1 <<
" x "
56 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << parToInt <<
" is an invalid parameter (must be between 0 and 10)!");
59 else if (neighbourDef ==
"R") {
60 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", radius: " << par <<
" cm");
62 else B2FATAL(
"ECLNeighbours::ECLNeighbours: " << par <<
" is an invalid parameter (must be between 0 cm and 30 cm)!");
65 else if (neighbourDef ==
"F") {
66 double parChecked = par;
67 if (parChecked > 1.0) parChecked = 1.0;
68 else if (parChecked < 0.1) parChecked = 0.1;
69 B2DEBUG(150,
"ECLNeighbours::ECLNeighbours: initialize " << neighbourDef <<
", fraction: " << parChecked);
74 B2FATAL(
"ECLNeighbours::ECLNeighbours (constructor via std::string): Invalid option: " << neighbourDef <<
75 " (valid: N(n), NC(n), NLegacy(n), NCLegacy(n), R ( with R<30 cm), F (with 0.1<f<1)");
88 std::vector<short int> fakeneighbours;
89 fakeneighbours.push_back(0);
98 for (
int i = 0; i < 8736; i++) {
100 TVector3 direction = geom->GetCrystalVec(i);
101 TVector3 position = geom->GetCrystalPos(i);
105 std::vector<short int> neighboursTemp;
108 for (
auto const&
id : neighbours) {
109 const TVector3& directionNeighbour = geom->GetCrystalVec(
id - 1);
110 const double alpha = direction.Angle(directionNeighbour);
111 const double R = position.Mag();
114 if (distance <= radius) neighboursTemp.push_back(
id);
130 for (
int i = 0; i < 8736; i++) {
132 std::vector<short int> neighbours;
136 const short tid = geom->GetThetaID();
137 const short pid = geom->GetPhiID();
142 neighbours.push_back(geom->GetCellID(tid , pid) + 1);
143 neighbours.push_back(geom->GetCellID(tid , phiInc) + 1);
144 neighbours.push_back(geom->GetCellID(tid , phiDec) + 1);
149 short int tidinner = tid - 1;
160 const double dist = fabs(fracPos - f);
165 n1 = geom->GetCellID(tidinner, inner);
167 }
else if (dist < dist2) {
169 n2 = geom->GetCellID(tidinner, inner);
179 neighbours.push_back(n1 + 1);
180 if (cov < frac - 1e-4) neighbours.push_back(n2 + 1);
184 short int tidouter = tid + 1;
185 if (tidouter <= 68) {
187 double disto1 = 999.;
188 short int pido1 = -1;
190 double disto2 = 999.;
194 const double dist = fabs(fracPos - f);
199 no1 = geom->GetCellID(tidouter, outer);
201 }
else if (dist < disto2) {
203 no2 = geom->GetCellID(tidouter, outer);
212 neighbours.push_back(no1 + 1);
213 if (cov < frac - 1e-4) {
214 neighbours.push_back(no2 + 1);
227 for (
int i = 0; i < 8736; i++) {
230 std::vector<short int> neighbours;
231 neighbours.push_back(i + 1);
233 std::vector<short int> neighbours_temp;
236 for (
int idx = 0; idx < n; idx++) {
238 for (
const auto& nbr : neighbours) {
240 for (std::vector<EclNbr::Identifier>::const_iterator newnbr = aNbr.
nearBegin(); newnbr != aNbr.
nearEnd(); ++newnbr) {
241 neighbours_temp.push_back(((
short) *newnbr) + 1);
246 sort(neighbours_temp.begin(), neighbours_temp.end());
247 neighbours_temp.erase(unique(neighbours_temp.begin(), neighbours_temp.end()), neighbours_temp.end());
248 neighbours.insert(neighbours.end(), neighbours_temp.begin(), neighbours_temp.end());
252 sort(neighbours.begin(), neighbours.end());
253 neighbours.erase(unique(neighbours.begin(), neighbours.end()), neighbours.end());
266 for (
int i = 0; i < 8736; i++) {
268 std::vector<short int> neighbours_temp;
271 const int centerthetaid = geom->GetThetaID();
273 for (
const auto& nbr : neighbours) {
274 geom->Mapping(nbr - 1);
275 const int thetaid = geom->GetThetaID();
277 if (abs(thetaid - centerthetaid) == n) {
278 const short int phiInc =
increasePhiId(geom->GetPhiID(), geom->GetThetaID(), 1);
279 const short int phiDec =
decreasePhiId(geom->GetPhiID(), geom->GetThetaID(), 1);
280 const int cid1 = geom->GetCellID(thetaid , phiInc) + 1;
281 const int cid2 = geom->GetCellID(thetaid , phiDec) + 1;
284 if (!((std::find(neighbours.begin(), neighbours.end(), cid1) != neighbours.end()) and
285 (std::find(neighbours.begin(), neighbours.end(), cid2) != neighbours.end()))) {
289 neighbours_temp.push_back(nbr);
306 for (
int i = 0; i < 8736; i++) {
309 std::vector<short int> neighbours;
313 const short tid = geom->GetThetaID();
314 const short pid = geom->GetPhiID();
319 const double fractionalPhiInc =
static_cast < double >(phiInc) /
m_crystalsPerRing [ tid ];
320 const double fractionalPhiDec =
static_cast < double >(phiDec) /
m_crystalsPerRing [ tid ];
323 for (
int theta = tid - n; theta <= tid + n; theta++) {
324 if ((theta > 68) || (theta < 0))
continue;
326 short int thisPhiInc = std::lround(fractionalPhiInc *
m_crystalsPerRing [ theta ]);
328 short int thisPhiDec = std::lround(fractionalPhiDec *
m_crystalsPerRing [ theta ]);
331 const std::vector<short int> phiList =
getPhiIdsInBetween(thisPhiInc, thisPhiDec, theta);
333 for (
unsigned int k = 0; k < phiList.size(); ++k) {
334 neighbours.push_back(geom->GetCellID(theta , phiList.at(k)) + 1);
352 for (
int i = 0; i < 8736; i++) {
355 std::vector<short int> neighbours;
359 const short tid = geom->GetThetaID();
360 const short pid = geom->GetPhiID();
365 const double fractionalPhiInc =
static_cast < double >(phiInc) /
m_crystalsPerRing [ tid ];
366 const double fractionalPhiDec =
static_cast < double >(phiDec) /
m_crystalsPerRing [ tid ];
369 for (
int theta = tid - n; theta <= tid + n; theta++) {
370 if ((theta > 68) || (theta < 0))
continue;
372 short int thisPhiInc = std::lround(fractionalPhiInc *
m_crystalsPerRing [ theta ]);
374 short int thisPhiDec = std::lround(fractionalPhiDec *
m_crystalsPerRing [ theta ]);
377 std::vector<short int> phiList;
378 if ((theta == tid - n) or (theta == tid + n)) phiList =
getPhiIdsInBetweenC(thisPhiInc, thisPhiDec, theta, corners);
379 else if (corners == 2 and ((theta == tid - n + 1)
380 or (theta == tid + n - 1))) phiList =
getPhiIdsInBetweenC(thisPhiInc, thisPhiDec, theta, 1);
383 for (
unsigned int k = 0; k < phiList.size(); ++k) {
384 neighbours.push_back(geom->GetCellID(theta , phiList.at(k)) + 1);
402 short int previousPhiId = ((phiid - n < 0) ?
m_crystalsPerRing[thetaid] + phiid - n : phiid - n);
403 return previousPhiId;
416 std::vector<short int> phiList;
417 short int loop = phi0;
420 phiList.push_back(loop);
421 if (loop == phi1)
break;
431 std::vector<short int> phiList;
432 if (phi0 == phi1)
return phiList;
435 if (loop == phi1)
return phiList;
440 phiList.push_back(loop);
441 if (loop == stop)
break;
450 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
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 initializeN(const int nneighbours)
initialize the mask neighbour list.
ECLNeighbours(const std::string &neighbourDef, const double par)
Constructor: Fix number of neighbours ("N") in the seed theta ring, fraction cross ("F"),...
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 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.
Abstract base class for different kinds of events.