Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TrackingVolumeArrayCreator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // TrackingVolumeArrayCreator.cxx, (c) ATLAS Detector software
8 
9 // Trk include
10 #include <cmath>
11 #include <algorithm>
12 
26 // Amg
28 
29 namespace {
31  inline std::vector<VolumePtr> translateToShared(const std::vector<Trk::TrackingVolume*>& inVols,
32  bool no_deletePtr) {
33  std::vector<VolumePtr> outVec{};
34  outVec.reserve(inVols.size());
35  for (Trk::TrackingVolume* vol : inVols) {
36  if(!no_deletePtr) {
37  outVec.emplace_back(vol);
38  } else {
39  outVec.emplace_back(vol, Trk::do_not_delete<Trk::TrackingVolume>);
40  }
41  }
42  return outVec;
43  }
44 }
45 
46 
47 namespace Trk{
48 // constructor
50  const std::string& n,
51  const IInterface* p)
52  : AthAlgTool(t, n, p)
53 {
54  declareInterface<ITrackingVolumeArrayCreator>(this);
55 }
56 
57 // destructor
59 
61  bool navtype) const {
62  return cylinderVolumesArrayInR(translateToShared(vols, navtype), navtype).release();
63 }
64 std::unique_ptr<TrackingVolumeArray> TrackingVolumeArrayCreator::cylinderVolumesArrayInR(const std::vector<VolumePtr>& vols,
65  bool navtype) const {
66 
67 
68  ATH_MSG_VERBOSE("Create VolumeArray of "<< vols.size() << " Volumes (with CylinderVolumeBounds) with R-binning. ");
69 
70  // check for compatibility - needs r-sorting first
71  double lastZmin{0.}, lastZmax{0.}, lastOuterRadius{0.};
72 
73  // the vector of doubles for identification
74  std::vector<float> boundaries;
75  boundaries.reserve(vols.size() + 1);
76 
77  // the vector needed for the BinnedArray
78  std::vector<TrackingVolumeOrderPosition> volOrder;
79  // loop over volumes and fill primaries
80  auto volIter = vols.begin();
81  for (unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
82  const CylinderVolumeBounds* currentCylBounds = nullptr;
83  if (*volIter) currentCylBounds = dynamic_cast<const CylinderVolumeBounds*>(&((*volIter)->volumeBounds()));
84  if (!currentCylBounds) {
85  ATH_MSG_ERROR("Given TrackingVolume doesn't exist or is not of shape "
86  "'CylinderVolumeBounds': return 0");
87  return nullptr;
88  }
89  // current rmin/rmax
90  double currentRmin = currentCylBounds->innerRadius();
91  double currentRmax = currentCylBounds->outerRadius();
92  if (!ivol)
93  boundaries.push_back(currentRmin);
94  boundaries.push_back(currentRmax);
95 
96  // compatibility checks
97  double currentZmin = (*volIter)->center().z() - currentCylBounds->halflengthZ();
98  double currentZmax = (*volIter)->center().z() + currentCylBounds->halflengthZ();
99 
100  // check for compatibility of the new volume - not for navigation type
101  if (ivol && !navtype) {
102  // longitudinal clinch
103  if (std::abs(currentZmin - lastZmin) > 0.1 || std::abs(currentZmax - lastZmax) > 0.1) {
104  ATH_MSG_ERROR("Given TrackingVolume(s) do not extend in z to the same point (required) : return 0");
105  ATH_MSG_VERBOSE("Information : lastZmin / lastZmin = "<< lastZmin << " / " << currentZmin);
106  ATH_MSG_VERBOSE(" lastZmax / currentZmax = "<< lastZmax << " / " << currentZmax);
107  return nullptr;
108  }
109  // radial clinch
110  if (std::abs(currentRmin - lastOuterRadius) > 0.1) {
111  ATH_MSG_ERROR("Given TrackingVolume(s) are not wrapping, neither inside-out, nor v.v. : return 0");
112  ATH_MSG_VERBOSE("Information : currentRmin / lastOuterRadius = "<< currentRmin << " / " << lastOuterRadius);
113  return nullptr;
114  }
115  }
116  // register for next round
117  lastZmin = currentZmin;
118  lastZmax = currentZmax;
119  lastOuterRadius = currentRmax;
120  // output
121  ATH_MSG_VERBOSE("Adding Volume '" << (*volIter)->volumeName() << "' to Array");
122 
123  volOrder.emplace_back((*volIter), currentCylBounds->mediumRadius() * Amg::Vector3D::UnitX());
124  // push back the volume order position
125 
126  }
127  if (!volOrder.empty()) {
128  auto volBinUtilR = BinUtility(boundaries, open, binR);
129  ATH_MSG_VERBOSE("Return created Array. ");
130  return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtilR);
131  }
132  ATH_MSG_ERROR("No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
133  return nullptr;
134 }
135 
136 
138  bool navtype) const {
139  return cylinderVolumesArrayInZ(translateToShared(vols, navtype), navtype).release();
140  }
141 
142 std::unique_ptr<TrackingVolumeArray>
143  TrackingVolumeArrayCreator::cylinderVolumesArrayInZ(const std::vector<VolumePtr>& vols,
144  bool navtype) const {
145  ATH_MSG_VERBOSE("Create VolumeArray of "
146  << vols.size()
147  << " Volumes (with CylinderVolumeBounds) with Z-binning. ");
148 
149  // for compatibility checks
150  double lastRmin{0.}, lastRmax{0.}, lastZmax{0.};
151 
152  // the vector of doubles for identification
153  std::vector<float> boundaries;
154  boundaries.reserve(vols.size() + 1);
155 
156  // the vector needed for the BinnedArray
157  std::vector<TrackingVolumeOrderPosition> volOrder;
158  // loop over volumes and fill primaries
159  auto volIter = vols.begin();
160  for (unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
161  const CylinderVolumeBounds* currentCylBounds = nullptr;
162  if (*volIter)currentCylBounds = dynamic_cast<const CylinderVolumeBounds*>( &((*volIter)->volumeBounds()));
163  if (!currentCylBounds) {
164  ATH_MSG_ERROR("Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
165  return nullptr;
166  }
167  //
168  const Amg::Vector3D& volCenter = (*volIter)->center();
169  double halflengthZ = currentCylBounds->halflengthZ();
170  // get the numbers
171  double currentZmin = volCenter.z() - halflengthZ;
172  double currentZmax = volCenter.z() + halflengthZ;
173  if (!ivol) boundaries.push_back(currentZmin);
174  boundaries.push_back(currentZmax);
175 
176  // consistency checks
177  double currentRmin = currentCylBounds->innerRadius();
178  double currentRmax = currentCylBounds->outerRadius();
179 
180  // compatibility check - not for navtype
181  if (ivol && !navtype) {
182  // first the radial check
183  if (std::abs(lastRmin - currentRmin) > 0.1 || std::abs(lastRmax - currentRmax) > 0.1) {
184  ATH_MSG_ERROR("Given TrackingVolume(s) do not have same radial extends (required): return 0");
185  ATH_MSG_VERBOSE("Information : lastRmin / currentRmin = " << lastRmin << " / " << currentRmin);
186  ATH_MSG_VERBOSE(" lastRmax / currentRmax = " << lastRmax << " / " << currentRmax);
187  return nullptr;
188  }
189  // then let's see whether they leave gaps in z
190  if (std::abs(lastZmax - currentZmin) > 0.1) {
191  ATH_MSG_ERROR("Given TrackingVolume(s) are not attaching in z (required) : return 0");
192  return nullptr;
193  }
194  }
195  // for the next round
196  lastRmin = currentRmin;
197  lastRmax = currentRmax;
198  lastZmax = currentZmax;
199  // output
200  ATH_MSG_VERBOSE("Adding Volume '" << (*volIter)->volumeName()
201  << "' to Array");
202  // push back the volume order position
203  volOrder.emplace_back((*volIter), (*volIter)->center());
204 
205  }
206  if (!volOrder.empty()) {
207  auto volBinUtil = BinUtility(boundaries, open, binZ);
208  ATH_MSG_VERBOSE("Return created Array. ");
209  return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
210  }
211  ATH_MSG_ERROR("No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
212  return nullptr;
213 }
214 
216  bool navtype) const {
217  return cylinderVolumesArrayInPhi(translateToShared(vols,navtype), navtype).release();
218 }
219 
220 std::unique_ptr<TrackingVolumeArray>
221  TrackingVolumeArrayCreator::cylinderVolumesArrayInPhi(const std::vector<VolumePtr>& vols,
222  bool /*navtype*/) const {
223 
224  ATH_MSG_VERBOSE("Create VolumeArray of " << vols.size()
225  << " Volumes (with CylinderVolumeBounds) with Phi-binning. ");
226 
227  // phi binning; assume equidistant
228  int nPhiBins = !vols.empty() ? vols.size() : 1;
229  double phi = M_PI;
230  // the vector needed for the BinnedArray
231  std::vector<TrackingVolumeOrderPosition> volOrder;
232  // loop over volumes and fill primaries
233  auto volIter = vols.begin();
234  for (; volIter != vols.end(); ++volIter) {
235  const CylinderVolumeBounds* cyl = nullptr;
236  if (*volIter) cyl = dynamic_cast<const CylinderVolumeBounds*>(&((*volIter)->volumeBounds()));
237  if (!cyl) {
238  ATH_MSG_ERROR("Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
239  return nullptr;
240  }
241  // output
242  ATH_MSG_VERBOSE("Adding Volume '" << (*volIter)->volumeName()<< "' to Array");
243  // push back the volume order position
244  volOrder.emplace_back((*volIter), (*volIter)->transform() * (cyl->mediumRadius() * Amg::Vector3D::UnitX()));
245 
246  }
247  if (!volOrder.empty()) {
248  auto volBinUtil = BinUtility(nPhiBins, -phi, +phi, closed, binPhi);
249  return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
250  }
251  ATH_MSG_ERROR("No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
252  return nullptr;
253 }
254 
256  TrackingVolumeArrayCreator::cylinderVolumesArrayInPhiR(const std::vector<TrackingVolume*>& vols,
257  bool navtype) const {
258  return cylinderVolumesArrayInPhiR(translateToShared(vols, navtype), navtype).release();
259 }
260 std::unique_ptr<TrackingVolumeArray>
262  bool navtype) const {
263  if (vols.empty())
264  return nullptr;
265 
266  const bool bevelled = std::find_if(vols.begin(),vols.end(),
267  [](const VolumePtr& ptr) -> bool {
268  return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
269  }) != vols.end();
270 
271  double tol = 0.001;
272 
273  // the vector needed for the BinnedArray
274  std::vector<TrackingVolumeOrderPosition> volOrder;
275 
276  if (bevelled) {
277  ATH_MSG_VERBOSE("Create 2dim VolumeArray of "<< vols.size()
278  << " Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
279  std::vector<float> phiSteps;
280  std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
281  volPos;
282  std::vector<VolumePtr> fullPhiVols;
283 
284  for (const VolumePtr& vol : vols) {
285  const auto *cyl = dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
286  const auto *bcyl =dynamic_cast<const BevelledCylinderVolumeBounds*>(&(vol->volumeBounds()));
287  double rmin{0.}, rmax{0.}, dphi{0.}, mRad{0.};
288  int type = 0;
289 
290  if (cyl) {
291  rmin = cyl->innerRadius();
292  rmax = cyl->outerRadius();
293  dphi = cyl->halfPhiSector();
294  mRad = cyl->mediumRadius();
295  } else if (bcyl) {
296  rmin = bcyl->innerRadius();
297  rmax = bcyl->outerRadius();
298  dphi = bcyl->halfPhiSector();
299  mRad = bcyl->mediumRadius();
300  type = bcyl->type();
301  } else {
302  ATH_MSG_ERROR("volume not cylinder nor bevelled cylinder ");
303  return nullptr;
304  }
305 
306  if (dphi < M_PI) {
307  // push back the volume order position
308  Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
309  volOrder.emplace_back(vol, ngp);
310 
311  // push back volume position to avoid another loop
312  volPos.emplace_back(std::pair<double, int>(ngp.phi(), type),
313  std::pair<double, double>(rmin, rmax));
314  // phi binning
315  double phi1 = ngp.phi() - dphi;
316  double phi2 = ngp.phi() + dphi;
317  if (phi1 < -2 * M_PI) {
318  phi1 += 2 * M_PI;
319  } if (phi2 < -2 * M_PI) {
320  phi2 += 2 * M_PI;
321  } if (phi1 > 2 * M_PI) {
322  phi1 -= 2 * M_PI;
323  } if (phi2 > 2 * M_PI) {
324  phi2 -= 2 * M_PI;
325  }
326 
327  if (!phiSteps.empty()) {
328  std::vector<float>::iterator iter = phiSteps.begin();
329  bool known = false;
330  while (iter != phiSteps.end()) {
331  if (std::abs(phi1 - (*iter)) < tol) {
332  known = true;
333  break;
334  }
335  if (phi1 < (*iter)) {
336  phiSteps.insert(iter, phi1);
337  known = true;
338  break;
339  }
340  ++iter;
341  }
342  if (!known)
343  phiSteps.push_back(phi1);
344  iter = phiSteps.begin();
345  known = false;
346  while (iter != phiSteps.end()) {
347  if (std::abs(phi2 - (*iter)) < tol) {
348  known = true;
349  break;
350  }
351  if (phi2 < (*iter)) {
352  phiSteps.insert(iter, phi2);
353  known = true;
354  break;
355  }
356  ++iter;
357  }
358  if (!known)
359  phiSteps.push_back(phi2);
360  } else {
361  phiSteps.push_back(fmin(phi1, phi2));
362  phiSteps.push_back(fmax(phi1, phi2));
363  }
364  } else {
365  fullPhiVols.push_back(vol);
366  }
367  } // end of first loop over volumes
368  // collect volumes with full phi range
369  if (phiSteps.empty()) {
370  phiSteps.push_back(-M_PI);
371  phiSteps.push_back(+M_PI);
372  }
373  for (auto & fullPhiVol : fullPhiVols) {
374  const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(fullPhiVol->volumeBounds()));
375  if (!cyl) {
376  ATH_MSG_WARNING("dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
377  continue;
378  }
379  double rmin = cyl->innerRadius();
380  double rmax = cyl->outerRadius();
381 
382  for (unsigned int iphi = 0; iphi < phiSteps.size(); ++iphi) {
383  // reference position
384  double phiRef = 0.5 * phiSteps[iphi];
385  if (iphi < phiSteps.size() - 1)
386  phiRef += 0.5 * phiSteps[iphi + 1];
387  else
388  phiRef += 0.5 * phiSteps[0] + M_PI;
389  // setting the position in the phi sector
390  const Amg::Vector3D ngp{cyl->mediumRadius() * std::cos(phiRef),cyl->mediumRadius() * std::sin(phiRef),0.};
391 
392  volOrder.emplace_back(fullPhiVol, ngp);
393 
394  // push back volume position to avoid another loop
395  volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
396  std::pair<double, double>(rmin, rmax));
397  }
398  }
399  // all volumes in arrays : build bin utilities
400 
401  // adjust phiSteps : upper bound equal the lower
402  if (phiSteps.size() > 1) {
403  if (phiSteps.back() > M_PI)
404  phiSteps.erase(phiSteps.end() - 1);
405  else
406  phiSteps.erase(phiSteps.begin());
407  }
408 
409  // phi binning
410  std::vector<std::vector<std::pair<int, float>>> hSteps(phiSteps.size());
411  std::vector<float> phiRef(phiSteps.size());
412  for (unsigned int ip = 0; ip < phiSteps.size() - 1; ++ip)
413  phiRef[ip] = 0.5 * (phiSteps[ip] + phiSteps[ip + 1]);
414  phiRef.back() = 0.5 * (phiSteps.back() + phiSteps.front());
415  phiRef.back() += (phiRef.back() > 0) ? -M_PI : M_PI;
416 
417  auto phiBinUtil = BinUtility(phiSteps, closed, binPhi);
418 
419  // H binning
420 
421  for (unsigned int i = 0; i < volPos.size(); ++i) {
422 
423  // double phi = volPos[i].first.first;
424  int type = volPos[i].first.second;
425  double rmin = volPos[i].second.first;
426  double rmax = volPos[i].second.second;
427  int tmin = (type != 1 && type != 3) ? 0 : 1;
428  int tmax = (type < 2) ? 0 : 1;
429 
430  int phibin = phiBinUtil.bin(volOrder[i].second);
431 
432  if (!hSteps[phibin].empty()) {
433  std::vector<std::pair<int, float>>::iterator iter =
434  hSteps[phibin].begin();
435  bool known = false;
436  while (iter != hSteps[phibin].end()) {
437  if (std::abs(rmin - (*iter).second) < tol) {
438  known = true;
439  break;
440  }
441  if (rmin < (*iter).second) {
442  hSteps[phibin].insert(iter, std::pair<int, float>(tmin, rmin));
443  known = true;
444  break;
445  }
446  ++iter;
447  }
448  if (!known)
449  hSteps[phibin].emplace_back(tmin, rmin);
450  iter = hSteps[phibin].begin();
451  known = false;
452  while (iter != hSteps[phibin].end()) {
453  if (std::abs(rmax - (*iter).second) < tol) {
454  known = true;
455  break;
456  }
457  if (rmax < (*iter).second) {
458  hSteps[phibin].insert(iter, std::pair<int, float>(tmax, rmax));
459  known = true;
460  break;
461  }
462  ++iter;
463  }
464  if (!known)
465  hSteps[phibin].emplace_back(tmax, rmax);
466  } else {
467  hSteps[phibin].emplace_back(tmin, rmin);
468  hSteps[phibin].emplace_back(tmax, rmax);
469  }
470  }
471  // verify size of the array
472  // 2dim array
473  // steering bin utility in phi
474  auto hUtil = std::vector<BinUtility>(phiSteps.size());
475 
476  for (unsigned int ih = 0; ih < phiSteps.size(); ++ih) {
477  (hUtil)[ih] = BinUtility(phiRef[ih], hSteps[ih]);
478  }
479 
480  return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil, hUtil);
481  }
482 
483  ATH_MSG_VERBOSE("Create 2dim VolumeArray of of "<< vols.size()
484  << " Volumes (with CylinderVolumeBounds) with PhiR-binning. ");
485 
486  std::vector<float> rSteps;
487  double phiSector = M_PI;
488  std::vector<std::pair<double, std::pair<double, double>>> volPos;
489 
490  for (const auto& vol : vols) {
491  const auto *cyl =dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
492  if (!cyl) {
493  ATH_MSG_WARNING("dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
494  continue;
495  }
496  double rmin = cyl->innerRadius();
497  double rmax = cyl->outerRadius();
498  double dphi = cyl->halfPhiSector();
499  if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
500  phiSector = phiSector < M_PI ? -1. : dphi;
501 
502 
503  const Amg::Vector3D ngp{vol->transform() * (cyl->mediumRadius()* Amg::Vector3D::UnitX())};
504  volOrder.emplace_back(vol, ngp);
505 
506  // push back volume position to avoid another loop
507  volPos.emplace_back(cyl->mediumRadius(), std::make_pair(ngp.phi(), dphi));
508  // r binning
509  if (!rSteps.empty()) {
510  std::vector<float>::iterator iter = rSteps.begin();
511  bool known = false;
512  while (iter != rSteps.end()) {
513  if (std::abs(rmin - (*iter)) < tol) {
514  known = true;
515  break;
516  }
517  if (rmin < (*iter)) {
518  rSteps.insert(iter, rmin);
519  known = true;
520  break;
521  }
522  ++iter;
523  }
524  if (!known)
525  rSteps.push_back(rmin);
526  iter = rSteps.begin();
527  known = false;
528  while (iter != rSteps.end()) {
529  if (std::abs(rmax - (*iter)) < tol) {
530  known = true;
531  break;
532  }
533  if (rmax < (*iter)) {
534  rSteps.insert(iter, rmax);
535  known = true;
536  break;
537  }
538  ++iter;
539  }
540  if (!known)
541  rSteps.push_back(rmax);
542  } else {
543  rSteps.push_back(rmin);
544  rSteps.push_back(rmax);
545  }
546  }
547 
548  if (phiSector > 0.) { // overall equidistant binning
549 
550  const int rStepsSizem1 = rSteps.size() - 1;
551  std::vector<double> phi(rStepsSizem1, M_PI);
552  std::vector<int> phiSect(rStepsSizem1,int(M_PI / phiSector));
553 
554  // simplify if possible
555  if (rSteps.size() == 1) {
556  return cylinderVolumesArrayInPhi(vols, navtype);
557  }
558  if (phiSector == M_PI) {
559  return cylinderVolumesArrayInR(vols, navtype);
560  }
561  // 2dim array
562  auto rBinUtil = BinUtility(rSteps, open, binR);
563  auto phiUtil = std::vector<BinUtility>(rSteps.size() - 1);
564  for (unsigned int ip = 0; ip < phiUtil.size(); ++ip) {
565  (phiUtil)[ip] =BinUtility(phiSect[ip], closed, binPhi);
566  }
567  return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil, phiUtil);
568  }
569 
570  // R binning : steering binUtility
571  auto binGenR = BinUtility(rSteps, open, binR);
572 
573  // phi binning
574  std::vector<std::vector<float>> phiSteps(rSteps.size() - 1);
575 
576  for (unsigned int i = 0; i < volPos.size(); ++i) {
577 
578  double phi = volPos[i].second.first;
579  double dphi = volPos[i].second.second;
580 
581  int binr = binGenR.bin(volOrder[i].second);
582 
583  float phi1 = phi - dphi;
584  float phi2 = phi + dphi;
585  if (phi1 < 0)
586  phi1 += 2 * M_PI;
587  if (phi2 < 0)
588  phi2 += 2 * M_PI;
589 
590  if (!phiSteps[binr].empty()) {
591  std::vector<float>::iterator iter = phiSteps[binr].begin();
592  bool known = false;
593  while (iter != phiSteps[binr].end()) {
594  if (std::abs(phi1 - (*iter)) < tol) {
595  known = true;
596  break;
597  }
598  if (phi1 < (*iter)) {
599  phiSteps[binr].insert(iter, phi1);
600  known = true;
601  break;
602  }
603  ++iter;
604  }
605  if (!known)
606  phiSteps[binr].push_back(phi1);
607  iter = phiSteps[binr].begin();
608  known = false;
609  while (iter != phiSteps[binr].end()) {
610  if (std::abs(phi2 - (*iter)) < tol) {
611  known = true;
612  break;
613  }
614  if (phi2 < (*iter)) {
615  phiSteps[binr].insert(iter, phi2);
616  known = true;
617  break;
618  }
619  ++iter;
620  }
621  if (!known)
622  phiSteps[binr].push_back(phi2);
623  } else {
624  phiSteps[binr].push_back(std::fmin(phi1, phi2));
625  phiSteps[binr].push_back(std::fmax(phi1, phi2));
626  }
627  }
628 
629  // 2dim array
630  auto phiUtil = std::vector<BinUtility>(phiSteps.size());
631 
632  for (unsigned int ip = 0; ip < phiSteps.size(); ++ip) {
633  (phiUtil)[ip] = BinUtility(phiSteps[ip], closed, binPhi);
634  }
635 
636  return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR, phiUtil);
637 }
638 
640 TrackingVolumeArrayCreator::cylinderVolumesArrayInPhiZ(const std::vector<TrackingVolume*>& vols,
641  bool navtype) const {
642  return cylinderVolumesArrayInPhiZ(translateToShared(vols, navtype), navtype).release();
643 }
644 std::unique_ptr<TrackingVolumeArray>
646  bool navtype) const {
647 
648  ATH_MSG_VERBOSE("Create 2dim VolumeArray of of "<< vols.size()
649  << " Volumes (with CylinderVolumeBounds) with PhiZ-binning. ");
650 
651  double tol = 0.001;
652  // the vector needed for the BinnedArray
653  std::vector<TrackingVolumeOrderPosition> volOrder;
654 
655  std::vector<float> zSteps;
656 
657  double phiSector = M_PI;
658  std::vector<std::pair<float, std::pair<float, float>>> volPos;
659 
660  for (const VolumePtr& vol : vols) {
661  const auto *cyl = dynamic_cast<const CylinderVolumeBounds*>(&(vol->volumeBounds()));
662  const auto *bcyl = dynamic_cast<const BevelledCylinderVolumeBounds*>(&(vol->volumeBounds()));
663  double zmin{0.}, zmax{0.}, dphi{0.}, mRad{0.};
664  if (cyl) {
665  zmin = vol->center().z() - cyl->halflengthZ();
666  zmax = vol->center().z() + cyl->halflengthZ();
667  dphi = cyl->halfPhiSector();
668  mRad = cyl->mediumRadius();
669  } else if (bcyl) {
670  zmin = vol->center().z() - bcyl->halflengthZ();
671  zmax = vol->center().z() + bcyl->halflengthZ();
672  dphi = bcyl->halfPhiSector();
673  mRad = bcyl->mediumRadius();
674  } else {
675  ATH_MSG_ERROR("volume not cylinder nor bevelled cylinder ");
676  return nullptr;
677  }
678 
679  if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
680  phiSector = phiSector < M_PI ? -1. : dphi;
681 
682  // push back the volume order position
683  const Amg::Vector3D ngp{vol->transform() * (mRad * Amg::Vector3D::UnitX())};
684 
685  volOrder.emplace_back(vol, ngp);
686  // push back volume position to avoid another loop
687  volPos.emplace_back(vol->center().z(), std::make_pair(ngp.phi(), dphi));
688  // z binning
689  if (!zSteps.empty()) {
690  std::vector<float>::iterator iter = zSteps.begin();
691  bool known = false;
692  while (iter != zSteps.end()) {
693  if (std::abs(zmin - (*iter)) < tol) {
694  known = true;
695  break;
696  }
697  if (zmin < (*iter)) {
698  zSteps.insert(iter, zmin);
699  known = true;
700  break;
701  }
702  ++iter;
703  }
704  if (!known)
705  zSteps.push_back(zmin);
706  iter = zSteps.begin();
707  known = false;
708  while (iter != zSteps.end()) {
709  if (std::abs(zmax - (*iter)) < tol) {
710  known = true;
711  break;
712  }
713  if (zmax < (*iter)) {
714  zSteps.insert(iter, zmax);
715  known = true;
716  break;
717  }
718  ++iter;
719  }
720  if (!known)
721  zSteps.push_back(zmax);
722  } else {
723  zSteps.push_back(zmin);
724  zSteps.push_back(zmax);
725  }
726  }
727 
728  if (phiSector > 0.) { // overall equidistant binning
729 
730  const int zStepsSizem1 = zSteps.size() - 1;
731  std::vector<double> phi(zStepsSizem1, M_PI);
732  std::vector<int> phiSect(zStepsSizem1,int(M_PI / phiSector));
733 
734  // simplify if possible
735  if (phiSector == M_PI) {
736  return cylinderVolumesArrayInZ(vols, navtype);
737  }
738  if (zSteps.size() == 2) {
739  return cylinderVolumesArrayInPhi(vols, navtype);
740  }
741  // 2dim array
742  auto binGenZPhi = BinUtility(zSteps, open, binZ);
743  binGenZPhi += BinUtility(phiSector, -M_PI, M_PI, closed, binPhi);
744  return std::make_unique<BinnedArray2D<TrackingVolume>>(volOrder, binGenZPhi);
745  }
746 
747  // steering binUtility in binZ
748  auto binGenZ = BinUtility(zSteps, open, binZ);
749 
750  // phi binning - steering binUtility in binZ
751  std::vector<std::vector<float>> phiSteps(zSteps.size() - 1);
752 
753  for (unsigned int i = 0; i < volPos.size(); ++i) {
754 
755  float phi = volPos[i].second.first;
756  float dphi = volPos[i].second.second;
757 
758  int binZ = binGenZ.bin(volOrder[i].second);
759 
760  float phi1 = phi - dphi;
761  float phi2 = phi + dphi;
762  if (phi1 < 0)
763  phi1 += 2 * M_PI;
764  if (phi2 < 0)
765  phi2 += 2 * M_PI;
766 
767  if (!phiSteps[binZ].empty()) {
769  bool known = false;
770  while (iter != phiSteps[binZ].end()) {
771  if (std::abs(phi1 - (*iter)) < tol) {
772  known = true;
773  break;
774  }
775  if (phi1 < (*iter)) {
776  phiSteps[binZ].insert(iter, phi1);
777  known = true;
778  break;
779  }
780  ++iter;
781  }
782  if (!known)
783  phiSteps[binZ].push_back(phi1);
784  iter = phiSteps[binZ].begin();
785  known = false;
786  while (iter != phiSteps[binZ].end()) {
787  if (std::abs(phi2 - (*iter)) < tol) {
788  known = true;
789  break;
790  }
791  if (phi2 < (*iter)) {
792  phiSteps[binZ].insert(iter, phi2);
793  known = true;
794  break;
795  }
796  ++iter;
797  }
798  if (!known)
799  phiSteps[binZ].push_back(phi2);
800  } else {
801  phiSteps[binZ].push_back(std::fmin(phi1, phi2));
802  phiSteps[binZ].push_back(std::fmax(phi1, phi2));
803  // phiSectors[binZ] = dphi ;
804  }
805  }
806 
807  // 2dim array: construct from two 1D boundaries
808  auto phiUtil = std::vector<BinUtility>(phiSteps.size());
809 
810  for (unsigned int ip = 0; ip < phiSteps.size(); ++ip) {
811  phiUtil[ip] = BinUtility(phiSteps[ip], closed, binPhi);
812  }
813 
814  return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenZ, phiUtil);
815 }
816 
817 
819 TrackingVolumeArrayCreator::cuboidVolumesArrayNav(const std::vector<TrackingVolume*>& vols,
820  BinUtility* binUtil,
821  bool navtype) const {
822  return cuboidVolumesArrayNav(translateToShared(vols, navtype), binUtil).release();
823 }
824 std::unique_ptr<TrackingVolumeArray>
825  TrackingVolumeArrayCreator::cuboidVolumesArrayNav(const std::vector<VolumePtr>& vols,
826  BinUtility* binUtil) const {
827  // the vector needed for the BinnedArray
828  std::vector<VolumePtr> volOrder;
829  // loop over volumes and fill primaries
830  auto volIter = vols.begin();
831  for (; volIter != vols.end(); ++volIter) {
832  const auto *currentCubBounds = dynamic_cast<const CuboidVolumeBounds*>(&((*volIter)->volumeBounds()));
833  if (!currentCubBounds) {
834  ATH_MSG_ERROR("Given TrackingVolume to TrackingVolumeArrayCreator didn't "
835  "match specified shape: return 0");
836  return nullptr;
837  }
838  volOrder.push_back(*volIter);
839  }
840  if (!volOrder.empty()) {
841  auto navTransform = std::make_unique<Amg::Transform3D>(Amg::Transform3D::Identity());
842  return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform.release());
843  }
844  ATH_MSG_ERROR("No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
845  return nullptr;
846 }
847 
848 
850 TrackingVolumeArrayCreator::trapezoidVolumesArrayNav(const std::vector<TrackingVolume*>& vols,
851  BinUtility* binUtil, bool navtype) const {
852  return trapezoidVolumesArrayNav(translateToShared(vols, navtype), binUtil).release();
853 }
854 
855 std::unique_ptr<TrackingVolumeArray>
856  TrackingVolumeArrayCreator::trapezoidVolumesArrayNav(const std::vector<VolumePtr>& vols, BinUtility* binUtil) const {
857  // the vector needed for the BinnedArray
858  std::vector<VolumePtr> volOrder;
859  // loop over volumes and fill primaries
860  auto volIter = vols.begin();
861  for (; volIter != vols.end(); ++volIter) {
862  const auto *currentTrdBounds = dynamic_cast<const TrapezoidVolumeBounds*>(&((*volIter)->volumeBounds()));
863  if (!currentTrdBounds) {
864  ATH_MSG_ERROR("Given TrackingVolume to TrackingVolumeArrayCreator didn't "
865  "match specified shape: return 0");
866  return nullptr;
867  }
868  // push back the volume order position
869  volOrder.push_back(*volIter);
870  }
871  if (!volOrder.empty()) {
872  Amg::Transform3D* navTransform = new Amg::Transform3D(Amg::Transform3D::Identity());
873  return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
874  }
875  ATH_MSG_ERROR("No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
876  return nullptr;
877 }
878 
880  BinUtility* binUtil,
881  bool navtype) const {
882  return doubleTrapezoidVolumesArrayNav(translateToShared(vols, navtype), binUtil).release();
883 }
884 
885 std::unique_ptr<TrackingVolumeArray>
886  TrackingVolumeArrayCreator::doubleTrapezoidVolumesArrayNav(const std::vector<VolumePtr>& vols, BinUtility* binUtil) const {
887  // the vector needed for the BinnedArray
888  std::vector<VolumePtr> volOrder;
889  // loop over volumes and fill primaries
890  auto volIter = vols.begin();
891  for (; volIter != vols.end(); ++volIter) {
892  const auto *currentDTrdBounds =dynamic_cast<const DoubleTrapezoidVolumeBounds*>(&((*volIter)->volumeBounds()));
893  if (!currentDTrdBounds) {
894  ATH_MSG_ERROR("Given TrackingVolume to TrackingVolumeArrayCreator didn't "
895  "match specified shape: return 0");
896  return nullptr;
897  }
898  // push back the volume order position
899  volOrder.push_back(*volIter);
900  }
901  if (!volOrder.empty()) {
902  Amg::Transform3D* navTransform = new Amg::Transform3D(Amg::Transform3D::Identity());
903  return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
904  }
906  "No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
907  return nullptr;
908 }
909 
910 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Trk::TrackingVolumeArrayCreator::cylinderVolumesArrayInZ
TrackingVolumeArray * cylinderVolumesArrayInZ(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a R-binned cylindrical volume array.
Definition: TrackingVolumeArrayCreator.cxx:137
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
Trk::BevelledCylinderVolumeBounds
Definition: BevelledCylinderVolumeBounds.h:100
Trk::CuboidVolumeBounds
Definition: CuboidVolumeBounds.h:52
Trk::binZ
@ binZ
Definition: BinningType.h:49
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
SharedDoNoDelete.h
BinnedArray2D.h
Trk::TrackingVolumeArrayCreator::TrackingVolumeArrayCreator
TrackingVolumeArrayCreator(const std::string &, const std::string &, const IInterface *)
Constructor.
Definition: TrackingVolumeArrayCreator.cxx:49
BinUtility.h
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrackingVolumeArrayCreator.h
Trk::closed
@ closed
Definition: BinningType.h:41
BinnedArray1D1D.h
NavBinnedArray1D.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
TrapezoidVolumeBounds.h
Trk::TrackingVolumeArrayCreator::~TrackingVolumeArrayCreator
virtual ~TrackingVolumeArrayCreator()
Destructor.
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
Trk::TrackingVolumeArrayCreator::cylinderVolumesArrayInPhi
TrackingVolumeArray * cylinderVolumesArrayInPhi(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a R-binned cylindrical volume array.
Definition: TrackingVolumeArrayCreator.cxx:215
BinnedArray1D.h
GeometryStatics.h
CylinderVolumeBounds.h
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
Trk::ITrackingVolumeArrayCreator::VolumePtr
std::shared_ptr< TrackingVolume > VolumePtr
Definition: ITrackingVolumeArrayCreator.h:48
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
BevelledCylinderVolumeBounds.h
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::TrackingVolumeArrayCreator::doubleTrapezoidVolumesArrayNav
TrackingVolumeArray * doubleTrapezoidVolumesArrayNav(const std::vector< TrackingVolume * > &vols, Trk::BinUtility *binUtil, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a doubleTrapezoid volume array - linked to detac...
Definition: TrackingVolumeArrayCreator.cxx:879
Trk::CylinderVolumeBounds::halflengthZ
double halflengthZ() const
This method returns the halflengthZ.
Definition: CylinderVolumeBounds.h:207
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
Trk::TrackingVolumeArrayCreator::cylinderVolumesArrayInPhiZ
TrackingVolumeArray * cylinderVolumesArrayInPhiZ(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a 2dim cylindrical volume array.
Definition: TrackingVolumeArrayCreator.cxx:640
Trk::BinUtility
Definition: BinUtility.h:39
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
DoubleTrapezoidVolumeBounds.h
Trk::CylinderVolumeBounds::outerRadius
double outerRadius() const
This method returns the outer radius.
Definition: CylinderVolumeBounds.h:191
Trk::TrapezoidVolumeBounds
Definition: TrapezoidVolumeBounds.h:57
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::TrackingVolumeArrayCreator::cylinderVolumesArrayInPhiR
TrackingVolumeArray * cylinderVolumesArrayInPhiR(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a 2dim cylindrical volume array.
Definition: TrackingVolumeArrayCreator.cxx:256
Trk::open
@ open
Definition: BinningType.h:40
Trk::binR
@ binR
Definition: BinningType.h:50
Trk::TrackingVolumeArrayCreator::trapezoidVolumesArrayNav
TrackingVolumeArray * trapezoidVolumesArrayNav(const std::vector< TrackingVolume * > &vols, Trk::BinUtility *binUtil, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a trapezoid volume array - linked to detached tr...
Definition: TrackingVolumeArrayCreator.cxx:850
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::CylinderVolumeBounds::innerRadius
double innerRadius() const
This method returns the inner radius.
Definition: CylinderVolumeBounds.h:187
GeoPrimitivesHelpers.h
known
Definition: TrigBStoxAODTool.cxx:107
Trk::DoubleTrapezoidVolumeBounds
Definition: DoubleTrapezoidVolumeBounds.h:66
Trk::TrackingVolumeArrayCreator::cuboidVolumesArrayNav
TrackingVolumeArray * cuboidVolumesArrayNav(const std::vector< TrackingVolume * > &vols, Trk::BinUtility *binUtil, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a cuboid volume array - linked to detached track...
Definition: TrackingVolumeArrayCreator.cxx:819
Trk::phi
@ phi
Definition: ParamDefs.h:75
Trk::TrackingVolumeArrayCreator::cylinderVolumesArrayInR
TrackingVolumeArray * cylinderVolumesArrayInR(const std::vector< TrackingVolume * > &vols, bool navigationtype=false) const override
TrackingVolumeArrayCreator interface method - create a R-binned cylindrical volume array.
Definition: TrackingVolumeArrayCreator.cxx:60
Trk::BinnedArray
Definition: BinnedArray.h:38
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
Trk::TrackingVolume
Definition: TrackingVolume.h:121
LArCellBinning.phiSteps
dictionary phiSteps
Definition: LArCellBinning.py:37
CuboidVolumeBounds.h
PUfitVar::nPhiBins
constexpr std::size_t nPhiBins
Definition: GepMETPufitAlg.cxx:20
Trk::CylinderVolumeBounds::mediumRadius
double mediumRadius() const
This method returns the medium radius.
Definition: CylinderVolumeBounds.h:195
Trk::binPhi
@ binPhi
Definition: BinningType.h:51