LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
SpacePointHit3DBuilder_tool.cc
Go to the documentation of this file.
1 
8 // Framework Includes
15 #include "art_root_io/TFileService.h"
19 #include "cetlib/cpu_timer.h"
20 #include "fhiclcpp/ParameterSet.h"
22 
23 // LArSoft includes
35 
36 // std includes
37 #include <cmath>
38 #include <iostream>
39 #include <map>
40 #include <memory>
41 #include <numeric> // std::accumulate
42 #include <unordered_map>
43 #include <utility>
44 #include <vector>
45 
46 // Ack!
47 #include "TTree.h"
48 
49 //------------------------------------------------------------------------------------------------------------------------------------------
50 // implementation follows
51 
52 namespace lar_cluster3d {
53 
57  class SpacePointHit3DBuilder : virtual public IHit3DBuilder {
58  public:
64  explicit SpacePointHit3DBuilder(fhicl::ParameterSet const& pset);
65 
70  void produces(art::ProducesCollector&) override;
71 
78  void Hit3DBuilder(art::Event& evt, reco::HitPairList& hitPairList, RecobHitToPtrMap&) override;
79 
83  float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
84  {
85  return fTimeVector.at(index);
86  }
87 
88  private:
92  void clear();
93 
97  float chargeIntegral(float, float, float, int, int) const;
98 
99  using Hit2DVector = std::vector<reco::ClusterHit2D>;
100 
110 
112  mutable std::vector<float> fTimeVector;
113 
114  // Define some basic histograms
115  TTree* m_tupleTree;
116 
117  mutable std::vector<float> m_deltaTimeVec;
118  mutable std::vector<float> m_chiSquare3DVec;
119  mutable std::vector<float> m_maxPullVec;
120  mutable std::vector<float> m_overlapFractionVec;
121  mutable std::vector<float> m_overlapRangeVec;
122  mutable std::vector<float> m_maxSideVecVec;
123  mutable std::vector<float> m_pairWireDistVec;
124  mutable std::vector<float> m_smallChargeDiffVec;
125  mutable std::vector<int> m_smallIndexVec;
126  mutable std::vector<float> m_qualityMetricVec;
127  mutable std::vector<float> m_spacePointChargeVec;
128  mutable std::vector<float> m_hitAsymmetryVec;
129 
130  // Get instances of the primary data structures needed
132 
135  };
136 
138  {
139  fSpacePointProducerLabel = pset.get<art::InputTag>("SpacePointProducerLabel");
140  fHitProducerLabel = pset.get<art::InputTag>("HitProducerLabel");
141  fDoWireAssns = pset.get<bool>("DoWireAssns", true);
142  fDoRawDigitAssns = pset.get<bool>("DoRawDigitAssns", true);
143  fEnableMonitoring = pset.get<bool>("EnableMonitoring", true);
144  m_maxHit3DChiSquare = pset.get<float>("MaxHitChiSquare", 6.0);
145  m_outputHistograms = pset.get<bool>("OutputHistograms", false);
146 
147  // Access ART's TFileService, which will handle creating and writing
148  // histograms and n-tuples for us.
150 
151  if (m_outputHistograms) {
152  m_tupleTree = tfs->make<TTree>("Hit3DBuilderTree", "Tree by StandardHit3DBuilder");
153 
154  clear();
155 
156  m_tupleTree->Branch("DeltaTime2D", "std::vector<float>", &m_deltaTimeVec);
157  m_tupleTree->Branch("ChiSquare3D", "std::vector<float>", &m_chiSquare3DVec);
158  m_tupleTree->Branch("MaxPullValue", "std::vector<float>", &m_maxPullVec);
159  m_tupleTree->Branch("OverlapFraction", "std::vector<float>", &m_overlapFractionVec);
160  m_tupleTree->Branch("OverlapRange", "std::vector<float>", &m_overlapRangeVec);
161  m_tupleTree->Branch("MaxSideVec", "std::vector<float>", &m_maxSideVecVec);
162  m_tupleTree->Branch("PairWireDistVec", "std::vector<float>", &m_pairWireDistVec);
163  m_tupleTree->Branch("SmallChargeDiff", "std::vector<float>", &m_smallChargeDiffVec);
164  m_tupleTree->Branch("SmallChargeIdx", "std::vector<int>", &m_smallIndexVec);
165  m_tupleTree->Branch("QualityMetric", "std::vector<float>", &m_qualityMetricVec);
166  m_tupleTree->Branch("SPCharge", "std::vector<float>", &m_spacePointChargeVec);
167  m_tupleTree->Branch("HitAsymmetry", "std::vector<float>", &m_hitAsymmetryVec);
168  }
169 
172  }
173 
174  //------------------------------------------------------------------------------------------------------------------------------------------
175 
177  {
178  collector.produces<std::vector<recob::Hit>>();
179 
182  }
183 
184  //------------------------------------------------------------------------------------------------------------------------------------------
185 
187  {
188  m_deltaTimeVec.clear();
189  m_chiSquare3DVec.clear();
190  m_maxPullVec.clear();
191  m_overlapFractionVec.clear();
192  m_overlapRangeVec.clear();
193  m_maxSideVecVec.clear();
194  m_pairWireDistVec.clear();
195  m_smallChargeDiffVec.clear();
196  m_smallIndexVec.clear();
197  m_qualityMetricVec.clear();
198  m_spacePointChargeVec.clear();
199  m_hitAsymmetryVec.clear();
200  }
201 
203  reco::HitPairList& hitPairList,
204  RecobHitToPtrMap& recobHitToArtPtrMap)
205  {
210  fTimeVector.resize(NUMTIMEVALUES, 0.);
211 
212  cet::cpu_timer theClockMakeHits;
213 
214  if (fEnableMonitoring) theClockMakeHits.start();
215 
216  // Start by recovering the associations between space points and hits
218  evt.getByLabel(fSpacePointProducerLabel, hitSpacePointAssnsHandle);
219 
220  if (!hitSpacePointAssnsHandle.isValid()) return;
221 
222  // Get a hit refiner for the output hit collection
224 
225  // We need to spin through the associations first to build a map between the SpacePoints and
226  // the WireID associated to the collection plane... where for APA style TPCs this will be
227  // unambiguous (note that this is not true for ICARUS!)
228  using SpacePointToWireIDMap = std::unordered_map<const recob::SpacePoint*, geo::WireID>;
229 
230  SpacePointToWireIDMap spacePointToWireIDMap;
231 
232  for (const auto& assnPair : *hitSpacePointAssnsHandle) {
233  if (assnPair.first->SignalType() == geo::kCollection)
234  spacePointToWireIDMap[assnPair.second.get()] = assnPair.first->WireID();
235  }
236 
237  // First step is to loop through and get a mapping between space points and associated hits
238  // and, importantly, a list of unique hits (and mapping between art ptr and hit)
239  using OldHitToNewHitMap = std::map<const recob::Hit*, const recob::Hit*>;
240  using SpacePointHitVecMap = std::map<const recob::SpacePoint*, std::vector<const recob::Hit*>>;
241 
242  OldHitToNewHitMap oldHitToNewHitMap;
243  SpacePointHitVecMap spacePointHitVecMap;
244 
245  // We need a container for our new hits...
246  std::unique_ptr<std::vector<recob::Hit>> newHitVecPtr(new std::vector<recob::Hit>);
247 
248  // reserve a chunk of memory... cannot be more hits than 3 x # spacer points...
249  newHitVecPtr->reserve(3 * hitSpacePointAssnsHandle->size());
250 
251  // Use this handy art utility to make art::Ptr objects to the new recob::Hits for use in the output phase
252  art::PtrMaker<recob::Hit> ptrMaker(evt);
253 
254  for (auto& assnPair : *hitSpacePointAssnsHandle) {
255  const art::Ptr<recob::SpacePoint> spacePoint = assnPair.second;
256  const art::Ptr<recob::Hit>& recobHit = assnPair.first;
257 
258  // If we have seen this hit before then no need to create new hit
259  if (oldHitToNewHitMap.find(recobHit.get()) == oldHitToNewHitMap.end()) {
260  // Recover the reference WireID from our previous map
261  geo::WireID refWireID = spacePointToWireIDMap[spacePoint.get()];
262  geo::WireID thisWireID = recobHit.get()->WireID();
263 
264  // Recover the list of possible WireIDs from the geometry service
265  const std::vector<geo::WireID>& wireIDs =
266  fWireReadoutGeom->ChannelToWire(recobHit.get()->Channel());
267 
268  // Loop to find match
269  for (const auto& wireID : wireIDs) {
270  if (wireID.TPC != refWireID.TPC || wireID.Cryostat != refWireID.Cryostat) continue;
271  thisWireID = wireID;
272  break;
273  }
274 
275  // Create and save the new recob::Hit with the correct WireID
276  newHitVecPtr->emplace_back(recob::HitCreator(*recobHit.get(), thisWireID).copy());
277 
278  // Recover a pointer to it...
279  recob::Hit* newHit = &newHitVecPtr->back();
280 
281  spacePointHitVecMap[spacePoint.get()].push_back(newHit);
282 
283  recobHitToArtPtrMap[newHit] = ptrMaker(newHitVecPtr->size() - 1);
284  oldHitToNewHitMap[recobHit.get()] = newHit;
285  }
286  else
287  spacePointHitVecMap[spacePoint.get()].push_back(oldHitToNewHitMap[recobHit.get()]);
288  }
289 
290  // We'll want to correct the hit times for the plane offsets
291  // (note this is already taken care of when converting to position)
292  std::map<geo::PlaneID, double> planeOffsetMap;
293 
294  auto const clock_data =
296  auto const det_prop =
298 
299  // Initialize the plane to hit vector map
300  for (size_t cryoIdx = 0; cryoIdx < fGeometry->Ncryostats(); cryoIdx++) {
301  for (size_t tpcIdx = 0; tpcIdx < fGeometry->NTPC(); tpcIdx++) {
302  // What we want here are the relative offsets between the planes
303  // Note that plane 0 is assumed the "first" plane and is the reference
304  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 0)] = 0.;
305  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 1)] =
306  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 1)) -
307  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0));
308  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 2)] =
309  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 2)) -
310  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0));
311 
312  std::cout << "***> plane 0 offset: " << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 0)]
313  << ", plane 1: " << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 1)]
314  << ", plane 2: " << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 2)] << std::endl;
315  std::cout << " Det prop plane 0: "
316  << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0))
317  << ", plane 1: " << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 1))
318  << ", plane 2: " << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 2))
319  << ", Trig: " << trigger_offset(clock_data) << std::endl;
320  }
321  }
322 
323  // We need temporary mapping from recob::Hit's to our 2D hits
324  using RecobHitTo2DHitMap = std::map<const recob::Hit*, const reco::ClusterHit2D*>;
325 
326  RecobHitTo2DHitMap recobHitTo2DHitMap;
327 
328  // Set the size of the container for our hits
329  m_clusterHit2DMasterVec.clear();
330  m_clusterHit2DMasterVec.reserve(oldHitToNewHitMap.size());
331 
332  // Now go throught the list of unique hits and create the 2D hits we'll use
333  for (auto& hitPair : oldHitToNewHitMap) {
334  const recob::Hit* recobHit = hitPair.second;
335  const geo::WireID& hitWireID(recobHit->WireID());
336 
337  double hitPeakTime(
338  recobHit->PeakTime() -
339  planeOffsetMap.at(hitWireID.planeID())); //planeOffsetMap[hitWireID.planeID()]);
340  double xPosition(det_prop.ConvertTicksToX(
341  recobHit->PeakTime(), hitWireID.Plane, hitWireID.TPC, hitWireID.Cryostat));
342 
343  m_clusterHit2DMasterVec.emplace_back(0, 0., 0., xPosition, hitPeakTime, hitWireID, recobHit);
344 
345  recobHitTo2DHitMap[recobHit] = &m_clusterHit2DMasterVec.back();
346  }
347 
348  // Now we can go through the space points and build our 3D hits
349  for (auto& pointPair : spacePointHitVecMap) {
350  const recob::SpacePoint* spacePoint = pointPair.first;
351  const std::vector<const recob::Hit*>& recobHitVec = pointPair.second;
352 
353  if (recobHitVec.size() != 3) {
354  std::cout << "************>>>>>> do not have 3 hits associated to space point! "
355  << recobHitVec.size() << " ***************" << std::endl;
356  continue;
357  }
358 
359  reco::ClusterHit2DVec hitVector(recobHitVec.size());
360 
361  for (const auto& recobHit : recobHitVec) {
362  const reco::ClusterHit2D* hit2D = recobHitTo2DHitMap.at(recobHit);
363 
364  hitVector[hit2D->WireID().Plane] = hit2D;
365  }
366 
367  // Set up to get average peak time, hitChiSquare, etc.
368  unsigned int statusBits(0x7);
369  float avePeakTime(0.);
370  float weightSum(0.);
371 
372  // And get the wire IDs
373  std::vector<geo::WireID> wireIDVec = {geo::WireID(), geo::WireID(), geo::WireID()};
374 
375  // First loop through the hits to get WireIDs and calculate the averages
376  for (size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
377  const reco::ClusterHit2D* hit2D = hitVector[planeIdx];
378 
379  wireIDVec[planeIdx] = hit2D->WireID();
380 
383 
385 
386  float hitRMS = hit2D->getHit()->RMS();
387  float weight = 1. / (hitRMS * hitRMS);
388  float peakTime = hit2D->getTimeTicks();
389 
390  avePeakTime += peakTime * weight;
391  weightSum += weight;
392  }
393 
394  avePeakTime /= weightSum;
395 
396  // Armed with the average peak time, now get hitChiSquare and the sig vec
397  float hitChiSquare(0.);
398  float sigmaPeakTime(std::sqrt(1. / weightSum));
399  std::vector<float> hitDelTSigVec;
400 
401  for (const auto& hit2D : hitVector) {
402  float hitRMS = hit2D->getHit()->RMS();
403  float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
404  float peakTime = hit2D->getTimeTicks();
405  float deltaTime = peakTime - avePeakTime;
406  float hitSig = deltaTime / combRMS;
407 
408  hitChiSquare += hitSig * hitSig;
409 
410  hitDelTSigVec.emplace_back(std::fabs(hitSig));
411  }
412 
413  if (m_outputHistograms) m_chiSquare3DVec.push_back(hitChiSquare);
414 
415  // Need to determine the hit overlap ranges
416  int lowMinIndex(std::numeric_limits<int>::max());
417  int lowMaxIndex(std::numeric_limits<int>::min());
418  int hiMinIndex(std::numeric_limits<int>::max());
419  int hiMaxIndex(std::numeric_limits<int>::min());
420 
421  // This loop through hits to find min/max values for the common overlap region
422  for (const auto& hit2D : hitVector) {
423  int hitStart = hit2D->getHit()->PeakTime() - 2. * hit2D->getHit()->RMS() - 0.5;
424  int hitStop = hit2D->getHit()->PeakTime() + 2. * hit2D->getHit()->RMS() + 0.5;
425 
426  lowMinIndex = std::min(hitStart, lowMinIndex);
427  lowMaxIndex = std::max(hitStart, lowMaxIndex);
428  hiMinIndex = std::min(hitStop + 1, hiMinIndex);
429  hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
430  }
431 
432  // Keep only "good" hits...
433  if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
434  // One more pass through hits to get charge
435  std::vector<float> chargeVec;
436 
437  for (const auto& hit2D : hitVector)
438  chargeVec.push_back(chargeIntegral(hit2D->getHit()->PeakTime(),
439  hit2D->getHit()->PeakAmplitude(),
440  hit2D->getHit()->RMS(),
441  lowMaxIndex,
442  hiMinIndex));
443 
444  float totalCharge =
445  std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
446  float overlapRange = float(hiMinIndex - lowMaxIndex);
447  float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
448 
449  // Set up to compute the charge asymmetry
450  std::vector<float> smallestChargeDiffVec;
451  std::vector<float> chargeAveVec;
452  float smallestDiff(std::numeric_limits<float>::max());
453  size_t chargeIndex(0);
454 
455  for (size_t idx = 0; idx < 3; idx++) {
456  size_t leftIdx = (idx + 2) % 3;
457  size_t rightIdx = (idx + 1) % 3;
458 
459  smallestChargeDiffVec.push_back(std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
460  chargeAveVec.push_back(float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
461 
462  if (smallestChargeDiffVec.back() < smallestDiff) {
463  smallestDiff = smallestChargeDiffVec.back();
464  chargeIndex = idx;
465  }
466 
467  // Take opportunity to look at peak time diff
468  if (m_outputHistograms) {
469  float deltaPeakTime =
470  hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
471 
472  m_deltaTimeVec.push_back(deltaPeakTime);
473  }
474  }
475 
476  float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
477  (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
478 
479  // If this is true there has to be a negative charge that snuck in somehow
480  if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
481  const geo::WireID& hitWireID = hitVector[chargeIndex]->WireID();
482 
483  std::cout << "============> Charge asymmetry out of range: " << chargeAsymmetry
484  << " <============" << std::endl;
485  std::cout << " hit C: " << hitWireID.Cryostat << ", TPC: " << hitWireID.TPC
486  << ", Plane: " << hitWireID.Plane << ", Wire: " << hitWireID.Wire << std::endl;
487  std::cout << " charge: " << chargeVec[0] << ", " << chargeVec[1] << ", "
488  << chargeVec[2] << std::endl;
489  std::cout << " index: " << chargeIndex << ", smallest diff: " << smallestDiff
490  << std::endl;
491  continue;
492  }
493 
494  // Usurping "deltaPeakTime" to be the maximum pull
495  float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
496 
497  if (m_outputHistograms) {
498  m_smallChargeDiffVec.push_back(smallestDiff);
499  m_smallIndexVec.push_back(chargeIndex);
500  m_maxPullVec.push_back(deltaPeakTime);
501  m_qualityMetricVec.push_back(hitChiSquare);
502  m_spacePointChargeVec.push_back(totalCharge);
503  m_overlapFractionVec.push_back(overlapFraction);
504  m_overlapRangeVec.push_back(overlapRange);
505  m_hitAsymmetryVec.push_back(chargeAsymmetry);
506  }
507 
508  Eigen::Vector3f position(
509  float(spacePoint->XYZ()[0]), float(spacePoint->XYZ()[1]), float(spacePoint->XYZ()[2]));
510 
511  // Create the 3D cluster hit
512  hitPairList.emplace_back(0,
513  statusBits,
514  position,
515  totalCharge,
516  avePeakTime,
517  deltaPeakTime,
518  sigmaPeakTime,
519  hitChiSquare,
520  overlapFraction,
521  chargeAsymmetry,
522  0.,
523  0.,
524  hitVector,
525  hitDelTSigVec,
526  wireIDVec);
527  }
528  }
529 
530  // Now we give the new hits to the refinery
531  // Note that one advantage of using this utility is that it handles the
532  // Hit/Wire and Hit/RawDigit associations all behind the scenes for us
533  hitRefiner.use_hits(std::move(newHitVecPtr));
534 
535  // Output the new hit collection to the event
536  hitRefiner.put_into();
537 
538  // Handle tree output too
539  m_tupleTree->Fill();
540 
541  clear();
542 
543  if (fEnableMonitoring) {
544  theClockMakeHits.stop();
545 
546  fTimeVector[BUILDTHREEDHITS] = theClockMakeHits.accumulated_real_time();
547  }
548 
549  mf::LogDebug("Cluster3D") << ">>>>> 3D hit building done, found " << hitPairList.size()
550  << " 3D Hits" << std::endl;
551  }
552 
554  float peakAmp,
555  float peakSigma,
556  int low,
557  int hi) const
558  {
559  float integral(0);
560 
561  for (int sigPos = low; sigPos < hi; sigPos++) {
562  float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
563  integral += peakAmp * std::exp(-0.5 * arg * arg);
564  }
565 
566  return integral;
567  }
568 
569  //------------------------------------------------------------------------------------------------------------------------------------------
570  //------------------------------------------------------------------------------------------------------------------------------------------
571 
573 } // namespace lar_cluster3d
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
std::list< reco::ClusterHit3D > HitPairList
Definition: Cluster3D.h:330
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
art::InputTag fSpacePointProducerLabel
Data members to follow.
float getTimeTicks() const
Definition: Cluster3D.h:75
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:234
unsigned int NTPC(CryostatID const &cryoid=details::cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
Definition: GeometryCore.h:416
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
Declaration of signal hit object.
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
float chargeIntegral(float, float, float, int, int) const
Perform charge integration between limits.
const geo::WireID & WireID() const
Definition: Cluster3D.h:76
std::vector< reco::ClusterHit2D > Hit2DVector
constexpr auto abs(T v)
Returns the absolute value of the argument.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:303
void Hit3DBuilder(art::Event &evt, reco::HitPairList &hitPairList, RecobHitToPtrMap &) override
Given a set of recob hits, run DBscan to form 3D clusters.
const recob::Hit * getHit() const
Definition: Cluster3D.h:77
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
bool isValid() const noexcept
Definition: Handle.h:203
void clear()
clear the tuple vectors before processing next event
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:87
Helper functions to create a hit.
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
Definition: HitCreator.cxx:521
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
void put_into(art::Event &)
Moves the data into the event.
Definition: HitCreator.h:858
Interface for a class providing readout channel mapping to geometry.
T get(std::string const &key) const
Definition: ParameterSet.h:314
A class handling a collection of hits and its associations.
Definition: HitCreator.h:795
SpacePointHit3DBuilder class definiton.
const Double32_t * XYZ() const
Definition: SpacePoint.h:78
TimeValues
enumerate the possible values for time checking if monitoring timing
Definition: IHit3DBuilder.h:56
The geometry of one entire detector, as served by art.
Definition: Geometry.h:42
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
Definition of data types for geometry description.
IHit3DBuilder interface class definiton.
Definition: IHit3DBuilder.h:27
This provides an art tool interface definition for tools which construct 3D hits used in 3D clusterin...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:90
void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
double weight
Definition: plottest35.C:25
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:226
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
virtual std::vector< WireID > ChannelToWire(raw::ChannelID_t channel) const =0
SpacePointHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
int trigger_offset(DetectorClocksData const &data)
constexpr WireID()=default
Default constructor: an invalid TPC ID.
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
TCEvent evt
Definition: DataStructs.cxx:8
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
T const * get() const
Definition: Ptr.h:138
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:278
std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
Definition: IHit3DBuilder.h:43
art framework interface to geometry description
Signal from collection planes.
Definition: geo_types.h:148
unsigned getStatusBits() const
Definition: Cluster3D.h:71
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:79