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