LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
SpacePointAlg_TimeSort.cxx
Go to the documentation of this file.
1 
19 
20 #include <math.h>
21 
22 // Framework includes
25 #include "cetlib_except/exception.h"
27 
28 // LArSoft Includes
34 
35 //boost includes
36 #include "boost/multi_array.hpp"
37 
38 namespace {
39  inline bool HitTimeComparison(art::Ptr<recob::Hit> const& a, art::Ptr<recob::Hit> const& b)
40  {
41  return a->PeakTime() < b->PeakTime();
42  }
43 }
44 
45 namespace sppt {
46 
47  //-------------------------------------------------
49  {
50  fTimeDiffMax = pset.get<float>("TimeDiffMax");
51  fZDiffMax = pset.get<float>("ZDiffMax");
52  fYDiffMax = pset.get<float>("YDiffMax");
53 
54  //enforce a minimum time diff
55  if (fTimeDiffMax < 0) {
56  throw cet::exception("SpacePointAlg_TimeSort")
57  << "Time difference must be greater than zero.";
58  }
59  if (fZDiffMax < 0) {
60  throw cet::exception("SpacePointAlg_TimeSort")
61  << "Z-coordinate difference must be greater than zero.";
62  }
63  if (fYDiffMax < 0) {
64  throw cet::exception("SpacePointAlg_TimeSort")
65  << "Y-coordinate difference must be greater than zero.";
66  }
67  }
68 
69  //-------------------------------------------------
71  {
72  TIME_OFFSET_U = -1 * detProp.GetXTicksOffset(geo::View_t::kU, 0, 0);
73  TIME_OFFSET_V = -1 * detProp.GetXTicksOffset(geo::View_t::kV, 0, 0);
74  TIME_OFFSET_Y = -1 * detProp.GetXTicksOffset(geo::View_t::kZ, 0, 0);
75  TICKS_TO_X = detProp.GetXTicksCoefficient();
76 
77  TIME_OFFSET_SET = true;
78  }
79 
80  //-------------------------------------------------
82  {
84  constexpr geo::TPCID tpcid{0, 0};
85  geo::PlaneID const uplane_id{tpcid, geo::View_t::kU};
86  geo::PlaneID const vplane_id{tpcid, geo::View_t::kV};
87  geo::PlaneID const zplane_id{tpcid, geo::View_t::kZ};
88 
89  unsigned int nwires_u = geom->Nwires(uplane_id);
90  unsigned int nwires_v = geom->Nwires(vplane_id);
91  unsigned int nwires_y = geom->Nwires(zplane_id);
92 
93  coordinates_UV_y.resize(boost::extents[nwires_v][nwires_u]);
94  coordinates_UV_z.resize(boost::extents[nwires_v][nwires_u]);
95  coordinates_UY_y.resize(boost::extents[nwires_y][nwires_u]);
96  coordinates_UY_z.resize(boost::extents[nwires_y][nwires_u]);
97  for (unsigned int iu = 0; iu < nwires_u; iu++) {
98  for (unsigned int iv = 0; iv < nwires_v; iv++) {
99  geom->IntersectionPoint(geo::WireID{uplane_id, iu},
100  geo::WireID{vplane_id, iv},
101  coordinates_UV_y[iv][iu], //y
102  coordinates_UV_z[iv][iu]); //z
103  }
104  for (unsigned int iy = 0; iy < nwires_y; iy++) {
105  geom->IntersectionPoint(geo::WireID{uplane_id, iu},
106  geo::WireID{zplane_id, iy},
107  coordinates_UY_y[iy][iu],
108  coordinates_UY_z[iy][iu]);
109  }
110  }
111 
112  COORDINATES_FILLED = true;
113  }
114 
115  //-------------------------------------------------
117  detinfo::DetectorPropertiesData const& detProp,
121  std::unique_ptr<std::vector<recob::SpacePoint>>& spptCollection,
122  std::unique_ptr<std::vector<std::vector<art::Ptr<recob::Hit>>>>& spptAssociatedHits)
123  {
124 
125  if (!TIME_OFFSET_SET) {
126  mf::LogWarning("SpacePointAlg_TimeSort")
127  << "Time offsets not set before createSpacePoints call!"
128  << "\nYou should call SpacePointAlg_TimeSort::setTimeOffsets() in beginRun()!"
129  << "\nWill be set now, but you should modify your code!";
130  setTimeOffsets(detProp);
131  }
132  if (!COORDINATES_FILLED) {
133  mf::LogWarning("SpacePointAlg_TimeSort")
134  << "Coordinate arrays not filled before createSpacePoints call!"
135  << "\nYou should call SpacePointAlg_TimeSort::fillCoordinateArrays() in beginRun()!"
136  << "\nWill be filled now, but you should modify your code!";
138  }
139 
140  //sort the hits by the time
141  sortHitsByTime(hitVec_U);
142  sortHitsByTime(hitVec_V);
143  sortHitsByTime(hitVec_Y);
144 
145  MF_LOG_DEBUG("SpacePointAlg_TimeSort")
146  << "Sorted " << hitVec_U.size() << " u hits, " << hitVec_V.size() << " v hits, "
147  << hitVec_Y.size() << " y hits.";
148 
149  //now, do the loop to search for like-timed hits across the three planes
150  std::vector<art::Ptr<recob::Hit>>::iterator ihitu = hitVec_U.begin();
151  std::vector<art::Ptr<recob::Hit>>::iterator ihitv = hitVec_V.begin();
152  std::vector<art::Ptr<recob::Hit>>::iterator ihity = hitVec_Y.begin();
153  std::vector<art::Ptr<recob::Hit>>::iterator ihitv_inner, ihity_inner;
154  double time_hitu = (*ihitu)->PeakTime() + TIME_OFFSET_U;
155  double time_hitv = (*ihitv)->PeakTime() + TIME_OFFSET_V;
156  double time_hity = (*ihity)->PeakTime() + TIME_OFFSET_Y;
157  double time_hitv_inner, time_hity_inner;
158  while (ihitu != hitVec_U.end()) {
159  time_hitu = (*ihitu)->PeakTime() + TIME_OFFSET_U;
160 
161  mf::LogInfo("SpacePointAlg_TimeSort")
162  << "Hit times (u,v,y)=(" << time_hitu << "," << time_hitv << "," << time_hity << ")";
163 
164  //if time_hitu is too much bigger than time_hitv, need to advance hitv iterator
165  while ((time_hitu - time_hitv) > fTimeDiffMax) {
166  ihitv++;
167  if (ihitv == hitVec_V.end()) break;
168  time_hitv = (*ihitv)->PeakTime() + TIME_OFFSET_V;
169  }
170  if (ihitv == hitVec_V.end()) break;
171 
172  //same thing with time_hitu and time_hity
173  while ((time_hitu - time_hity) > fTimeDiffMax) {
174  ihity++;
175  if (ihity == hitVec_Y.end()) break;
176  time_hity = (*ihity)->PeakTime() + TIME_OFFSET_Y;
177  }
178  if (ihity == hitVec_Y.end()) break;
179 
180  //OK, now we know time_hitu <= time_hitv and time_hitu <= time_hity.
181  //Next, check if time_hitu is near time_hitv and time_hit y. If not,
182  //we have to increment ihitu.
183  if (std::abs(time_hitu - time_hitv) > fTimeDiffMax ||
184  std::abs(time_hitu - time_hity) > fTimeDiffMax) {
185  ihitu++;
186  continue;
187  }
188 
189  //OK! Note we KNOW that these three match in time:
190  // -- time_hitu is within fTimeDiffMax of both time_hitv and time_hity; and
191  // -- time_hitu <= time_hitv AND time_hitu <=time_hity, so time_hitv and time_hity are near too
192 
193  mf::LogInfo("SpacePointAlg_TimeSort") << "Matching hit times (u,v,y)=(" << time_hitu << ","
194  << time_hitv << "," << time_hity << ")";
195 
196  //Next thing to do, we need to loop over all possible 3-hit matches for our given u-hit.
197  //We need new iterators in v and y at this location, and will loop over those
198  ihitv_inner = ihitv;
199  time_hitv_inner = (*ihitv_inner)->PeakTime() + TIME_OFFSET_V;
200  ihity_inner = ihity;
201  time_hity_inner = (*ihity_inner)->PeakTime() + TIME_OFFSET_Y;
202 
203  while (std::abs(time_hitu - time_hitv_inner) < fTimeDiffMax &&
204  std::abs(time_hitu - time_hity_inner) < fTimeDiffMax) {
205 
206  unsigned int uwire = (*ihitu)->WireID().Wire;
207  unsigned int vwire = (*ihitv_inner)->WireID().Wire;
208  unsigned int ywire = (*ihity_inner)->WireID().Wire;
209 
210  mf::LogInfo("SpacePointAlg_TimeSort")
211  << "(y,z) coordinate for uv/uy: (" << coordinates_UV_y[vwire][uwire] << ","
212  << coordinates_UV_z[vwire][uwire] << ")/(" << coordinates_UY_y[ywire][uwire] << ","
213  << coordinates_UY_z[ywire][uwire] << ")";
214 
215  if (std::abs(coordinates_UV_y[vwire][uwire] - coordinates_UY_y[ywire][uwire]) < fYDiffMax &&
216  std::abs(coordinates_UV_z[vwire][uwire] - coordinates_UY_z[ywire][uwire]) < fZDiffMax) {
217 
218  double xyz[3];
219  double xyz_err[6];
220  //triangular error matrix:
221  // | 0. |
222  // | 0. 0. |
223  // | 0. 0. 0. |
224 
225  //get average y and z, with errors
226  xyz[1] = (coordinates_UV_y[vwire][uwire] + coordinates_UY_y[ywire][uwire]) * 0.5;
227  xyz_err[2] = std::abs(coordinates_UV_y[vwire][uwire] - xyz[1]);
228  xyz[2] = (coordinates_UV_z[vwire][uwire] + coordinates_UY_z[ywire][uwire]) * 0.5;
229  xyz_err[5] = std::abs(coordinates_UV_z[vwire][uwire] - xyz[2]);
230 
231  double t_val = (time_hitu + time_hitv_inner + time_hity_inner) / 3.;
232  double t_err = 0.5 * std::sqrt((time_hitu - t_val) * (time_hitu - t_val) +
233  (time_hitv_inner - t_val) * (time_hitv_inner - t_val) +
234  (time_hity_inner - t_val) * (time_hity_inner - t_val));
235  xyz[0] = TICKS_TO_X * t_val;
236  xyz_err[0] = TICKS_TO_X * t_err;
237 
238  //make space point to put on event
239  recob::SpacePoint spt(xyz, xyz_err, 0., spptCollection->size());
240  spptCollection->push_back(spt);
241 
242  //make association with hits
243  std::vector<art::Ptr<recob::Hit>> myhits = {*ihitu, *ihitv_inner, *ihity_inner};
244  spptAssociatedHits->push_back(myhits);
245  }
246 
247  //now increment the v or y hit, whichever is smalles (closest to u hit) in time
248  if (time_hitv_inner <= time_hity_inner) {
249  ihitv_inner++;
250  if (ihitv_inner == hitVec_V.end()) break;
251  time_hitv_inner = (*ihitv_inner)->PeakTime() + TIME_OFFSET_V;
252  }
253  else {
254  ihity_inner++;
255  if (ihity_inner == hitVec_Y.end()) break;
256  time_hity_inner = (*ihity_inner)->PeakTime() + TIME_OFFSET_Y;
257  }
258  }
259 
260  ihitu++;
261  } // end while looping over u hits
262 
263  MF_LOG_DEBUG("SpacePointAlg_TimeSort")
264  << "Finished with " << spptCollection->size() << " spacepoints.";
265 
266  } //end createSpacePoints
267 
268  //-------------------------------------------------
270  {
271  std::sort(hitVec.begin(), hitVec.end(), HitTimeComparison);
272  }
273 
274 } //end sppt namespace
void sortHitsByTime(std::vector< art::Ptr< recob::Hit >> &hits_handle) const
SpacePointAlg_TimeSort(fhicl::ParameterSet const &pset)
float fYDiffMax
Maximum allowed time difference.
void setTimeOffsets(detinfo::DetectorPropertiesData const &detProp)
double GetXTicksCoefficient(int t, int c) const
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Planes which measure V.
Definition: geo_types.h:136
double GetXTicksOffset(int p, int t, int c) const
Declaration of signal hit object.
The data type to uniquely identify a Plane.
Definition: geo_types.h:463
constexpr auto abs(T v)
Returns the absolute value of the argument.
boost::multi_array< double, 2 > coordinates_UV_y
Planes which measure Z direction.
Definition: geo_types.h:138
float fZDiffMax
Maximum allowed y-coordinate difference.
boost::multi_array< double, 2 > coordinates_UY_z
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
Planes which measure U.
Definition: geo_types.h:135
bool TIME_OFFSET_SET
Maximum allowed z-coordinate difference.
T get(std::string const &key) const
Definition: ParameterSet.h:314
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
Definition of data types for geometry description.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:220
boost::multi_array< double, 2 > coordinates_UY_y
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
#define MF_LOG_DEBUG(id)
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
void createSpacePoints(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> &hitVec_U, std::vector< art::Ptr< recob::Hit >> &hitVec_V, std::vector< art::Ptr< recob::Hit >> &hitVec_Y, std::unique_ptr< std::vector< recob::SpacePoint >> &spptCollection, std::unique_ptr< std::vector< std::vector< art::Ptr< recob::Hit >>>> &spptAssociatedHits)
bool IntersectionPoint(WireID const &wid1, WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
boost::multi_array< double, 2 > coordinates_UV_z