GeometryBuilderStandard.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/Geometry/GeometryBuilderStandard.h
3  * @brief Standard implementation of geometry extractor.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date January 29, 2019
6  * @see `larcorealg/Geometry/GeometryBuilder.h`,
7  * `larcorealg/Geometry/GeometryBuilderStandard.cxx`
8  */
9 
10 #ifndef LARCOREALG_GEOMETRY_GEOMETRYBUILDERSTANDARD_H
11 #define LARCOREALG_GEOMETRY_GEOMETRYBUILDERSTANDARD_H
12 
13 // LArSoft libraries
22 
23 // support libraries
24 #include "fhiclcpp/types/Atom.h"
25 
26 // ROOT libraries
27 #include "TGeoNode.h"
28 
29 // C++ standard library
30 #include <string_view>
31 #include <limits> // std::numeric_limits<>
32 
33 
34 namespace geo {
35 
36  /**
37  * @brief Extracts of LArSoft geometry information from ROOT.
38  *
39  * The builder manages several components, each devoted to the extraction of
40  * a specific type of geometry object (e.g. cryostat, or wire plane within a
41  * TPC).
42  *
43  *
44  * Further customization notes
45  * ============================
46  *
47  * This builder does not extend the interface of `geo::GeometryBuilder`, but
48  * it defines a protected interface that other builder classes could override
49  * to customize single elements of the build. As long as the interface is
50  * complied to, the different components are interchangeable.
51  *
52  * If instead a different interface is needed for one component, the parent
53  * component needs to be customised too. For example, if the signature of
54  * `doExtractPlanes()` is changed, also `doMakePlane()` needs to be
55  * customized to correctly call the previous. In that case, take care of
56  * deleting the inherited interface to avoid confusion and errors.
57  *
58  *
59  * Technical notes on customization
60  * ---------------------------------
61  *
62  * The internal structure of the builder follows the pattern already employed
63  * in the base class.
64  * The base class defines both the public interface and the implementation,
65  * but it separates the two leaving the former as non-virtual functions,
66  * and the latter as virtual functions accessible only by derived classes.
67  *
68  * The `geo::GeometryBuilderStandard` class replicates this pattern in a more
69  * hidden level.
70  * The general flow of the algorithm is a top-down crawl of the geometry tree
71  * structure, where the top objects (cryostats and auxiliary detectors) are
72  * discovered and built, and each of these objects takes care of discovering
73  * its own relevant components. Therefore e.g. the cryostat algorithm will,
74  * once found a candidate cryostat, descend into it to discover TPCs and
75  * optical detectors. This nested discovery is delegated to other algorithms,
76  * and e.g. the TPC algorithm will take care of creating a TPC and populating
77  * it with wire planes whose discovery is again delegated to another
78  * algorithm.
79  *
80  * The interface of these algorithms is fixed and is part of the protected
81  * class interface, in a way mirroring `geo::GeometryBuilder` in that it does
82  * not rely on virtuality, but entirely protected. The implementation is also
83  * in the protected space.
84  *
85  * Each component type has five elements:
86  *
87  * * a type describing a collection of the object of this component;
88  * this is integral part of the protected interface
89  * * an interface to create an object for a single component, called
90  * `makeXxx()`, expected to rely on its implementation method `doMakeXxx()`
91  * * an interface to discover all the components of this type, and creating
92  * them; it is called `extractXxx()` and it logically relies on `makeXxx()`,
93  * expected to rely on its implementation method `doExtractXxx()`
94  * * a virtual implementation method of the component creation routine, called
95  * `doMakeXxx()` and expected to invoke the `extractYyy()` interface of
96  * all the subcomponents nested inside it
97  * * a virtual implementation method of the component discovery routine,
98  * called `doExtractXxx()` and expected to invoke the `makeYyy()` interface
99  * of all the subcomponents nested inside it
100  *
101  * The discovery interface and the collection type of two of these components
102  * are directly part of the public interface inherited from
103  * `geo::GeometryBuilder`.
104  *
105  */
107 
108  public:
109 
110  /// Configuration parameters.
111  struct Config {
112 
113  using Name = fhicl::Name;
115 
117  Name("maxDepth"),
118  Comment("maximum number of level of the geometry structure to descend"),
120  };
121 
123  Name("opDetGeoName"),
124  Comment("the start of the name of optical detector GDML nodes"),
125  "volOpDetSensitive" // default
126  };
127 
128  }; // struct Config
129 
131 
132  //
133  // we don't expand the public interface here
134  //
135 
136  protected:
137 
138  /// Maximum level to descend into in the path.
140 
141  /// Name of the optical detector nodes.
142  std::string fOpDetGeoName = "volOpDetSensitive";
143 
144 
145  // --- BEGIN Auxiliary detector information --------------------------------
146  /// @name Auxiliary detector information
147  /// @{
148 
149  // extractAuxiliaryDetectors() and AuxDets_t are inherited public interface
150 
151  /// Constructs a `geo::AuxDetGeo` from the current node of the `path`.
153  { return doMakeAuxDet(path); }
154 
155 
156  /// Core implementation of `extractCryostats()`.
157  ///
158  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
159  virtual AuxDets_t doExtractAuxiliaryDetectors(Path_t& path) override;
160 
161  /// Core implementation of `extractAuxiliaryDetectors()`.
162  virtual geo::AuxDetGeo doMakeAuxDet(Path_t& path);
163 
164  /// @}
165  // --- END Auxiliary detector information ----------------------------------
166 
167 
168  // --- BEGIN Auxiliary detector sensitive volume information ---------------
169  /// @name Auxiliary detector sensitive volume information
170  /// @{
171 
173 
174  /**
175  * @brief Looks for all auxiliary detectors under the specified path.
176  * @param path path pointing to the starting node
177  * @return a list of fully constructed auxiliary detectors
178  *
179  * The auxiliary detectors contain all their inner elements.
180  * The current node itself of the path is also considered as auxiliary
181  * detector candidate, then it is descended into.
182  *
183  * @note Multithreading note: `path` is allowed to change during processing.
184  */
186  { auto localPath = path; return doExtractAuxDetSensitive(localPath); }
187 
188  /// Constructs a `geo::AuxDetSensitiveGeo` from the current node of the
189  /// `path`.
191  { return doMakeAuxDetSensitive(path); }
192 
193 
194  /// Core implementation of `extractAuxDetSensitive()`.
195  ///
196  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
198 
199  /// Core implementation of `makeAuxDetSensitive()`.
201 
202  /// @}
203  // --- END Auxiliary detector sensitive volume information -----------------
204 
205 
206  // --- BEGIN Cryostat information ------------------------------------------
207  /// @name Cryostat information
208  /// @{
209 
210  // extractCryostats() and Cryostats_t are inherited public interface
211 
212  /// Constructs a `geo::CryostatGeo` from the current node of the `path`.
214  { return doMakeCryostat(path); }
215 
216 
217  /// Core implementation of `extractCryostats()`.
218  ///
219  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
220  virtual Cryostats_t doExtractCryostats(Path_t& path) override;
221 
222  /// Core implementation of `extractAuxDetSensitive()`.
223  virtual geo::CryostatGeo doMakeCryostat(Path_t& path);
224 
225  /// @}
226  // --- END Cryostat information --------------------------------------------
227 
228 
229  // --- BEGIN Optical detector information ----------------------------------
230  /// @name Optical detector information
231  /// @{
232 
234 
235  /**
236  * @brief Looks for all optical detectors under the specified path.
237  * @param path path pointing to the starting node
238  * @return a list of fully constructed optical detector objects
239  */
241  { auto localPath = path; return doExtractOpDets(localPath); }
242 
243  /// Constructs a `geo::OpDetGeo` from the current node of the `path`.
245  { return doMakeOpDet(path); }
246 
247 
248  /// Core implementation of `extractOpDets()`.
249  ///
250  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
251  virtual OpDets_t doExtractOpDets(Path_t& path);
252 
253  /// Core implementation of `makeOpDet()`.
254  virtual geo::OpDetGeo doMakeOpDet(Path_t& path);
255 
256  /// @}
257  // --- END Optical detector information ------------------------------------
258 
259 
260  // --- BEGIN TPC information -----------------------------------------------
261  /// @name TPC information
262  /// @{
263 
265 
266  /**
267  * @brief Looks for all TPCs under the specified path.
268  * @param path path pointing to the starting node
269  * @return a list of fully constructed TPC objects
270  *
271  * Each TPC has its own wire planes already in.
272  */
274  { auto localPath = path; return doExtractTPCs(localPath); }
275 
276  /// Constructs a `geo::TPCGeo` from the current node of the `path`.
278  { return doMakeTPC(path); }
279 
280 
281  /// Core implementation of `extractTPCs()`.
282  ///
283  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
284  virtual TPCs_t doExtractTPCs(Path_t& path);
285 
286  /// Core implementation of `makeTPC()`.
287  virtual geo::TPCGeo doMakeTPC(Path_t& path);
288 
289  /// @}
290  // --- END TPC information -------------------------------------------------
291 
292 
293  // --- BEGIN Plane information ---------------------------------------------
294  /// @name Wire plane information
295  /// @{
296 
298 
299  /**
300  * @brief Looks for all wire planes under the specified path.
301  * @param path path pointing to the starting node
302  * @return a list of fully constructed wire plane objects
303  *
304  * Each plane has its own wires already in.
305  */
307  { auto localPath = path; return doExtractPlanes(localPath); }
308 
309  /// Constructs a `geo::PlaneGeo` from the current node of the `path`.
311  { return doMakePlane(path); }
312 
313 
314  /// Core implementation of `extractPlanes()`.
315  ///
316  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
317  virtual Planes_t doExtractPlanes(Path_t& path);
318 
319  /// Core implementation of `makePlanes()`.
320  virtual geo::PlaneGeo doMakePlane(Path_t& path);
321 
322  /// @}
323  // --- END Plane information -----------------------------------------------
324 
325 
326  // --- BEGIN Wire information ----------------------------------------------
327  /// @name Wire information
328  /// @{
329 
331 
332  /**
333  * @brief Looks for all wires under the specified path.
334  * @param path path pointing to the starting node
335  * @return a list of fully constructed wires
336  *
337  */
339  { auto localPath = path; return doExtractWires(localPath); }
340 
341  /// Constructs a `geo::WireGeo` from the current node of the `path`.
343  { return doMakeWire(path); }
344 
345 
346  /// Core implementation of `extractWires()`.
347  ///
348  /// The actual algorithm is specialization of `doExtractGeometryObjects()`.
349  virtual Wires_t doExtractWires(Path_t& path);
350 
351  /// Core implementation of `makeWire()`.
352  virtual geo::WireGeo doMakeWire(Path_t& path);
353 
354  /// @}
355  // --- END Wire information ------------------------------------------------
356 
357 
358 
359  // --- BEGIN Note type identification --------------------------------------
360  /**
361  * @name Node type identification
362  *
363  * These are implementation details of `doExtractGeometryObjects()` and its
364  * users. They can be made virtual if the needs arises.
365  */
366  /// @{
367  /// Returns whether the specified node is recognised as auxiliary detector.
368  bool isAuxDetNode(TGeoNode const& node) const;
369 
370  /// Returns whether the specified node is recognised as sensitive volume of
371  /// auxiliary detector.
372  bool isAuxDetSensitiveNode(TGeoNode const& node) const;
373 
374  /// Returns whether the specified node is recognised as a cryostat.
375  bool isCryostatNode(TGeoNode const& node) const;
376 
377  /// Returns whether the specified node is recognised as a optical detector.
378  bool isOpDetNode(TGeoNode const& node) const;
379 
380  /// Returns whether the specified node is recognised as a TPC.
381  bool isTPCNode(TGeoNode const& node) const;
382 
383  /// Returns whether the specified node is recognised as a wire plane.
384  bool isPlaneNode(TGeoNode const& node) const;
385 
386  /// Returns whether the specified node is recognised as a wire.
387  bool isWireNode(TGeoNode const& node) const;
388 
389  /// @}
390  // --- END Note type identification ----------------------------------------
391 
392 
393  /// Returns whether the start of `s` matches the full `key`.
394  /// @note Remove this when C++20 is adopted (`s.starts_with(key)`).
395  static bool starts_with
396  (std::string_view const& s, std::string_view const& key)
397  { return s.compare(0, key.size(), key) == 0; }
398 
399 
400  private:
401 
402  /**
403  * @brief Boilerplate implementation of `doExtractXxxx()` methods.
404  * @tparam ObjGeo the geometry object being extracted (e.g. `geo::WireGeo`)
405  * @tparam IsObj function to identify if a node is of the right type
406  * @tparam MakeObj class method creating the target object from a path
407  * @param path the path to the node describing the object
408  * @return a fully constructed object of type `ObjGeo`
409  *
410  * This implementation first evaluates if the current node in the specified
411  * path is suitable to create a `ObjGeo`; if not, then it descends into the
412  * node daughters and recursively to their descendents.
413  * For each candidate node, a `ObjGeo` is created. All descendents of the
414  * candidates are ignored.
415  *
416  * @note Multithreading note: `path` is allowed to change during processing.
417  */
418  template <
419  typename ObjGeo,
420  bool (geo::GeometryBuilderStandard::*IsObj)(TGeoNode const&) const,
421  ObjGeo (geo::GeometryBuilderStandard::*MakeObj)(Path_t&)
422  >
424 
425 
426  }; // class GeometryBuilderStandard
427 
428 } // namespace geo
429 
430 
431 #endif // LARCOREALG_GEOMETRY_GEOMETRYBUILDERSTANDARD_H
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
Definition: WireGeo.h:65
virtual OpDets_t doExtractOpDets(Path_t &path)
TPCs_t extractTPCs(Path_t &path)
Looks for all TPCs under the specified path.
Planes_t extractPlanes(Path_t &path)
Looks for all wire planes under the specified path.
virtual geo::PlaneGeo doMakePlane(Path_t &path)
Core implementation of makePlanes().
virtual geo::AuxDetSensitiveGeo doMakeAuxDetSensitive(Path_t &path)
Core implementation of makeAuxDetSensitive().
virtual geo::TPCGeo doMakeTPC(Path_t &path)
Core implementation of makeTPC().
geo::TPCGeo makeTPC(Path_t &path)
Constructs a geo::TPCGeo from the current node of the path.
fhicl::Atom< Path_t::Depth_t > maxDepth
Encapsulate the construction of a single cyostat.
GeometryBuilderStandard(Config const &config)
std::string string
Definition: nybbler.cc:12
GeoColl_t< geo::AuxDetSensitiveGeo > AuxDetSensitive_t
Geometry information for a single TPC.
Definition: TPCGeo.h:38
bool isCryostatNode(TGeoNode const &node) const
Returns whether the specified node is recognised as a cryostat.
ChannelGroupService::Name Name
Interface for geometry extractor classes.
virtual geo::CryostatGeo doMakeCryostat(Path_t &path)
Core implementation of extractAuxDetSensitive().
geo::AuxDetGeo makeAuxDet(Path_t &path)
Constructs a geo::AuxDetGeo from the current node of the path.
virtual AuxDetSensitive_t doExtractAuxDetSensitive(Path_t &path)
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
virtual geo::AuxDetGeo doMakeAuxDet(Path_t &path)
Core implementation of extractAuxiliaryDetectors().
GeoColl_t< geo::AuxDetGeo > AuxDets_t
Collection of auxiliary detector information objects.
OpDets_t extractOpDets(Path_t &path)
Looks for all optical detectors under the specified path.
Encapsulate the geometry of the sensitive portion of an auxiliary detector.
virtual Cryostats_t doExtractCryostats(Path_t &path) override
GeoColl_t< ObjGeo > doExtractGeometryObjects(Path_t &path)
Boilerplate implementation of doExtractXxxx() methods.
virtual AuxDets_t doExtractAuxiliaryDetectors(Path_t &path) override
def key(type, name=None)
Definition: graph.py:13
bool isTPCNode(TGeoNode const &node) const
Returns whether the specified node is recognised as a TPC.
GeoColl_t< geo::WireGeo > Wires_t
static Config * config
Definition: config.cpp:1054
bool isOpDetNode(TGeoNode const &node) const
Returns whether the specified node is recognised as a optical detector.
std::string fOpDetGeoName
Name of the optical detector nodes.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
virtual TPCs_t doExtractTPCs(Path_t &path)
Encapsulate the geometry of an auxiliary detector.
GeoColl_t< geo::CryostatGeo > Cryostats_t
Collection of cryostat information objects.
static int max(int a, int b)
bool isWireNode(TGeoNode const &node) const
Returns whether the specified node is recognised as a wire.
Path_t::Depth_t fMaxDepth
Maximum level to descend into in the path.
virtual geo::OpDetGeo doMakeOpDet(Path_t &path)
Core implementation of makeOpDet().
GeoColl_t< geo::PlaneGeo > Planes_t
Encapsulate the geometry of a wire.
GeoColl_t< geo::OpDetGeo > OpDets_t
Encapsulate the geometry of an optical detector.
Wires_t extractWires(Path_t &path)
Looks for all wires under the specified path.
#define Comment
std::size_t Depth_t
Type used to represent the depth of the path.
Definition: GeoNodePath.h:50
Encapsulate the construction of a single detector plane.
bool isPlaneNode(TGeoNode const &node) const
Returns whether the specified node is recognised as a wire plane.
bool isAuxDetSensitiveNode(TGeoNode const &node) const
AuxDetSensitive_t extractAuxDetSensitive(Path_t &path)
Looks for all auxiliary detectors under the specified path.
virtual Wires_t doExtractWires(Path_t &path)
geo::OpDetGeo makeOpDet(Path_t &path)
Constructs a geo::OpDetGeo from the current node of the path.
Manages the extraction of LArSoft geometry information from ROOT.
Representation of a node and its ancestry.
Definition: GeoNodePath.h:38
LArSoft geometry interface.
Definition: ChannelGeo.h:16
geo::PlaneGeo makePlane(Path_t &path)
Constructs a geo::PlaneGeo from the current node of the path.
virtual Planes_t doExtractPlanes(Path_t &path)
int bool
Definition: qglobal.h:345
static QCString * s
Definition: config.cpp:1042
Extracts of LArSoft geometry information from ROOT.
Encapsulate the construction of a single detector plane.
std::vector< GeoObj > GeoColl_t
Type of direct collection of geometry objects.
geo::CryostatGeo makeCryostat(Path_t &path)
Constructs a geo::CryostatGeo from the current node of the path.
virtual geo::WireGeo doMakeWire(Path_t &path)
Core implementation of makeWire().
static bool starts_with(std::string_view const &s, std::string_view const &key)
bool isAuxDetNode(TGeoNode const &node) const
geo::WireGeo makeWire(Path_t &path)
Constructs a geo::WireGeo from the current node of the path.
geo::AuxDetSensitiveGeo makeAuxDetSensitive(Path_t &path)