All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PMTverticalSlicingAlg.h
Go to the documentation of this file.
1 /**
2  * @file icaruscode/PMT/Algorithms/PMTverticalSlicingAlg.h
3  * @brief Algorihtm to group PMTs into piling towers.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date January 7, 2020
6  * @see icaruscode/PMT/Algorithms/PMTverticalSlicingAlg.cxx
7  */
8 
9 #ifndef ICARUSCODE_PMT_ALGORITHMS_PMTVERTICALSLICINGALG_H
10 #define ICARUSCODE_PMT_ALGORITHMS_PMTVERTICALSLICINGALG_H
11 
12 // LArSoft libraries
13 #include "larcorealg/CoreUtils/StdUtils.h" // util::begin(), util::end()
14 #include "larcoreobj/SimpleTypesAndConstants/geo_vectors.h" // geo::Vector_t
15 
16 // framework libraries
17 #include "messagefacility/MessageLogger/MessageLogger.h"
18 #include "cetlib_except/exception.h"
19 
20 // C/C++ standard libraries
21 #include <vector>
22 #include <string>
23 
24 
25 // -----------------------------------------------------------------------------
26 // --- forward declarations
27 // ---
28 namespace geo {
29  class GeometryCore;
30  class CryostatGeo;
31  class OpDetGeo;
32 } // namespace geo
33 
34 
35 //------------------------------------------------------------------------------
36 namespace icarus::trigger { class PMTverticalSlicingAlg; }
37 /**
38  * @brief Algorithm clustering PMT according to their position.
39  *
40  * The algorithm groups the provided PMT by plane (determined from the drift
41  * direction of the TPC) and by the beam-like direction
42  * (the one that is not the vertical, i.e. TPC "width" direction).
43  *
44  */
46 
47  public:
48 
49  /// Type of optical detector list.
50  using PMTlist_t = std::vector<geo::OpDetGeo const*>;
51 
52  /// Type of optical detector list in a PMT tower.
54 
55  /// Type of list of PMT towers on a single optical detector plane.
56  using PMTtowerOnPlane_t = std::vector<PMTtower_t>;
57 
58  /// Type of PMT towers, per plane.
59  using Slices_t = std::vector<PMTtowerOnPlane_t>;
60 
61 
62  /// Constructor: no configuration parameters so far.
63  PMTverticalSlicingAlg(std::string logCategory = "PMTverticalSlicingAlg");
64 
65 
66  /// Computes slices from all PMT in `cryo` and appends them to `slices`.
67  void appendCryoSlices(Slices_t& slices, geo::CryostatGeo const& cryo) const;
68 
69  /**
70  * @brief Groups optical detectors under the specified cryostat into walls.
71  * @param cryo the cryostat containing the optical detectors
72  * @return a list of pairs: each an absolute drift coordinate and PMT list
73  *
74  * The algorithm returns a list of walls, with as first element a coordinate
75  * representing the wall (drift coordinate) and the second the list of
76  * optical detectors in that wall, in no particular order.
77  * The walls are sorted by increasing drift coordinate.
78  */
79  std::vector<std::pair<double, PMTlist_t>> PMTwalls
80  (geo::CryostatGeo const& cryo) const;
81 
82  /**
83  * @brief Groups optical detectors in all the detector into walls.
84  * @param geom the geometry description of the detector
85  * @return a list of pairs: each an absolute drift coordinate and PMT list
86  * @see `PMTwalls(geo::CryostatGeo const&) const`
87  *
88  * PMT walls are extracted for each of the cryostats in the detector, and
89  * the result is merged into a single collection.
90  */
91  std::vector<std::pair<double, PMTlist_t>> PMTwalls
92  (geo::GeometryCore const& geom) const;
93 
94 
95  private:
96 
97  std::string fLogCategory; ///< Category for message streaming.
98 
99  /// Computes slices and appends them to an existing list.
100  void appendSlices(
101  Slices_t& slices, PMTlist_t const& PMTs,
102  geo::Vector_t const& planeNorm, geo::Vector_t const& clusterDir
103  ) const;
104 
105  /**
106  * @brief Groups the specifies optical detectors into walls.
107  * @param PMTs the list of PMT to be grouped
108  * @param dir the direction normal to the walls
109  * @return a list of pairs: each an absolute wall coordinate and PMT list
110  *
111  * The algorithm returns a list of walls, with as first element a coordinate
112  * representing the wall and the second the list of optical detectors in that
113  * wall, in no particular order.
114  * The walls are sorted by increasing coordinate.
115  */
116  std::vector<std::pair<double, PMTlist_t>> PMTwalls
117  (PMTlist_t const& PMTs, geo::Vector_t const& dir) const;
118 
119 
120  /// Returns an (arbitrary) coordinate along `dir` representing the PMT list.
121  static double PMTwallPosition
122  (PMTlist_t const& PMTs, geo::Vector_t const& dir);
123 
124 
125  template <typename TPCCont>
126  static geo::Vector_t determineDriftDir(TPCCont const& TPCcont);
127 
128  template <typename TPCCont>
129  static geo::Vector_t determineLengthDir(TPCCont const& TPCcont);
130 
131  /// Clusters the PMTs along the specified direction.
132  static std::vector<PMTlist_t> clusterPMTby
133  (PMTlist_t const& PMTs, geo::Vector_t const& dir);
134 
135  /// Returns a list of all `geo::OpDetGeo` in cryostat `cryo`.
136  static PMTlist_t getCryoPMTs(geo::CryostatGeo const& cryo);
137 
138  /// Returns a list of all `geo::OpDetGeo` in the whole geometry.
139  static PMTlist_t getPMTs(geo::GeometryCore const& geom);
140 
141  // pretty sure this is already in some feature branch if not in LArSoft...
142  /// Returns whether `a` and `b` are parallel.
143  static bool areParallel(geo::Vector_t const& a, geo::Vector_t const& b);
144 
145 }; // class icarus::trigger::PMTverticalSlicingAlg
146 
147 
148 //------------------------------------------------------------------------------
149 //--- template implementation
150 //------------------------------------------------------------------------------
151 template <typename TPCCont>
153  (TPCCont const& TPCcont)
154 {
155 
156  auto iTPC = util::begin(TPCcont);
157  auto const tend = util::end(TPCcont);
158 
159  if (iTPC == tend) {
160  throw cet::exception("PMTverticalSlicingAlg")
161  << "determineDriftDir(): no TPC in the specified object!";
162  }
163 
164  auto const dir = iTPC->template DriftDir<geo::Vector_t>();
165  while(++iTPC != tend) {
166  if (areParallel(iTPC->template DriftDir<geo::Vector_t>(), dir))
167  continue;
168  throw cet::exception("PMTverticalSlicingAlg")
169  << "determineDriftDir(): TPC " << iTPC->ID()
170  << " has a drift direction incompatible with " << dir << ".\n";
171  } // while
172 
173  return dir;
174 
175 } // icarus::trigger::PMTverticalSlicingAlg::determineDriftDir()
176 
177 
178 //------------------------------------------------------------------------------
179 template <typename TPCCont>
181  (TPCCont const& TPCcont)
182 {
183 
184  auto iTPC = util::begin(TPCcont);
185  auto const tend = util::end(TPCcont);
186 
187  if (iTPC == tend) {
188  throw cet::exception("PMTverticalSlicingAlg")
189  << "determineLengthDir(): no TPC in the specified object!";
190  }
191 
192  auto const dir = iTPC->template LengthDir<geo::Vector_t>();
193  while(++iTPC != tend) {
194  if (areParallel(iTPC->template LengthDir<geo::Vector_t>(), dir))
195  continue;
196  throw cet::exception("PMTverticalSlicingAlg")
197  << "determineLengthDir(): TPC " << iTPC->ID()
198  << " has a width direction incompatible with " << dir << ".\n";
199  } // while
200 
201  return dir;
202 
203 } // icarus::trigger::PMTverticalSlicingAlg::determineLengthDir()
204 
205 
206 //------------------------------------------------------------------------------
207 
208 
209 #endif // ICARUSCODE_PMT_ALGORITHMS_PMTVERTICALSLICINGALG_H
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
std::vector< geo::OpDetGeo const * > PMTlist_t
Type of optical detector list.
PMTverticalSlicingAlg(std::string logCategory="PMTverticalSlicingAlg")
Constructor: no configuration parameters so far.
void appendSlices(Slices_t &slices, PMTlist_t const &PMTs, geo::Vector_t const &planeNorm, geo::Vector_t const &clusterDir) const
Computes slices and appends them to an existing list.
static std::vector< PMTlist_t > clusterPMTby(PMTlist_t const &PMTs, geo::Vector_t const &dir)
Clusters the PMTs along the specified direction.
static PMTlist_t getPMTs(geo::GeometryCore const &geom)
Returns a list of all geo::OpDetGeo in the whole geometry.
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
static geo::Vector_t determineLengthDir(TPCCont const &TPCcont)
process_name gaushit a
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
void appendCryoSlices(Slices_t &slices, geo::CryostatGeo const &cryo) const
Computes slices from all PMT in cryo and appends them to slices.
Definitions of geometry vector data types.
Description of geometry of one entire detector.
std::string fLogCategory
Category for message streaming.
std::vector< TCSlice > slices
Definition: DataStructs.cxx:13
static bool areParallel(geo::Vector_t const &a, geo::Vector_t const &b)
Returns whether a and b are parallel.
tuple dir
Definition: dropbox.py:28
std::vector< std::pair< double, PMTlist_t > > PMTwalls(geo::CryostatGeo const &cryo) const
Groups optical detectors under the specified cryostat into walls.
Functions pulling in STL customization if available.
static double PMTwallPosition(PMTlist_t const &PMTs, geo::Vector_t const &dir)
Returns an (arbitrary) coordinate along dir representing the PMT list.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
static geo::Vector_t determineDriftDir(TPCCont const &TPCcont)
std::vector< PMTtowerOnPlane_t > Slices_t
Type of PMT towers, per plane.
PMTlist_t PMTtower_t
Type of optical detector list in a PMT tower.
std::vector< PMTtower_t > PMTtowerOnPlane_t
Type of list of PMT towers on a single optical detector plane.
static PMTlist_t getCryoPMTs(geo::CryostatGeo const &cryo)
Returns a list of all geo::OpDetGeo in cryostat cryo.
Algorithm clustering PMT according to their position.