LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
GeometryCore.cxx
Go to the documentation of this file.
1 
7 // class header
9 
10 // LArSoft includes
15 #include "larcorealg/Geometry/Decomposer.h" // geo::vect::dot()
20 #include "larcorealg/Geometry/geo_vectors_utils.h" // geo::vect
22 
23 // Framework includes
24 #include "cetlib_except/exception.h"
25 #include "fhiclcpp/types/Table.h"
27 
28 // ROOT includes
29 #include "TGeoBBox.h"
30 #include "TGeoManager.h"
31 #include "TGeoNode.h"
32 #include "TGeoVolume.h"
33 #include "TROOT.h"
34 
35 // C/C++ includes
36 #include <algorithm> // std::transform()
37 #include <cassert>
38 #include <cctype> // std::tolower()
39 #include <cmath> // std::abs() ...
40 #include <cstddef> // std::size_t
41 #include <limits> // std::numeric_limits<>
42 #include <numeric> // std::accumulate
43 #include <sstream> // std::ostringstream
44 #include <vector>
45 
46 namespace geo {
47 
48  //......................................................................
49  // Constructor.
51  std::unique_ptr<GeometryBuilder> builder,
52  std::unique_ptr<GeoObjectSorter> sorter)
54  , fBuilder{std::move(builder)}
55  , fSorter{std::move(sorter)}
56  , fGDMLfile{lar::searchPathPlusRelative(pset.get<std::string>("RelativePath", ""),
57  pset.get<std::string>("GDML"))}
59  , fSurfaceY(pset.get<double>("SurfaceY"))
60  , fPositionWiggle(pset.get<double>("PositionEpsilon", 1.e-4))
61  {
62  std::transform(fDetectorName.begin(), fDetectorName.end(), fDetectorName.begin(), [](auto c) {
63  return std::tolower(c);
64  });
65 
67  }
68 
69  //......................................................................
71  {
72  if (fManager) {
73  throw cet::exception("GeometryCore") << "Reloading a geometry is not supported.\n";
74  }
75 
76  if (fGDMLfile.empty()) {
77  throw cet::exception("GeometryCore") << "No GDML Geometry file specified!\n";
78  }
79 
80  (void)gROOT; // <= Can be removed once ROOT 6.26/08 is adopted
81 
82  if (!gGeoManager) {
83  // [20210630, petrillo@slac.stanford.edu]
84  // ROOT 6.22.08 allows us to choose the representation of lengths in the geometry
85  // objects parsed from GDML. In LArSoft we want them to be centimeters (ROOT
86  // standard). This was tracked as Redmine issue #25990, and I leave this mark
87  // because I feel that we'll be back to it not too far in the future. Despite the
88  // documentation (ROOT 6.22/08), it seems the units are locked from the beginning,
89  // so we unlock without prejudice.
90  TGeoManager::LockDefaultUnits(false);
91  TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
92  TGeoManager::LockDefaultUnits(true);
93 
94  TGeoManager::Import(fGDMLfile.c_str());
95  gGeoManager->LockGeometry();
96  }
97 
98  BuildGeometry();
99 
100  fManager = gGeoManager;
101 
102  SortGeometry();
103 
104  mf::LogInfo("GeometryCore") << "New detector geometry loaded from\n\t" << fGDMLfile;
105  }
106 
107  //......................................................................
109  {
110  mf::LogInfo("GeometryCore") << "Sorting volumes...";
111 
112  if (not fSorter) { return; }
113 
114  fSorter->sort(fCryostats);
115 
116  // Renumber cryostats according to sorted order
118  for (CryostatGeo& cryo : fCryostats) {
119  cryo.SortSubVolumes(*fSorter);
120  cryo.UpdateAfterSorting(CryostatID{c});
121  ++c;
122  }
123  }
124 
125  //......................................................................
126  TGeoManager* GeometryCore::ROOTGeoManager() const
127  {
128  assert(fManager == gGeoManager);
129  return fManager;
130  }
131 
132  //......................................................................
133  unsigned int GeometryCore::NOpDets() const
134  {
135  int N = 0;
136  for (auto const& cryo : Iterate<CryostatGeo>())
137  N += cryo.NOpDet();
138  return N;
139  }
140 
141  //......................................................................
142  //
143  // Return the geometry description of the ith cryostat in the detector.
144  //
145  // \param cstat : input cryostat number, starting from 0
146  // \returns cryostat geometry for ith cryostat
147  //
148  // \throws geo::Exception if "cstat" is outside allowed range
149  //
150  CryostatGeo const& GeometryCore::Cryostat(CryostatID const& cryoid) const
151  {
152  if (auto pCryo = CryostatPtr(cryoid)) { return *pCryo; }
153  throw cet::exception("GeometryCore") << "Cryostat #" << cryoid.Cryostat << " does not exist\n";
154  }
155 
156  //......................................................................
158  {
159  // first find the cryostat
160  CryostatGeo const* cryo = PositionToCryostatPtr(point);
161  if (!cryo) return {};
162 
163  // then ask it about the TPC
164  return cryo->PositionToTPCID(point, 1. + fPositionWiggle);
165  }
166 
167  //......................................................................
169  {
170  for (auto const& cryostat : Iterate<CryostatGeo>()) {
171  if (cryostat.ContainsPosition(point, 1.0 + fPositionWiggle)) return &cryostat;
172  }
173  return nullptr;
174  }
175 
176  //......................................................................
178  {
179  CryostatGeo const* cryo = PositionToCryostatPtr(point);
180  return cryo ? cryo->ID() : CryostatID{};
181  }
182 
183  //......................................................................
184  TPCGeo const* GeometryCore::PositionToTPCptr(Point_t const& point) const
185  {
186  CryostatGeo const* cryo = PositionToCryostatPtr(point);
187  return cryo ? cryo->PositionToTPCptr(point, 1. + fPositionWiggle) : nullptr;
188  }
189 
190  //......................................................................
191  TPCGeo const& GeometryCore::PositionToTPC(Point_t const& point) const
192  {
193  if (auto tpc = PositionToTPCptr(point)) { return *tpc; }
194  throw cet::exception("GeometryCore") << "Can't find any TPC at position " << point << "\n";
195  }
196 
197  //......................................................................
199  {
200  TPCGeo const* tpc = PositionToTPCptr(point);
201  return tpc ? tpc->ID() : TPCID{};
202  }
203 
204  //......................................................................
206  {
207  if (auto cstat = PositionToCryostatPtr(point)) { return *cstat; }
208  throw cet::exception("GeometryCore") << "Can't find any cryostat at position " << point << "\n";
209  }
210 
211  //......................................................................
212  std::string const& GeometryCore::GetWorldVolumeName() const
213  {
214  // For now, and possibly forever, this is a constant (given the definition of
215  // "nodeNames" above).
216  static std::string const worldVolumeName{"volWorld"};
217  return worldVolumeName;
218  }
219 
220  //......................................................................
222  std::string const& name /* = "volDetEnclosure" */) const
223  {
224  auto const& path = FindDetectorEnclosure(name);
225  if (path.empty()) {
226  throw cet::exception("GeometryCore")
227  << "DetectorEnclosureBox(): can't find enclosure volume '" << name << "'\n";
228  }
229 
230  TGeoVolume const* pEncl = path.back().node->GetVolume();
231  auto const* pBox = dynamic_cast<TGeoBBox const*>(pEncl->GetShape());
232 
233  // check that this is indeed a box
234  if (!pBox) {
235  // at initialisation time we don't know yet our real ID
236  throw cet::exception("GeometryCore")
237  << "Detector enclosure '" << name << "' is not a box! (it is a "
238  << pEncl->GetShape()->IsA()->GetName() << ")\n";
239  }
240 
241  LocalTransformation<TGeoHMatrix> trans(path, path.size() - 1);
242  // get the half width, height, etc of the cryostat
243  double const halfwidth = pBox->GetDX();
244  double const halfheight = pBox->GetDY();
245  double const halflength = pBox->GetDZ();
246 
247  return {trans.LocalToWorld(Point_t{-halfwidth, -halfheight, -halflength}),
248  trans.LocalToWorld(Point_t{+halfwidth, +halfheight, +halflength})};
249  }
250 
251  //......................................................................
273  public:
274  explicit ROOTGeoNodeForwardIterator(TGeoNode const* start_node);
275 
277  TGeoNode const* operator*() const
278  {
279  return current_path.empty() ? nullptr : current_path.back().self;
280  }
281 
283  ROOTGeoNodeForwardIterator& operator++();
284 
286  std::vector<TGeoNode const*> get_path() const;
287 
288  private:
289  struct NodeInfo_t {
290  TGeoNode const* self;
291  int sibling;
292  };
293 
295  std::vector<NodeInfo_t> current_path;
296 
297  void reach_deepest_descendant();
298  }; // class ROOTGeoNodeForwardIterator
299 
301  std::set<std::string> const* vol_names;
302 
303  NodeNameMatcherClass(std::set<std::string> const& names) : vol_names(&names) {}
304 
306  bool operator()(TGeoNode const& node) const
307  {
308  if (!vol_names) return true;
309  return vol_names->find(node.GetVolume()->GetName()) != vol_names->end();
310  }
311  };
312 
314  std::vector<TGeoNode const*> nodes;
315 
316  CollectNodesByName(std::set<std::string> const& names) : matcher(names) {}
317 
319  void operator()(TGeoNode const& node)
320  {
321  if (matcher(node)) nodes.push_back(&node);
322  }
323 
324  void operator()(ROOTGeoNodeForwardIterator const& iter) { operator()(**iter); }
325 
326  private:
328  };
329 
331  std::vector<std::vector<TGeoNode const*>> paths;
332 
333  CollectPathsByName(std::set<std::string> const& names) : matcher(names) {}
334 
337  {
338  if (matcher(**iter)) paths.push_back(iter.get_path());
339  }
340 
341  private:
343  };
344 
345  //......................................................................
346  std::vector<TGeoNode const*> GeometryCore::FindAllVolumes(
347  std::set<std::string> const& vol_names) const
348  {
349  CollectNodesByName node_collector(vol_names);
350 
351  ROOTGeoNodeForwardIterator iNode{ROOTGeoManager()->GetTopNode()};
352  TGeoNode const* pCurrentNode;
353 
354  while ((pCurrentNode = *iNode)) {
355  node_collector(*pCurrentNode);
356  ++iNode;
357  }
358 
359  return node_collector.nodes;
360  }
361 
362  //......................................................................
363  std::vector<std::vector<TGeoNode const*>> GeometryCore::FindAllVolumePaths(
364  std::set<std::string> const& vol_names) const
365  {
366  CollectPathsByName path_collector(vol_names);
367 
368  ROOTGeoNodeForwardIterator iNode(ROOTGeoManager()->GetTopNode());
369 
370  while (*iNode) {
371  path_collector(iNode);
372  ++iNode;
373  }
374 
375  return path_collector.paths;
376  }
377 
378  //......................................................................
379  unsigned int GeometryCore::MaxTPCs() const
380  {
381  unsigned int maxTPCs = 0;
382  for (CryostatGeo const& cryo : fCryostats) {
383  unsigned int maxTPCsInCryo = cryo.NTPC();
384  if (maxTPCsInCryo > maxTPCs) maxTPCs = maxTPCsInCryo;
385  }
386  return maxTPCs;
387  }
388 
389  //......................................................................
390  unsigned int GeometryCore::TotalNTPC() const
391  {
392  // it looks like C++11 lambdas have made STL algorithms easier to use, but only so
393  // much:
394  return std::accumulate(
395  fCryostats.begin(), fCryostats.end(), 0U, [](unsigned int sum, CryostatGeo const& cryo) {
396  return sum + cryo.NTPC();
397  });
398  }
399 
400  //......................................................................
401  TGeoVolume const* GeometryCore::WorldVolume() const
402  {
403  return gGeoManager->FindVolumeFast(GetWorldVolumeName().c_str());
404  }
405 
406  //......................................................................
408  {
409  TGeoVolume const* world = WorldVolume();
410  if (!world) {
411  throw cet::exception("GeometryCore") << "no world volume '" << GetWorldVolumeName() << "'\n";
412  }
413  TGeoShape const* s = world->GetShape();
414  if (!s) {
415  throw cet::exception("GeometryCore")
416  << "world volume '" << GetWorldVolumeName() << "' is shapeless!!!\n";
417  }
418 
419  double x1, x2, y1, y2, z1, z2;
420  s->GetAxisRange(1, x1, x2);
421  s->GetAxisRange(2, y1, y2);
422  s->GetAxisRange(3, z1, z2);
423 
424  // BoxBoundedGeo constructor will sort the coordinates as needed
425  return BoxBoundedGeo{x1, x2, y1, y2, z1, z2};
426  }
427 
428  //......................................................................
429  void GeometryCore::WorldBox(double* xlo,
430  double* xhi,
431  double* ylo,
432  double* yhi,
433  double* zlo,
434  double* zhi) const
435  {
436  BoxBoundedGeo const box = WorldBox();
437  if (xlo) *xlo = box.MinX();
438  if (ylo) *ylo = box.MinY();
439  if (zlo) *zlo = box.MinZ();
440  if (xhi) *xhi = box.MaxX();
441  if (yhi) *yhi = box.MaxY();
442  if (zhi) *zhi = box.MaxZ();
443  }
444 
445  //......................................................................
446  std::string GeometryCore::VolumeName(Point_t const& point) const
447  {
448  // check that the given point is in the World volume at least
449  TGeoVolume const* volWorld = WorldVolume();
450  double halflength = ((TGeoBBox*)volWorld->GetShape())->GetDZ();
451  double halfheight = ((TGeoBBox*)volWorld->GetShape())->GetDY();
452  double halfwidth = ((TGeoBBox*)volWorld->GetShape())->GetDX();
453  if (std::abs(point.x()) > halfwidth || std::abs(point.y()) > halfheight ||
454  std::abs(point.z()) > halflength) {
455  mf::LogWarning("GeometryCoreBadInputPoint")
456  << "point (" << point.x() << "," << point.y() << "," << point.z() << ") "
457  << "is not inside the world volume "
458  << " half width = " << halfwidth << " half height = " << halfheight
459  << " half length = " << halflength << " returning unknown volume name";
460  return "unknownVolume";
461  }
462 
463  return gGeoManager->FindNode(point.X(), point.Y(), point.Z())->GetName();
464  }
465 
466  //......................................................................
467  TGeoMaterial const* GeometryCore::Material(Point_t const& point) const
468  {
469  auto const pNode = gGeoManager->FindNode(point.X(), point.Y(), point.Z());
470  if (!pNode) return nullptr;
471  auto const pMedium = pNode->GetMedium();
472  return pMedium ? pMedium->GetMaterial() : nullptr;
473  }
474 
475  //......................................................................
476  std::string GeometryCore::MaterialName(Point_t const& point) const
477  {
478  // check that the given point is in the World volume at least
479  BoxBoundedGeo worldBox = WorldBox();
480  if (!worldBox.ContainsPosition(point)) {
481  mf::LogWarning("GeometryCoreBadInputPoint")
482  << "point " << point << " is not inside the world volume " << worldBox.Min() << " -- "
483  << worldBox.Max() << "; returning unknown material name";
484  return {"unknownMaterial"};
485  }
486  auto const pMaterial = Material(point);
487  if (!pMaterial) {
488  mf::LogWarning("GeometryCoreBadInputPoint")
489  << "material for point " << point << " not found! returning unknown material name";
490  return {"unknownMaterial"};
491  }
492  return pMaterial->GetName();
493  }
494 
495  //......................................................................
496  std::vector<GeoNodePathEntry> GeometryCore::FindDetectorEnclosure(
497  std::string const& name /* = "volDetEnclosure" */) const
498  {
499  std::vector<GeoNodePathEntry> path{{ROOTGeoManager()->GetTopNode()}};
500  if (!FindFirstVolume(name, path)) path.clear();
501  return path;
502  }
503 
504  //......................................................................
505  bool GeometryCore::FindFirstVolume(std::string const& name,
506  std::vector<GeoNodePathEntry>& path) const
507  {
508  assert(!path.empty());
509 
510  auto const* pCurrent = path.back().node;
511 
512  // first check the current layer
513  if (strncmp(name.c_str(), pCurrent->GetName(), name.length()) == 0) return true;
514 
515  //explore the next layer down
516  auto const* pCurrentVolume = pCurrent->GetVolume();
517  unsigned int nd = pCurrentVolume->GetNdaughters();
518  for (unsigned int i = 0; i < nd; ++i) {
519  path.push_back({pCurrentVolume->GetNode(i)});
520  if (FindFirstVolume(name, path)) return true;
521  path.pop_back();
522  }
523  return false;
524  }
525 
526  //......................................................................
528  {
529  GeoNodePath path{gGeoManager->GetTopNode()};
530  fCryostats = fBuilder->extractCryostats(path);
531  }
532 
533  //......................................................................
534  //
535  // Return the total mass of the detector
536  //
537  //
538  double GeometryCore::TotalMass(std::string vol) const
539  {
540  //the TGeoNode::GetVolume() returns the TGeoVolume of the detector outline and ROOT
541  //calculates the mass in kg for you
542  TGeoVolume* gvol = gGeoManager->FindVolumeFast(vol.c_str());
543  if (gvol) return gvol->Weight();
544 
545  throw cet::exception("GeometryCore")
546  << "could not find specified volume '" << vol << " 'to determine total mass\n";
547  }
548 
549  //......................................................................
550  double GeometryCore::MassBetweenPoints(Point_t const& p1, Point_t const& p2) const
551  {
552  //The purpose of this method is to determine the column density between the two points
553  //given. Do that by starting at p1 and stepping until you get to the node of p2.
554  //calculate the distance between the point just inside that node and p2 to get the
555  //last bit of column density
556  double columnD = 0.;
557 
558  //first initialize a track - get the direction cosines
559  Vector_t const dir = (p2 - p1).Unit();
560 
561  double const dxyz[3] = {dir.X(), dir.Y(), dir.Z()};
562  double const cp1[3] = {p1.X(), p1.Y(), p1.Z()};
563  gGeoManager->InitTrack(cp1, dxyz);
564 
565  //might be helpful to have a point to a TGeoNode
566  TGeoNode* node = gGeoManager->GetCurrentNode();
567 
568  //check that the points are not in the same volume already. if they are in different
569  //volumes, keep stepping until you are in the same volume as the second point
570  while (!gGeoManager->IsSameLocation(p2.X(), p2.Y(), p2.Z())) {
571  gGeoManager->FindNextBoundary();
572  columnD += gGeoManager->GetStep() * node->GetMedium()->GetMaterial()->GetDensity();
573 
574  //the act of stepping puts you in the next node and returns that node
575  node = gGeoManager->Step();
576  } //end loop to get to volume of second point
577 
578  //now you are in the same volume as the last point, but not at that point. get the
579  //distance between the current point and the last one
580  Point_t const last = vect::makePointFromCoords(gGeoManager->GetCurrentPoint());
581  double const lastStep = (p2 - last).R();
582  columnD += lastStep * node->GetMedium()->GetMaterial()->GetDensity();
583 
584  return columnD;
585  }
586 
587  //......................................................................
588  std::string GeometryCore::Info(std::string indent /* = "" */) const
589  {
590  std::ostringstream sstr;
591  Print(sstr, indent);
592  return sstr.str();
593  }
594 
595  //============================================================================
596  //--------------------------------------------------------------------
597  // Convert OpDet, Cryo into unique OpDet number
598  unsigned int GeometryCore::OpDetFromCryo(unsigned int o, unsigned int c) const
599  {
600  static bool Loaded = false;
601  static std::vector<unsigned int> LowestID;
602  static unsigned int NCryo;
603 
604  CryostatID const cid{c};
605  // If not yet loaded static parameters, do it
606  if (Loaded == false) {
607 
608  Loaded = true;
609 
610  // Store the lowest ID for each cryostat
611  NCryo = Ncryostats();
612  LowestID.resize(NCryo + 1);
613  LowestID.at(0) = 0;
614  for (size_t cryo = 0; cryo != NCryo; ++cryo) {
615  LowestID.at(cryo + 1) = LowestID.at(cryo) + Cryostat(cid).NOpDet();
616  }
617  }
618 
619  if ((c < NCryo) && (o < Cryostat(cid).NOpDet())) { return LowestID.at(c) + o; }
620 
621  throw cet::exception("OpDetCryoToOpID Error")
622  << "Coordinates c=" << c << ", o=" << o << " out of range. Abort\n";
623  }
624 
625  //--------------------------------------------------------------------
626  OpDetGeo const& GeometryCore::OpDetGeoFromOpDet(unsigned int OpDet) const
627  {
628  static bool Loaded = false;
629  static std::vector<unsigned int> LowestID;
630  static size_t NCryo;
631  // If not yet loaded static parameters, do it
632  if (Loaded == false) {
633 
634  Loaded = true;
635 
636  // Store the lowest ID for each cryostat
637  NCryo = Ncryostats();
638  LowestID.resize(NCryo + 1);
639  LowestID[0] = 0;
640  for (size_t cryo = 0; cryo != NCryo; ++cryo) {
641  LowestID[cryo + 1] = LowestID[cryo] + Cryostat(CryostatID(cryo)).NOpDet();
642  }
643  }
644 
645  for (size_t i = 0; i != NCryo; ++i) {
646  if ((OpDet >= LowestID[i]) && (OpDet < LowestID[i + 1])) {
647  int c = i;
648  int o = OpDet - LowestID[i];
649  return Cryostat(CryostatID(c)).OpDet(o);
650  }
651  }
652  // If we made it here, we didn't find the right combination. abort
653  throw cet::exception("OpID To OpDetCryo error") << "OpID out of range, " << OpDet << "\n";
654  }
655 
656  //--------------------------------------------------------------------
657  // Find the closest OpChannel to this point, in the appropriate cryostat
658  unsigned int GeometryCore::GetClosestOpDet(Point_t const& point) const
659  {
660  CryostatGeo const* cryo = PositionToCryostatPtr(point);
661  if (!cryo) return std::numeric_limits<unsigned int>::max();
662  int o = cryo->GetClosestOpDet(point);
663  return OpDetFromCryo(o, cryo->ID().Cryostat);
664  }
665 
666  //--------------------------------------------------------------------
667  //--- ROOTGeoNodeForwardIterator
668  //---
669 
671  {
672  if (start_node) {
673  current_path.push_back({start_node, 0U});
674  reach_deepest_descendant();
675  }
676  }
677 
679  {
680  if (current_path.empty()) return *this;
681  if (current_path.size() == 1) {
682  current_path.pop_back();
683  return *this;
684  }
685 
686  // I am done; all my descendants were also done already; first look at my younger
687  // siblings
688  NodeInfo_t& current = current_path.back();
689  NodeInfo_t const& parent = current_path[current_path.size() - 2];
690  if (++(current.sibling) < parent.self->GetNdaughters()) {
691  // my next sibling exists, let's parse his descendents
692  current.self = parent.self->GetDaughter(current.sibling);
693  reach_deepest_descendant();
694  }
695  else
696  current_path.pop_back(); // no sibling, it's time for mum
697  return *this;
698  }
699 
700  //--------------------------------------------------------------------
701  std::vector<TGeoNode const*> ROOTGeoNodeForwardIterator::get_path() const
702  {
703  std::vector<TGeoNode const*> node_path(current_path.size());
704  std::transform(current_path.begin(),
705  current_path.end(),
706  node_path.begin(),
707  [](NodeInfo_t const& node_info) { return node_info.self; });
708  return node_path;
709  }
710 
711  //--------------------------------------------------------------------
713  {
714  TGeoNode const* descendent = current_path.back().self;
715  while (descendent->GetNdaughters() > 0) {
716  descendent = descendent->GetDaughter(0);
717  current_path.push_back({descendent, 0U});
718  }
719  }
720 
721 } // namespace geo
CryostatGeo const * PositionToCryostatPtr(Point_t const &point) const
Returns the cryostat at specified location.
std::string const & GetWorldVolumeName() const
Return the name of the world volume (needed by Geant4 simulation)
IDparameter< geo::CryostatID > CryostatID
Member type of validated geo::CryostatID parameter.
Specializations of geo_vectors_utils.h for ROOT old vector types.
Functions to help with numbers.
TGeoNode const * operator*() const
Returns the pointer to the current node, or nullptr if none.
unsigned int TotalNTPC() const
Returns the total number of TPCs in the detector.
std::vector< NodeInfo_t > current_path
which node, which sibling?
bool operator()(TGeoNode const &node) const
Returns whether the specified node matches a set of names.
OpDetGeo const & OpDet(unsigned int iopdet) const
Return the iopdet&#39;th optical detector in the cryostat.
Definition: CryostatGeo.cxx:83
Float_t y1[n_points_granero]
Definition: compare.C:5
ROOTGeoNodeForwardIterator & operator++()
Points to the next node, or to nullptr if there are no more.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
Encapsulate the geometry of the sensitive portion of an auxiliary detector .
std::vector< GeoNodePathEntry > FindDetectorEnclosure(std::string const &name="volDetEnclosure") const
Point_t Max() const
Returns the corner point with the largest coordinates.
unsigned int GetClosestOpDet(Point_t const &point) const
void Print(Stream &&out, std::string indent=" ") const
Prints geometry information with maximum verbosity.
Definition: GeometryCore.h:633
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
GENVECTOR_CONSTEXPR Point_t makePointFromCoords(Coords &&coords)
Creates a geo::Point_t from its coordinates (see makeFromCoords()).
Float_t x1[n_points_granero]
Definition: compare.C:5
CryostatList_t fCryostats
Definition: GeometryCore.h:605
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
unsigned int GetClosestOpDet(Point_t const &point) const
Find the nearest OpChannel to some point.
Geometry information for a single TPC.
Definition: TPCGeo.h:33
BoxBoundedGeo DetectorEnclosureBox(std::string const &name="volDetEnclosure") const
constexpr auto abs(T v)
Returns the absolute value of the argument.
double fSurfaceY
The point where air meets earth for this detector.
Definition: GeometryCore.h:613
TGeoVolume const * WorldVolume() const
Returns a pointer to the world volume.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
void LocalToWorld(double const *local, double *world) const
Transforms a point from local frame to world frame.
TGeoMaterial const * Material(Point_t const &point) const
Returns the material at the specified position.
Geometry information for a single cryostat.
Definition: CryostatGeo.h:42
std::set< std::string > const * vol_names
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:303
void operator()(TGeoNode const &node)
If the name of the node matches, records the end node.
CryostatGeo const & PositionToCryostat(Point_t const &point) const
Returns the cryostat at specified location.
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
unsigned int OpDetFromCryo(unsigned int o, unsigned int c) const
Get unique opdet number from cryo and internal count.
Float_t y2[n_points_geant4]
Definition: compare.C:26
std::vector< std::vector< TGeoNode const * > > paths
double TotalMass() const
Returns the total mass [kg] of the specified volume (default: world).
Definition: GeometryCore.h:255
std::string searchPathPlusRelative(std::string relativePath, std::string fileName)
Access the description of the physical detector geometry.
void operator()(ROOTGeoNodeForwardIterator const &iter)
If the name of the node matches, records the node full path.
NodeNameMatcherClass matcher
std::string VolumeName(Point_t const &point) const
Returns the name of the deepest volume containing specified point.
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
Iterator to navigate through all the nodes.
Class to transform between world and local coordinates.
Classes to project and compose a vector on a plane.
void operator()(ROOTGeoNodeForwardIterator const &iter)
ROOTGeoNodeForwardIterator(TGeoNode const *start_node)
TPCGeo const & PositionToTPC(Point_t const &point) const
Returns the TPC at specified location.
CryostatGeo const * CryostatPtr(CryostatID const &cryoid) const
Returns the specified cryostat.
Definition: GeometryCore.h:345
std::string MaterialName(Point_t const &point) const
Name of the deepest material containing the point xyz.
std::string indent(std::size_t const i)
NodeNameMatcherClass(std::set< std::string > const &names)
Utilities to extend the interface of geometry vectors.This library provides facilities that can be us...
double MinZ() const
Returns the world z coordinate of the start of the box.
std::unique_ptr< GeoObjectSorter > fSorter
Definition: GeometryCore.h:608
CryostatID const & ID() const
Returns the identifier of this cryostat.
Definition: CryostatGeo.h:126
std::string Info(std::string indent=" ") const
Returns a string with complete geometry information.
bool FindFirstVolume(std::string const &name, std::vector< GeoNodePathEntry > &path) const
GeometryCore(fhicl::ParameterSet const &pset, std::unique_ptr< GeometryBuilder > builder, std::unique_ptr< GeoObjectSorter > sorter)
Initialize geometry from a given configuration.
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
TGeoManager * fManager
Definition: GeometryCore.h:610
NodeNameMatcherClass matcher
CryostatGeo const & Cryostat(CryostatID const &cryoid=details::cryostat_zero) const
Returns the specified cryostat.
unsigned int NOpDets() const
Number of OpDets in the whole detector.
std::vector< TGeoNode const * > get_path() const
Returns the full path of the current node.
double fPositionWiggle
accounting for rounding errors when testing positions
Definition: GeometryCore.h:614
double MaxY() const
Returns the world y coordinate of the end of the box.
Encapsulate the geometry of an auxiliary detector.
std::vector< TGeoNode const * > FindAllVolumes(std::set< std::string > const &vol_names) const
Returns all the nodes with volumes with any of the specified names.
Encapsulate the geometry of an optical detector.
std::string fGDMLfile
path to geometry file used for Geant4 simulation
Definition: GeometryCore.h:611
TPCID PositionToTPCID(Point_t const &point, double wiggle) const
Returns the ID of the TPC at specified location.
BoxBoundedGeo WorldBox() const
CryostatID PositionToCryostatID(Point_t const &point) const
Returns the ID of the cryostat at specified location.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
Point_t Min() const
Returns the corner point with the smallest coordinates.
double MassBetweenPoints(Point_t const &p1, Point_t const &p2) const
Returns the column density between two points.
unsigned int CryostatID_t
Type for the ID number.
Definition: geo_types.h:188
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:31
void BuildGeometry()
Parses ROOT geometry nodes and builds LArSoft geometry representation.
std::string maybe_default_detector_name(fhicl::ParameterSet const &pset, std::string const &filename)
CollectNodesByName(std::set< std::string > const &names)
std::vector< TGeoNode const * > nodes
TDirectory * dir
Definition: macro.C:5
unsigned int NOpDet() const
Number of optical detectors in this TPC.
Definition: CryostatGeo.h:317
double MaxZ() const
Returns the world z coordinate of the end of the box.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::unique_ptr< GeometryBuilder > fBuilder
Definition: GeometryCore.h:607
std::string fDetectorName
Name of the detector.
Definition: GeometryCore.h:612
Representation of a node and its ancestry.
Definition: GeoNodePath.h:34
std::vector< std::vector< TGeoNode const * > > FindAllVolumePaths(std::set< std::string > const &vol_names) const
Returns paths of all nodes with volumes with the specified names.
TPCGeo const * PositionToTPCptr(Point_t const &point, double wiggle) const
Returns a pointer to the TPC at specified location.
CollectPathsByName(std::set< std::string > const &names)
Float_t x2[n_points_geant4]
Definition: compare.C:26
Double_t sum
Definition: plot.C:31
TPCGeo const * PositionToTPCptr(Point_t const &point) const
Returns the TPC at specified location.
ROOT libraries.
double MinY() const
Returns the world y coordinate of the start of the box.
TPCID const & ID() const
Returns the identifier of this TPC.
Definition: TPCGeo.h:147
unsigned int MaxTPCs() const
Returns the largest number of TPCs a cryostat in the detector has.
TPCID PositionToTPCID(Point_t const &point) const
Returns the ID of the TPC at specified location.
bool ContainsPosition(Point_t const &point, double wiggle=1.0) const
Returns whether this volume contains the specified point.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
The data type to uniquely identify a cryostat.
Definition: geo_types.h:187