LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
HitCreator.cxx
Go to the documentation of this file.
1 
10 // declaration header
12 
13 // C/C++ standard library
14 #include <utility> // std::move()
15 #include <algorithm> // std::accumulate(), std::max()
16 #include <limits> // std::numeric_limits<>
17 #include <cassert>
18 
19 // art libraries
24 
25 // LArSoft libraries
27 // #include "RawData/RawDigit.h"
31 
32 
33 namespace {
34 
36  template <typename Left, typename Right, typename Metadata>
37  void ClearAssociations(art::Assns<Left, Right, Metadata>& assns) {
39  assns.swap(empty);
40  } // ClearAssociations()
41 
42 } // local namespace
43 
44 
46 namespace recob {
47 
48  //****************************************************************************
49  //*** HitCreator
50  //----------------------------------------------------------------------
52  raw::RawDigit const& digits,
53  geo::WireID const& wireID,
54  raw::TDCtick_t start_tick,
55  raw::TDCtick_t end_tick,
56  float rms,
57  float peak_time,
58  float sigma_peak_time,
59  float peak_amplitude,
60  float sigma_peak_amplitude,
61  float hit_integral,
62  float hit_sigma_integral,
63  float summedADC,
64  short int multiplicity,
65  short int local_index,
66  float goodness_of_fit,
67  int dof
68  ):
69  hit(
70  digits.Channel(),
71  start_tick,
72  end_tick,
73  peak_time,
74  sigma_peak_time,
75  rms,
76  peak_amplitude,
77  sigma_peak_amplitude,
78  summedADC,
79  hit_integral,
80  hit_sigma_integral,
81  multiplicity,
82  local_index,
83  goodness_of_fit,
84  dof,
85  art::ServiceHandle<geo::Geometry>()->View(digits.Channel()),
86  art::ServiceHandle<geo::Geometry>()->SignalType(digits.Channel()),
87  wireID
88  )
89  {} // HitCreator::HitCreator(RawDigit)
90 
91 
92  //----------------------------------------------------------------------
94  recob::Wire const& wire,
95  geo::WireID const& wireID,
96  raw::TDCtick_t start_tick,
97  raw::TDCtick_t end_tick,
98  float rms,
99  float peak_time,
100  float sigma_peak_time,
101  float peak_amplitude,
102  float sigma_peak_amplitude,
103  float hit_integral,
104  float hit_sigma_integral,
105  float summedADC,
106  short int multiplicity,
107  short int local_index,
108  float goodness_of_fit,
109  int dof
110  ):
111  hit(
112  wire.Channel(),
113  start_tick,
114  end_tick,
115  peak_time,
116  sigma_peak_time,
117  rms,
118  peak_amplitude,
119  sigma_peak_amplitude,
120  summedADC,
121  hit_integral,
122  hit_sigma_integral,
123  multiplicity,
124  local_index,
125  goodness_of_fit,
126  dof,
127  wire.View(),
128  art::ServiceHandle<geo::Geometry>()->SignalType(wire.Channel()),
129  wireID
130  )
131  {} // HitCreator::HitCreator(Wire)
132 
133 
134  //----------------------------------------------------------------------
136  recob::Wire const& wire,
137  geo::WireID const& wireID,
138  raw::TDCtick_t start_tick,
139  raw::TDCtick_t end_tick,
140  float rms,
141  float peak_time,
142  float sigma_peak_time,
143  float peak_amplitude,
144  float sigma_peak_amplitude,
145  float hit_integral,
146  float hit_sigma_integral,
147  short int multiplicity,
148  short int local_index,
149  float goodness_of_fit,
150  int dof
151  ):
152  HitCreator(
153  wire, wireID, start_tick, end_tick,
154  rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
155  hit_integral, hit_sigma_integral,
156  std::accumulate(
157  wire.SignalROI().begin() + start_tick,
158  wire.SignalROI().begin() + end_tick,
159  0.
160  ), // sum of ADC counts between start_tick and end_tick
161  multiplicity, local_index,
162  goodness_of_fit, dof
163  )
164  {} // HitCreator::HitCreator(Wire; no summed ADC)
165 
166 
167  //----------------------------------------------------------------------
169  recob::Wire const& wire,
170  geo::WireID const& wireID,
171  float rms,
172  float peak_time,
173  float sigma_peak_time,
174  float peak_amplitude,
175  float sigma_peak_amplitude,
176  float hit_integral,
177  float hit_sigma_integral,
178  float summedADC,
179  short int multiplicity,
180  short int local_index,
181  float goodness_of_fit,
182  int dof,
183  RegionOfInterest_t const& signal
184  ):
185  HitCreator(
186  wire, wireID, signal.begin_index(), signal.end_index(),
187  rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
188  hit_integral, hit_sigma_integral, summedADC, multiplicity, local_index,
189  goodness_of_fit, dof
190  )
191  {} // HitCreator::HitCreator(Wire; RoI)
192 
193 
194  //----------------------------------------------------------------------
196  recob::Wire const& wire,
197  geo::WireID const& wireID,
198  float rms,
199  float peak_time,
200  float sigma_peak_time,
201  float peak_amplitude,
202  float sigma_peak_amplitude,
203  float hit_integral,
204  float hit_sigma_integral,
205  float summedADC,
206  short int multiplicity,
207  short int local_index,
208  float goodness_of_fit,
209  int dof,
210  size_t iSignalRoI
211  ):
212  HitCreator(
213  wire, wireID, rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
214  hit_integral, hit_sigma_integral, summedADC, multiplicity, local_index,
215  goodness_of_fit, dof, wire.SignalROI().range(iSignalRoI)
216  )
217  {} // HitCreator::HitCreator(Wire; RoI index)
218 
219 
220  HitCreator::HitCreator(recob::Hit const& from): hit(from) {}
221 
222 
223  HitCreator::HitCreator(recob::Hit const& from, geo::WireID const& wireID):
224  hit(from)
225  {
226  hit.fWireID = wireID;
227  } // HitCreator::HitCreator(new wire ID)
228 
229 
230 
231  //****************************************************************************
232  //*** HitAndAssociationsWriterBase
233  //----------------------------------------------------------------------
235  assert(event);
236  if (hits) event->put(std::move(hits), prod_instance);
237  if (WireAssns) event->put(std::move(WireAssns), prod_instance);
238  if (RawDigitAssns) event->put(std::move(RawDigitAssns), prod_instance);
239  } // HitAndAssociationsWriterBase::put_into()
240 
241 
242  //****************************************************************************
243  //*** HitCollectionCreator
244  //----------------------------------------------------------------------
246  recob::Hit&& hit,
247  art::Ptr<recob::Wire> const& wire, art::Ptr<raw::RawDigit> const& digits
248  ) {
249 
250  // add the hit to the collection
251  hits->emplace_back(std::move(hit));
252 
253  CreateAssociationsToLastHit(wire, digits);
254  } // HitCollectionCreator::emplace_back(Hit&&)
255 
256 
257  //----------------------------------------------------------------------
259  recob::Hit const& hit,
260  art::Ptr<recob::Wire> const& wire, art::Ptr<raw::RawDigit> const& digits
261  ) {
262 
263  // add the hit to the collection
264  hits->push_back(hit);
265 
266  CreateAssociationsToLastHit(wire, digits);
267  } // HitCollectionCreator::emplace_back(Hit)
268 
269 
270  //----------------------------------------------------------------------
272  if (!hits) {
274  << "HitCollectionCreator is trying to put into the event"
275  " a hit collection that was never created!\n";
276  }
278  } // HitCollectionCreator::put_into()
279 
280 
281  //----------------------------------------------------------------------
283  art::Ptr<recob::Wire> const& wire, art::Ptr<raw::RawDigit> const& digits
284  ) {
285  // if no association is required, we are done
286  if (!WireAssns && !RawDigitAssns) return;
287 
288  // art pointer to the hit we just created
289  HitPtr_t hit_ptr(CreatePtrToLastHit());
290 
291  // association with wires
292  if (WireAssns && wire.isNonnull())
293  WireAssns->addSingle(wire, hit_ptr); // if it fails, it throws
294 
295  // association with wires
296  if (RawDigitAssns && digits.isNonnull())
297  RawDigitAssns->addSingle(digits, hit_ptr); // if it fails, it throws
298 
299  } // HitCollectionCreator::CreateAssociationsToLastHit()
300 
301 
302  //****************************************************************************
303  //*** HitCollectionAssociator
304  //----------------------------------------------------------------------
306  (std::unique_ptr<std::vector<recob::Hit>>&& srchits)
307  {
308  hits = std::move(srchits);
309  } // HitCollectionAssociator::use_hits()
310 
311 
312  //----------------------------------------------------------------------
314  prepare_associations();
316  } // HitCollectionAssociator::put_into()
317 
318 
319  //----------------------------------------------------------------------
321  (std::vector<recob::Hit> const& srchits)
322  {
323  if (!RawDigitAssns && !WireAssns) return; // no associations needed
324  assert(event);
325 
326  // we make the associations anew
327  if (RawDigitAssns) ClearAssociations(*RawDigitAssns);
328  if (WireAssns) ClearAssociations(*WireAssns);
329 
330  // the following is true is we want associations with digits
331  // but we don't know where digits are; in that case, we try to use wires
332  const bool bUseWiresForDigits = RawDigitAssns && (digits_label == "");
333 
334  if (WireAssns || bUseWiresForDigits) {
335  // do we use wires for digit associations too?
336 
337  // get the wire collection
339  = event->getValidHandle<std::vector<recob::Wire>>(wires_label);
340 
341  // fill a map of wire index vs. channel number
342  std::vector<size_t> WireMap
343  = util::MakeIndex(*hWires, std::mem_fn(&recob::Wire::Channel));
344 
345  // use raw rigit - wire association, assuming they have been produced
346  // by the same producer as the wire and with the same instance name;
347  // we don't check whether the data product is found, but the following
348  // code will have FindOneP throw if that was not the case
349  // (that's what we would do here anyway, maybe with a better message...)
350  std::unique_ptr<art::FindOneP<raw::RawDigit>> WireToDigit;
351  if (bUseWiresForDigits) {
352  WireToDigit.reset
353  (new art::FindOneP<raw::RawDigit>(hWires, *event, wires_label));
354  }
355 
356  // add associations, hit by hit:
357  for (size_t iHit = 0; iHit < srchits.size(); ++iHit) {
358 
359  // find the channel
360  size_t iChannel = size_t(srchits[iHit].Channel()); // forcibly converted
361 
362  // find the wire associated to that channel
363  size_t iWire = std::numeric_limits<size_t>::max();
364  if (iChannel < WireMap.size()) iWire = WireMap[iChannel];
365  if (iWire == std::numeric_limits<size_t>::max()) {
367  << "No wire associated to channel #" << iChannel << " whence hit #"
368  << iHit << " comes!\n";
369  } // if no channel
370 
371  // make the association with wires
372  if (WireAssns) {
373  art::Ptr<recob::Wire> wire(hWires, iWire);
374  WireAssns->addSingle(wire, CreatePtr(iHit));
375  }
376 
377  if (bUseWiresForDigits) {
378  // find the digit associated to that channel
379  art::Ptr<raw::RawDigit> const& digit = WireToDigit->at(iWire);
380  if (digit.isNull()) {
382  << "No raw digit associated to channel #" << iChannel
383  << " whence hit #" << iHit << " comes!\n";
384  } // if no channel
385 
386  // make the association
387  RawDigitAssns->addSingle(digit, CreatePtr(iHit));
388  } // if create digit associations through wires
389  } // for hit
390 
391  } // if wire associations
392 
393  if (RawDigitAssns && !bUseWiresForDigits) {
394  // get the digit collection
396  = event->getValidHandle<std::vector<raw::RawDigit>>(digits_label);
397 
398  // fill a map of wire index vs. channel number
399  std::vector<size_t> DigitMap
400  = util::MakeIndex(*hDigits, std::mem_fn(&raw::RawDigit::Channel));
401 
402  // add associations, hit by hit:
403  for (size_t iHit = 0; iHit < srchits.size(); ++iHit) {
404 
405  // find the channel
406  size_t iChannel = size_t(srchits[iHit].Channel()); // forcibly converted
407 
408  // find the digit associated to that channel
409  size_t iDigit = std::numeric_limits<size_t>::max();
410  if (iChannel < DigitMap.size()) iDigit = DigitMap[iChannel];
411  if (iDigit == std::numeric_limits<size_t>::max()) {
413  << "No raw digit associated to channel #" << iChannel
414  << " whence hit #" << iHit << " comes!\n";
415  } // if no channel
416 
417  // make the association
418  art::Ptr<raw::RawDigit> digit(hDigits, iDigit);
419  RawDigitAssns->addSingle(digit, CreatePtr(iHit));
420 
421  } // for hit
422  } // if we have rawdigit label
423 
424  } // HitCollectionAssociator::put_into()
425 
426 
427  //****************************************************************************
428  //*** HitRefinerAssociator
429  //----------------------------------------------------------------------
431  (std::unique_ptr<std::vector<recob::Hit>>&& srchits)
432  {
433  hits = std::move(srchits);
434  } // HitRefinerAssociator::use_hits()
435 
436 
437  //----------------------------------------------------------------------
439  prepare_associations();
441  } // HitRefinerAssociator::put_into()
442 
443 
444  //----------------------------------------------------------------------
446  (std::vector<recob::Hit> const& srchits)
447  {
448  if (!RawDigitAssns && !WireAssns) return; // no associations needed
449  assert(event);
450 
451  // we make the associations anew
452  if (RawDigitAssns) ClearAssociations(*RawDigitAssns);
453 
454  // read the hits; this is going to hurt performances...
455  // no solution to that until there is a way to have a lazy read
457  = event->getValidHandle<std::vector<recob::Hit>>(hits_label);
458 
459  // now get the associations
460  if (WireAssns) {
461  // we make the associations anew
462  ClearAssociations(*WireAssns);
463 
464  // find the associations between the hits and the wires
465  art::FindOneP<recob::Wire> HitToWire(hHits, *event, hits_label);
466  if (!HitToWire.isValid()) {
468  << "Can't find the associations between hits and wires produced by '"
469  << hits_label << "'!\n";
470  } // if no association
471 
472  // fill a map of wire vs. channel number
473  std::vector<art::Ptr<recob::Wire>> WireMap;
474  for (size_t iAssn = 0; iAssn < HitToWire.size(); ++iAssn) {
475  art::Ptr<recob::Wire> wire = HitToWire.at(iAssn);
476  if (wire.isNull()) continue;
477  size_t channelID = (size_t) wire->Channel();
478  if (WireMap.size() <= channelID) // expand the map of necessary
479  WireMap.resize(std::max(channelID + 1, 2 * WireMap.size()), {});
480  WireMap[channelID] = std::move(wire);
481  } // for
482 
483  // now go through all the hits...
484  for (size_t iHit = 0; iHit < srchits.size(); ++iHit) {
485  recob::Hit const& hit = srchits[iHit];
486  size_t channelID = (size_t) hit.Channel();
487 
488  // no association if there is no wire to associate with
489  if ((channelID >= WireMap.size()) || !WireMap[channelID]) continue;
490 
491  // create an association using the same wire pointer
492  WireAssns->addSingle(WireMap[channelID], CreatePtr(iHit));
493  } // for hits
494  } // if wire associations
495 
496  // now get the associations
497  if (RawDigitAssns) {
498  // we make the associations anew
499  ClearAssociations(*RawDigitAssns);
500 
501  // find the associations between the hits and the raw digits
502  art::FindOneP<raw::RawDigit> HitToDigits(hHits, *event, hits_label);
503  if (!HitToDigits.isValid()) {
505  << "Can't find the associations between hits and raw digits"
506  << " produced by '" << hits_label << "'!\n";
507  } // if no association
508 
509  // fill a map of digits vs. channel number
510  std::vector<art::Ptr<raw::RawDigit>> DigitMap;
511  for (size_t iAssn = 0; iAssn < HitToDigits.size(); ++iAssn) {
512  art::Ptr<raw::RawDigit> digits = HitToDigits.at(iAssn);
513  if (digits.isNull()) continue;
514  size_t channelID = (size_t) digits->Channel();
515  if (DigitMap.size() <= channelID) // expand the map of necessary
516  DigitMap.resize(std::max(channelID + 1, 2 * DigitMap.size()), {});
517  DigitMap[channelID] = std::move(digits);
518  } // for
519 
520  // now go through all the hits...
521  for (size_t iHit = 0; iHit < srchits.size(); ++iHit) {
522  recob::Hit const& hit = srchits[iHit];
523  size_t channelID = (size_t) hit.Channel();
524 
525  // no association if there is no digits to associate with
526  if ((channelID >= DigitMap.size()) || !DigitMap[channelID]) continue;
527 
528  // create an association using the same digits pointer
529  RawDigitAssns->addSingle(DigitMap[channelID], CreatePtr(iHit));
530  } // for hits
531  } // if digit associations
532 
533  } // HitRefinerAssociator::put_into()
534 
535 
536  //----------------------------------------------------------------------
537 } // namespace recob
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:68
Reconstruction base classes.
bool isNonnull() const
Definition: Ptr.h:335
void prepare_associations()
Finds out the associations for the current hits.
Definition: HitCreator.h:846
Declaration of signal hit object.
Procedures to create maps of object locations.
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:211
STL namespace.
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
Definition: HitCreator.cxx:306
std::vector< size_t > MakeIndex(Coll const &data, KeyOf key_of=KeyOf())
Creates a map of indices from an existing collection.
Definition: MakeIndex.h:43
void swap(art::Assns< L, R, D > &other)
Definition: Assns.h:499
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:24
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:84
Helper functions to create a hit.
Int_t max
Definition: plot.C:27
void hits()
Definition: readHits.C:15
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
Definition: HitCreator.cxx:431
void prepare_associations()
Finds out the associations for the current hits.
Definition: HitCreator.h:958
void put_into()
Moves the data into the event.
Definition: HitCreator.cxx:438
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:164
void put_into()
Moves the data into the event.
Definition: HitCreator.cxx:313
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
details::FindAllP< recob::Hit, recob::Wire > HitToWire
Query object connecting a hit to a wire.
Definition: HitUtils.h:56
void CreateAssociationsToLastHit(art::Ptr< recob::Wire > const &wire, art::Ptr< raw::RawDigit > const &digits)
Creates associations between the last hit and the specified pointers.
Definition: HitCreator.cxx:282
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
Definition: HitCreator.cxx:245
Detector simulation of raw signals on wires.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
void put_into()
Moves the data into the event.
Definition: HitCreator.cxx:234
Class holding the deconvoluted signals from a channel.
Definition: Wire.h:80
HitCreator(raw::RawDigit const &digits, geo::WireID const &wireID, raw::TDCtick_t start_tick, raw::TDCtick_t end_tick, float rms, float peak_time, float sigma_peak_time, float peak_amplitude, float sigma_peak_amplitude, float hit_integral, float hit_sigma_integral, float summedADC, short int multiplicity, short int local_index, float goodness_of_fit, int dof)
Constructor: extracts some information from raw digit.
Definition: HitCreator.cxx:51
HLT enums.
Declaration of basic channel signal object.
void put_into()
Moves the data into the event.
Definition: HitCreator.cxx:271
bool isNull() const
Definition: Ptr.h:328
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
recob::Wire::RegionsOfInterest_t::datarange_t RegionOfInterest_t
Type of one region of interest.
Definition: HitCreator.h:87
Namespace collecting geometry-related classes utilities.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:231
Definition: fwd.h:25
art framework interface to geometry description
Event finding and building.