ROOTGeometryNavigator.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/Geometry/ROOTGeometryNavigator.h
3  * @brief Class representing a path in ROOT geometry.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date January 29, 2019
6  * @see `larcorealg/Geometry/GeometryBuilder.h`,
7  * `larcorealg/Geometry/GeoNodePath.cxx`
8  */
9 
10 #ifndef LARCOREALG_GEOMETRY_ROOTGEOMETRYNAVIGATOR_H
11 #define LARCOREALG_GEOMETRY_ROOTGEOMETRYNAVIGATOR_H
12 
13 
14 // LArSoft libraries
16 #include "larcorealg/CoreUtils/counter.h" // geo::...::makeFromCoords()
17 
18 // ROOT libraries
19 #include "TGeoManager.h"
20 #include "TGeoNode.h"
21 #include "TGeoVolume.h"
22 
23 // C++ standard library
24 #include <utility> // std::forward()
25 #include <cassert>
26 
27 
28 namespace geo {
29 
30  class ROOTGeometryNavigator;
31 
32 } // namespace geo
33 
34 
35 //------------------------------------------------------------------------------
36 /**
37  * @brief Executes an operation on all the nodes of the ROOT geometry.
38  *
39  * For example, to collect the path (see `geo::GeoNodePath`) of all the volumes
40  * named `"volTPC"` in the geometry loaded in LArSoft:
41  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
42  * std::string const volumeName = "volTPC";
43  *
44  * auto const& geom = *(lar::providerFrom<geo::Geometry>());
45  *
46  * geo::ROOTGeometryNavigator navigator { *(geom.ROOTGeoManager()) };
47  *
48  * // the operation executed on all nodes accumulates the paths in `volumePaths`
49  * std::vector<geo::GeoNodePath> volumePaths;
50  * auto findVolume = [&volumePaths, volumeName](auto& path)
51  * {
52  * if (path.current().GetVolume()->GetName() == volumeName)
53  * volumePaths.push_back(path);
54  * return true;
55  * };
56  *
57  * geo::ROOTGeometryNavigator navigator { *(geom.ROOTGeoManager()) };
58  *
59  * navigator.apply(findVolume);
60  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61  *
62  *
63  */
65 
66  TGeoNode const* fTopNode = nullptr;
67 
68  public:
69 
70  /// Constructor: picks the manager.
71  ROOTGeometryNavigator(TGeoManager const& manager)
72  : fTopNode(manager.GetTopNode())
73  {}
74 
75  /**
76  * @brief Applies the specified operation to all nodes under the `path`.
77  * @tparam Op type of operation (see description)
78  * @param path the path to the first node to operate on
79  * @param op operation to be applied
80  * @return whether all nodes in the path were processed
81  *
82  * The operation `Op` must be a callable accepting a `geo::GeoNodePath`
83  * immutable argument and returning a value convertible to boolean.
84  * If a call to `op` results into a `false` value, the recursion is
85  * terminated and `false` is returned. `path` will be pointing to the
86  * last node already processed.
87  *
88  * The node at the head of the path is processed first, then for each
89  * daughter node, first the daughter itself then its own daughters,
90  * recursively.
91  */
92  template <typename Op>
93  bool apply(geo::GeoNodePath& path, Op&& op) const;
94 
95  /**
96  * @brief Applies the specified operation to all nodes under `node`.
97  * @tparam Op type of operation (see description)
98  * @param node the node to start from
99  * @param op operation to be applied
100  * @return whether all nodes in the path were processed
101  * @see `apply(geo::GeoNodePath&, Op&&) const`
102  *
103  * The operation `Op` must be a callable accepting a `geo::GeoNodePath`
104  * immutable argument.
105  */
106  template <typename Op>
107  bool apply(TGeoNode const& node, Op&& op) const;
108 
109  /**
110  * @brief Applies the specified operation to all nodes.
111  * @tparam Op type of operation (see description)
112  * @param op operation to be applied
113  * @return whether all nodes in the path were processed
114  *
115  * The operation `Op` must be a callable accepting a `geo::GeoNodePath`
116  * immutable argument.
117  */
118  template <typename Op>
119  bool apply(Op&& op) const;
120 
121 }; // geo::ROOTGeometryNavigator
122 
123 
124 //------------------------------------------------------------------------------
125 //--- template implementation
126 //------------------------------------------------------------------------------
127 template <typename Op>
129  if (!op(path)) return false;
130 
131  TGeoNode const& node = path.current();
132  TGeoVolume const* pVolume = node.GetVolume();
133  if (pVolume) { // is it even possible not to?
134  int const nDaughters = pVolume->GetNdaughters();
135  for (int iDaughter: util::counter<int>(nDaughters)) {
136  TGeoNode const* pDaughter = pVolume->GetNode(iDaughter);
137  if (!pDaughter) continue; // fishy...
138 
139  path.append(*pDaughter);
140  if (!apply(path, std::forward<Op>(op))) return false;
141  path.pop();
142  } // for
143  } // if we have a volume
144 
145  return true;
146 } // geo::ROOTGeometryNavigator::apply()
147 
148 
149 //------------------------------------------------------------------------------
150 template <typename Op>
151 bool geo::ROOTGeometryNavigator::apply(TGeoNode const& node, Op&& op) const {
152  geo::GeoNodePath path { &node };
153  return apply(path, std::forward<Op>(op));
154 } // geo::ROOTGeometryNavigator::apply()
155 
156 
157 //------------------------------------------------------------------------------
158 template <typename Op>
160  assert(fTopNode);
161  return apply(*fTopNode, std::forward<Op>(op));
162 } // geo::ROOTGeometryNavigator::apply()
163 
164 
165 //------------------------------------------------------------------------------
166 
167 
168 #endif // LARCOREALG_GEOMETRY_ROOTGEOMETRYNAVIGATOR_H
bool apply(geo::GeoNodePath &path, Op &&op) const
Applies the specified operation to all nodes under the path.
Executes an operation on all the nodes of the ROOT geometry.
Class representing a path in ROOT geometry.
void append(Node_t const &node)
Adds a node to the current path.
Definition: GeoNodePath.h:85
void pop()
Removes the current node from the path, moving the current one up.
Definition: GeoNodePath.h:88
Test of util::counter and support utilities.
Representation of a node and its ancestry.
Definition: GeoNodePath.h:38
Node_t const & current() const
Returns the current node. Undefined if the path is empty.
Definition: GeoNodePath.h:78
ROOTGeometryNavigator(TGeoManager const &manager)
Constructor: picks the manager.
LArSoft geometry interface.
Definition: ChannelGeo.h:16