All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CathodeCrossingUtils.h
Go to the documentation of this file.
1 /**
2  * @file icaruscode/Analysis/trigger/details/CathodeCrossingUtils.h
3  * @brief Algorithms dealing with a trajectory and the cathode.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date July 27, 2022
6  * @see icaruscode/Analysis/trigger/details/CathodeCrossingUtils.cxx
7  */
8 
9 #ifndef ICARUSCODE_ANALYSIS_TRIGGER_DETAILS_CATHODECROSSINGUTILS_H
10 #define ICARUSCODE_ANALYSIS_TRIGGER_DETAILS_CATHODECROSSINGUTILS_H
11 
12 
13 // ICARUS libraries
14 #include "icaruscode/Utilities/TrajectoryUtils.h" // util::findCrossingSegment()
15 
16 // LArSoft libraries
17 #include "larcoreobj/SimpleTypesAndConstants/geo_vectors.h" // geo::Point_t ...
18 
19 // C/C++ standard libraries
20 #include <vector>
21 #include <iterator> // std::distance()
22 #include <type_traits> // std::is_same_v
23 #include <cmath> // std::abs()
24 
25 
26 // -----------------------------------------------------------------------------
27 // forward declarations
28 namespace geo {
29  class GeometryCore;
30  class CryostatGeo;
31 }
32 
33 
34 // -----------------------------------------------------------------------------
35 namespace icarus {
36 
37  // --- BEGIN -- Data structures ---------------------------------------------
38  /// Simple description for the cathode.
39  struct CathodeDesc_t {
42  };
43 
44 
45  /// Information about the cathode crossing of a path.
47  static std::size_t const NoIndex = std::numeric_limits<std::size_t>::max();
48  std::size_t indexBefore = NoIndex; ///< Index of the point "before" cathode.
49  std::size_t indexAfter = NoIndex; ///< Index of the point "after" cathode.
50  double before = 0.0; ///< Length of the path "before" the cathode.
51  double after = 0.0; ///< Length of the path "after" the cathode.
52  geo::Point_t crossingPoint; ///< Trajectory crossing point.
53 
54  /// Returns whether the crossing information is valid.
55  operator bool() const { return indexBefore != indexAfter; }
56 
57  /// Returns whether the crossing information is invalid.
58  bool operator!() const { return indexBefore == indexAfter; }
59 
60  }; // CathodeCrossing_t
61 
62 
63  // --- END ---- Data structures ---------------------------------------------
64 
65  // ---------------------------------------------------------------------------
66  /**
67  * @brief Returns cathode information for cryostat at the specified `point`.
68  *
69  * The normal to the cathode is always the same as the normal of the first TPC
70  * in the cryostat containing `point`. This ensures consistency within the
71  * cryostat.
72  */
73  CathodeDesc_t findTPCcathode
74  (geo::Point_t const& point, geo::GeometryCore const& geom);
75 
76 
77  // ---------------------------------------------------------------------------
78  /// Returns the distance of a `point` from the `cathode`.
79  double distance(geo::Point_t const& point, CathodeDesc_t const& cathode);
80 
81 
82  // ---------------------------------------------------------------------------
83  /// Returns the center of the cathode in the specified cryostat.
85 
86 
87  // ---------------------------------------------------------------------------
88  /**
89  * @brief Returns the crossing point of a trajectory on the cathode.
90  * @tparam Iter type of iterator to a point in space
91  * @param begin iterator to the first point of the trajectory
92  * @param end iterator past the last point of the trajectory
93  * @param cathode description of the cathode plane
94  * @return the crossing information
95  *
96  * This algorithm intersects a path on a infinite plane in 3D space, and
97  * returns the intersection point.
98  *
99  * The path is a sequence of segments. For simple trajectories, there is only
100  * one crossing, and then the returned point lies on both the path and the
101  * plane (it is, indeed, the path/cathode intersection point).
102  * For trajectories which cross the plane multiple times, the details of the
103  * part of the trajectory between the first and the last crossing are ignored
104  * and the two chunks of end paths that lie entirely on one side of the
105  * cathode are joint by a segment, shortcutting the details of the path in
106  * between.
107  *
108  * The function also returns the length of the paths at the two sides of the
109  * cathode. Again, in case of multiple crossings, the details of the crossing
110  * are ignored and a single segment is used to connect the two sides, and the
111  * two lengths reflect that approximation.
112  * If no intersection point is found, the two partial lengths are both `0`.
113  */
114  template <typename Iter>
115  CathodeCrossing_t detectCrossing
116  (Iter begin, Iter end, CathodeDesc_t const& cathode);
117 
118 
119  // ---------------------------------------------------------------------------
120 
121 } // namespace icarus
122 
123 
124 // -----------------------------------------------------------------------------
125 // --- Template implementation
126 // -----------------------------------------------------------------------------
127 template <typename Iter>
129  (Iter begin, Iter end, CathodeDesc_t const& cathode)
130 {
131  using Point_t = typename Iter::value_type;
132 
133  // this function by itself is already generic;
134  // but the utilities and data it relies on (including the return value) aren't
135  static_assert(std::is_same_v<Point_t, geo::Point_t>,
136  "icarus::detectCrossing() only supports geo::Point_t points;"
137  " if needed, ask the author for extension"
138  );
139 
140  auto const isNegative = [&cathode]
141  (auto const& p) { return distance(p, cathode) < 0.0; };
142 
143  auto const [ itBeforeCathode, itAfterCathode ]
144  = util::findCrossingSegment(begin, end, isNegative);
145 
146  if (itBeforeCathode == itAfterCathode) {
147  std::size_t const nPoints = std::distance(begin, end);
148  return {
149  nPoints // indexBefore
150  , nPoints // indexAfter
151  // the rest is default
152  }; // no crossing at all
153  }
154 
155  CathodeCrossing_t crossInfo;
156 
157  crossInfo.indexBefore = std::distance(begin, itBeforeCathode);
158  crossInfo.indexAfter = std::distance(begin, itAfterCathode);
159 
160  // first estimation:
161  crossInfo.before = util::pathLength(begin, itBeforeCathode);
162  crossInfo.after = util::pathLength(itAfterCathode, end);
163 
164  auto const step = (*itAfterCathode - *itBeforeCathode);
165  double const stepLength = geo::vect::norm(step);
166 
167  // the two ends share the step in proportion to their cathode distance
168  double fBefore = std::abs(distance(*itBeforeCathode, cathode));
169  double fAfter = std::abs(distance(*itAfterCathode, cathode));
170  double const fTotal = fBefore + fAfter;
171  fBefore /= fTotal;
172  fAfter /= fTotal;
173 
174  crossInfo.before += fBefore * stepLength;
175  crossInfo.after += fAfter * stepLength;
176 
177  crossInfo.crossingPoint = *itBeforeCathode + fBefore * step;
178 
179  return crossInfo;
180 
181 } // icarus::detectCathodeCrossing()
182 
183 
184 // -----------------------------------------------------------------------------
185 
186 #endif // ICARUSCODE_ANALYSIS_TRIGGER_DETAILS_CATHODECROSSINGUTILS_H
bool operator!() const
Returns whether the crossing information is invalid.
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
geo::Point_t crossingPoint
Trajectory crossing point.
pdgs p
Definition: selectors.fcl:22
CathodeDesc_t findTPCcathode(geo::Point_t const &point, geo::GeometryCore const &geom)
Returns cathode information for cryostat at the specified point.
static constexpr bool
double after
Length of the path &quot;after&quot; the cathode.
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
geo::Point_t findCathodeCenter(geo::CryostatGeo const &cryo)
Returns the center of the cathode in the specified cryostat.
recob::tracking::Point_t Point_t
T abs(T value)
Simple description for the cathode.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
Definitions of geometry vector data types.
std::size_t indexBefore
Index of the point &quot;before&quot; cathode.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
double pathLength(BIter begin, EIter end)
Returns the total length of the specified path.
Description of geometry of one entire detector.
auto norm(Vector const &v)
Return norm of the specified vector.
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
CathodeCrossing_t detectCrossing(Iter begin, Iter end, CathodeDesc_t const &cathode)
Returns the crossing point of a trajectory on the cathode.
double before
Length of the path &quot;before&quot; the cathode.
Algorithms dealing with a trajectory as a sequence of 3D points.
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:184
Information about the cathode crossing of a path.
static std::size_t const NoIndex
std::size_t indexAfter
Index of the point &quot;after&quot; cathode.
std::pair< Iter, Iter > findCrossingSegment(Iter begin, Iter end, SideFunc sideOf)
Returns a path segment with ends on different sides than path ends.