LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
lar_cluster3d::StandardHit3DBuilder Class Reference

StandardHit3DBuilder class definiton. More...

Inheritance diagram for lar_cluster3d::StandardHit3DBuilder:
lar_cluster3d::IHit3DBuilder

Public Types

enum  TimeValues { COLLECTARTHITS = 0, BUILDTHREEDHITS = 1, BUILDNEWHITS = 2, NUMTIMEVALUES }
 enumerate the possible values for time checking if monitoring timing More...
 
using RecobHitToPtrMap = std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >>
 Defines a structure mapping art representation to internal. More...
 

Public Member Functions

 StandardHit3DBuilder (fhicl::ParameterSet const &pset)
 Constructor. More...
 
void produces (art::ProducesCollector &) override
 Each algorithm may have different objects it wants "produced" so use this to let the top level producer module "know" what it is outputting. More...
 
void Hit3DBuilder (art::Event &, reco::HitPairList &, RecobHitToPtrMap &) override
 Given a set of recob hits, run DBscan to form 3D clusters. More...
 
float getTimeToExecute (IHit3DBuilder::TimeValues index) const override
 If monitoring, recover the time to execute a particular function. More...
 

Private Types

using PlaneHitVectorItrPairVec = std::vector< std::pair< HitVector::iterator, HitVector::iterator >>
 Given the ClusterHit2D objects, build the HitPairMap. More...
 
using HitMatchPair = std::pair< const reco::ClusterHit2D *, reco::ClusterHit3D >
 This builds a list of candidate hit pairs from lists of hits on two planes. More...
 
using HitMatchPairVec = std::vector< HitMatchPair >
 
using HitMatchPairVecMap = std::map< geo::WireID, HitMatchPairVec >
 
using ChannelStatusVec = std::vector< size_t >
 define data structure for keeping track of channel status More...
 
using ChannelStatusByPlaneVec = std::vector< ChannelStatusVec >
 

Private Member Functions

void CollectArtHits (const art::Event &evt) const
 Extract the ART hits and the ART hit-particle relationships. More...
 
void BuildHit3D (reco::HitPairList &hitPairList) const
 Given the ClusterHit2D objects, build the HitPairMap. More...
 
void CreateNewRecobHitCollection (art::Event &, reco::HitPairList &, std::vector< recob::Hit > &, RecobHitToPtrMap &)
 Create a new 2D hit collection from hits associated to 3D space points. More...
 
void makeWireAssns (const art::Event &, art::Assns< recob::Wire, recob::Hit > &, RecobHitToPtrMap &) const
 Create recob::Wire to recob::Hit associations. More...
 
void makeRawDigitAssns (const art::Event &, art::Assns< raw::RawDigit, recob::Hit > &, RecobHitToPtrMap &) const
 Create raw::RawDigit to recob::Hit associations. More...
 
size_t BuildHitPairMap (PlaneToHitVectorMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
 Given the ClusterHit2D objects, build the HitPairMap. More...
 
size_t BuildHitPairMapByTPC (PlaneHitVectorItrPairVec &planeHitVectorItrPairVec, reco::HitPairList &hitPairList) const
 
int findGoodHitPairs (const reco::ClusterHit2D *, HitVector::iterator &, HitVector::iterator &, HitMatchPairVecMap &) const
 
void findGoodTriplets (HitMatchPairVecMap &, HitMatchPairVecMap &, reco::HitPairList &) const
 This algorithm takes lists of hit pairs and finds good triplets. More...
 
bool makeHitPair (reco::ClusterHit3D &pairOut, const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, float hitWidthSclFctr=1., size_t hitPairCntr=0) const
 Make a HitPair object by checking two hits. More...
 
bool makeHitTriplet (reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pairIn, const reco::ClusterHit2D *hit2) const
 Make a 3D HitPair object by checking two hits. More...
 
bool makeDeadChannelPair (reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pair, size_t maxStatus, size_t minStatus) const
 Make a 3D HitPair object from a valid pair and a dead channel in the missing plane. More...
 
const reco::ClusterHit2DFindBestMatchingHit (const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, float pairDeltaTimeLimits) const
 A utility routine for finding a 2D hit closest in time to the given pair. More...
 
int FindNumberInRange (const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, float range) const
 A utility routine for returning the number of 2D hits from the list in a given range. More...
 
geo::WireID NearestWireID (const Eigen::Vector3f &position, const geo::WireID &wireID) const
 Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range. More...
 
float DistanceFromPointToHitWire (const Eigen::Vector3f &position, const geo::WireID &wireID) const
 Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range. More...
 
void BuildChannelStatusVec () const
 Create the internal channel status vector (assume will eventually be event-by-event) More...
 
float chargeIntegral (float, float, float, int, int) const
 Perform charge integration between limits. More...
 
void clear ()
 clear the tuple vectors before processing next event More...
 

Private Attributes

std::vector< art::InputTagm_hitFinderTagVec
 Data members to follow. More...
 
float m_numSigmaPeakTime
 
float m_hitWidthSclFctr
 
float m_deltaPeakTimeSig
 
std::vector< int > m_invalidTPCVec
 
float m_wirePitchScaleFactor
 Scaling factor to determine max distance allowed between candidate pairs. More...
 
float m_maxHit3DChiSquare
 Provide ability to select hits based on "chi square". More...
 
bool m_outputHistograms
 Take the time to create and fill some histograms for diagnostics. More...
 
bool m_enableMonitoring
 
float m_wirePitch [3]
 
std::vector< float > m_timeVector
 
float m_zPosOffset
 
TTree * m_tupleTree
 output analysis tree More...
 
std::vector< float > m_deltaTimeVec
 
std::vector< float > m_chiSquare3DVec
 
std::vector< float > m_maxPullVec
 
std::vector< float > m_overlapFractionVec
 
std::vector< float > m_overlapRangeVec
 
std::vector< float > m_maxDeltaPeakVec
 
std::vector< float > m_maxSideVecVec
 
std::vector< float > m_pairWireDistVec
 
std::vector< float > m_smallChargeDiffVec
 
std::vector< int > m_smallIndexVec
 
std::vector< float > m_qualityMetricVec
 
std::vector< float > m_spacePointChargeVec
 
std::vector< float > m_hitAsymmetryVec
 
Hit2DList m_clusterHit2DMasterList
 
PlaneToHitVectorMap m_planeToHitVectorMap
 
PlaneToWireToHitSetMap m_planeToWireToHitSetMap
 
ChannelStatusByPlaneVec m_channelStatus
 
size_t m_numBadChannels
 
bool m_weHaveAllBeenHereBefore = false
 
const geo::Geometrym_geometry
 
const geo::WireReadoutGeomm_wireReadoutGeom
 
const lariov::ChannelStatusProvider * m_channelFilter
 

Detailed Description

StandardHit3DBuilder class definiton.

Definition at line 76 of file StandardHit3DBuilder_tool.cc.

Member Typedef Documentation

using lar_cluster3d::StandardHit3DBuilder::ChannelStatusVec = std::vector<size_t>
private

define data structure for keeping track of channel status

Definition at line 236 of file StandardHit3DBuilder_tool.cc.

This builds a list of candidate hit pairs from lists of hits on two planes.

Definition at line 160 of file StandardHit3DBuilder_tool.cc.

Given the ClusterHit2D objects, build the HitPairMap.

Definition at line 152 of file StandardHit3DBuilder_tool.cc.

using lar_cluster3d::IHit3DBuilder::RecobHitToPtrMap = std::unordered_map<const recob::Hit*, art::Ptr<recob::Hit>>
inherited

Defines a structure mapping art representation to internal.

Definition at line 43 of file IHit3DBuilder.h.

Member Enumeration Documentation

enumerate the possible values for time checking if monitoring timing

Enumerator
COLLECTARTHITS 
BUILDTHREEDHITS 
BUILDNEWHITS 
NUMTIMEVALUES 

Definition at line 56 of file IHit3DBuilder.h.

Constructor & Destructor Documentation

lar_cluster3d::StandardHit3DBuilder::StandardHit3DBuilder ( fhicl::ParameterSet const &  pset)
explicit

Constructor.

Parameters
pset

Definition at line 295 of file StandardHit3DBuilder_tool.cc.

References clear(), Get, art::ServiceHandle< T, SCOPE >::get(), m_channelFilter, m_chiSquare3DVec, m_deltaPeakTimeSig, m_deltaTimeVec, m_enableMonitoring, m_geometry, m_hitAsymmetryVec, m_hitFinderTagVec, m_hitWidthSclFctr, m_invalidTPCVec, m_maxDeltaPeakVec, m_maxHit3DChiSquare, m_maxPullVec, m_maxSideVecVec, m_numSigmaPeakTime, m_outputHistograms, m_overlapFractionVec, m_overlapRangeVec, m_pairWireDistVec, m_qualityMetricVec, m_smallChargeDiffVec, m_smallIndexVec, m_spacePointChargeVec, m_tupleTree, m_wirePitch, m_wirePitchScaleFactor, m_wireReadoutGeom, m_zPosOffset, and geo::WireReadoutGeom::Plane().

298  {
299  m_hitFinderTagVec = pset.get<std::vector<art::InputTag>>("HitFinderTagVec",
300  std::vector<art::InputTag>{"gaushit"});
301  m_enableMonitoring = pset.get<bool>("EnableMonitoring", true);
302  m_numSigmaPeakTime = pset.get<float>("NumSigmaPeakTime", 3.);
303  m_hitWidthSclFctr = pset.get<float>("HitWidthScaleFactor", 6.);
304  m_deltaPeakTimeSig = pset.get<float>("DeltaPeakTimeSig", 1.7);
305  m_zPosOffset = pset.get<float>("ZPosOffset", 0.0);
306  m_invalidTPCVec = pset.get<std::vector<int>>("InvalidTPCVec", std::vector<int>{});
307  m_wirePitchScaleFactor = pset.get<float>("WirePitchScaleFactor", 1.9);
308  m_maxHit3DChiSquare = pset.get<float>("MaxHitChiSquare", 6.0);
309  m_outputHistograms = pset.get<bool>("OutputHistograms", false);
310 
313 
314  // Returns the wire pitch per plane assuming they will be the same for all TPCs
315  constexpr geo::TPCID tpcid{0, 0};
316  m_wirePitch[0] = m_wireReadoutGeom->Plane({tpcid, 0}).WirePitch();
317  m_wirePitch[1] = m_wireReadoutGeom->Plane({tpcid, 1}).WirePitch();
318  m_wirePitch[2] = m_wireReadoutGeom->Plane({tpcid, 2}).WirePitch();
319 
320  if (m_outputHistograms) {
321  // Access ART's TFileService, which will handle creating and writing
322  // histograms and n-tuples for us.
324 
325  m_tupleTree = tfs->make<TTree>("Hit3DBuilderTree", "Tree by StandardHit3DBuilder");
326 
327  clear();
328 
329  m_tupleTree->Branch("DeltaTime2D", "std::vector<float>", &m_deltaTimeVec);
330  m_tupleTree->Branch("ChiSquare3D", "std::vector<float>", &m_chiSquare3DVec);
331  m_tupleTree->Branch("MaxPullValue", "std::vector<float>", &m_maxPullVec);
332  m_tupleTree->Branch("OverlapFraction", "std::vector<float>", &m_overlapFractionVec);
333  m_tupleTree->Branch("OverlapRange", "std::vector<float>", &m_overlapRangeVec);
334  m_tupleTree->Branch("MaxDeltaPeak", "std::vector<float>", &m_maxDeltaPeakVec);
335  m_tupleTree->Branch("MaxSideVec", "std::vector<float>", &m_maxSideVecVec);
336  m_tupleTree->Branch("PairWireDistVec", "std::vector<float>", &m_pairWireDistVec);
337  m_tupleTree->Branch("SmallChargeDiff", "std::vector<float>", &m_smallChargeDiffVec);
338  m_tupleTree->Branch("SmallChargeIdx", "std::vector<int>", &m_smallIndexVec);
339  m_tupleTree->Branch("QualityMetric", "std::vector<float>", &m_qualityMetricVec);
340  m_tupleTree->Branch("SPCharge", "std::vector<float>", &m_spacePointChargeVec);
341  m_tupleTree->Branch("HitAsymmetry", "std::vector<float>", &m_hitAsymmetryVec);
342  }
343  }
float m_wirePitchScaleFactor
Scaling factor to determine max distance allowed between candidate pairs.
T * get() const
Definition: ServiceHandle.h:69
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
const geo::WireReadoutGeom * m_wireReadoutGeom
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
const lariov::ChannelStatusProvider * m_channelFilter
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
void clear()
clear the tuple vectors before processing next event

Member Function Documentation

void lar_cluster3d::StandardHit3DBuilder::BuildChannelStatusVec ( ) const
private

Create the internal channel status vector (assume will eventually be event-by-event)

Definition at line 373 of file StandardHit3DBuilder_tool.cc.

References geo::WireReadoutGeom::ChannelToWire(), art::left(), m_channelFilter, m_channelStatus, m_numBadChannels, m_wireReadoutGeom, geo::WireReadoutGeom::Nchannels(), geo::WireReadoutGeom::Nplanes(), geo::WireReadoutGeom::Nwires(), geo::PlaneID::Plane, art::right(), lar_cluster3d::SetPeakHitPairIteratorOrder(), and geo::WireID::Wire.

Referenced by BuildHit3D().

374  {
375  // This is called each event, clear out the previous version and start over
376  if (!m_channelStatus.empty()) m_channelStatus.clear();
377 
378  m_numBadChannels = 0;
380 
381  // Loop through views/planes to set the wire length vectors
382  constexpr geo::TPCID tpcid{0, 0};
383  for (unsigned int idx = 0; idx < m_channelStatus.size(); idx++) {
384  m_channelStatus[idx] =
386  }
387 
388  // Loop through the channels and mark those that are "bad"
389  for (size_t channel = 0; channel < m_wireReadoutGeom->Nchannels(); channel++) {
390  if (m_channelFilter->IsGood(channel)) continue;
391 
392  std::vector<geo::WireID> wireIDVec = m_wireReadoutGeom->ChannelToWire(channel);
393  geo::WireID wireID = wireIDVec[0];
394  lariov::ChannelStatusProvider::Status_t chanStat = m_channelFilter->Status(channel);
395 
396  m_channelStatus[wireID.Plane][wireID.Wire] = chanStat;
398  }
399  }
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
std::vector< size_t > ChannelStatusVec
define data structure for keeping track of channel status
virtual unsigned int Nchannels() const =0
Returns the total number of channels present (not necessarily contiguous)
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
const geo::WireReadoutGeom * m_wireReadoutGeom
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
const lariov::ChannelStatusProvider * m_channelFilter
virtual std::vector< WireID > ChannelToWire(raw::ChannelID_t channel) const =0
void lar_cluster3d::StandardHit3DBuilder::BuildHit3D ( reco::HitPairList hitPairList) const
private

Given the ClusterHit2D objects, build the HitPairMap.

Driver for processing input 2D hits, transforming to 3D hits and building lists of associated 3D hits (candidate 3D clusters)

Definition at line 472 of file StandardHit3DBuilder_tool.cc.

References BuildChannelStatusVec(), BuildHitPairMap(), lar_cluster3d::IHit3DBuilder::BUILDTHREEDHITS, reco::ClusterHit2D::getHit(), reco::ClusterHit2D::getTimeTicks(), m_enableMonitoring, m_numRMS, m_planeToHitVectorMap, m_timeVector, and recob::Hit::RMS().

Referenced by Hit3DBuilder().

473  {
478  cet::cpu_timer theClockMakeHits;
479 
480  if (m_enableMonitoring) theClockMakeHits.start();
481 
482  // The first task is to take the lists of input 2D hits (a map of view to sorted lists of 2D hits)
483  // and then to build a list of 3D hits to be used in downstream processing
485 
486  size_t numHitPairs = BuildHitPairMap(m_planeToHitVectorMap, hitPairList);
487 
488  if (m_enableMonitoring) {
489  theClockMakeHits.stop();
490 
491  m_timeVector[BUILDTHREEDHITS] = theClockMakeHits.accumulated_real_time();
492  }
493 
494  mf::LogDebug("Cluster3D") << ">>>>> 3D hit building done, found " << numHitPairs << " 3D Hits"
495  << std::endl;
496  }
void BuildChannelStatusVec() const
Create the internal channel status vector (assume will eventually be event-by-event) ...
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
size_t BuildHitPairMap(PlaneToHitVectorMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
size_t lar_cluster3d::StandardHit3DBuilder::BuildHitPairMap ( PlaneToHitVectorMap planeToHitVectorMap,
reco::HitPairList hitPairList 
) const
private

Given the ClusterHit2D objects, build the HitPairMap.

Given input 2D hits, build out the lists of possible 3D hits

   The current strategy: ideally all 3D hits would be comprised of a triplet of 2D hits, one from each view
   However, we have concern that, in particular, the v-plane may have some inefficiency which we have to be
   be prepared to deal with. The idea, then, is to first make the association of hits in the U and W planes
   and then look for the match in the V plane. In the event we don't find the match in the V plane then we
   will evaluate the situation and in some instances keep the U-W pairs in order to keep efficiency high.

Definition at line 549 of file StandardHit3DBuilder_tool.cc.

References BuildHitPairMapByTPC(), m_geometry, m_numSigmaPeakTime, geo::GeometryCore::Ncryostats(), geo::GeometryCore::NTPC(), and lar_cluster3d::SetPairStartTimeOrder().

Referenced by BuildHit3D().

551  {
561  size_t totalNumHits(0);
562  size_t hitPairCntr(0);
563 
564  size_t nTriplets(0);
565  size_t nDeadChanHits(0);
566 
567  // Set up to loop over cryostats and tpcs...
568  for (size_t cryoIdx = 0; cryoIdx < m_geometry->Ncryostats(); cryoIdx++) {
569  for (size_t tpcIdx = 0; tpcIdx < m_geometry->NTPC(); tpcIdx++) {
571  planeToHitVectorMap.find(geo::PlaneID(cryoIdx, tpcIdx, 0));
573  planeToHitVectorMap.find(geo::PlaneID(cryoIdx, tpcIdx, 1));
575  planeToHitVectorMap.find(geo::PlaneID(cryoIdx, tpcIdx, 2));
576 
577  size_t nPlanesWithHits =
578  (mapItr0 != planeToHitVectorMap.end() && !mapItr0->second.empty() ? 1 : 0) +
579  (mapItr1 != planeToHitVectorMap.end() && !mapItr1->second.empty() ? 1 : 0) +
580  (mapItr2 != planeToHitVectorMap.end() && !mapItr2->second.empty() ? 1 : 0);
581 
582  if (nPlanesWithHits < 2) continue;
583 
584  HitVector& hitVector0 = mapItr0->second;
585  HitVector& hitVector1 = mapItr1->second;
586  HitVector& hitVector2 = mapItr2->second;
587 
588  // We are going to resort the hits into "start time" order...
589  std::sort(hitVector0.begin(),
590  hitVector0.end(),
591  SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
592  std::sort(hitVector1.begin(),
593  hitVector1.end(),
594  SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
595  std::sort(hitVector2.begin(),
596  hitVector2.end(),
597  SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
598 
599  PlaneHitVectorItrPairVec hitItrVec = {
600  HitVectorItrPair(hitVector0.begin(), hitVector0.end()),
601  HitVectorItrPair(hitVector1.begin(), hitVector1.end()),
602  HitVectorItrPair(hitVector2.begin(), hitVector2.end())};
603 
604  totalNumHits += BuildHitPairMapByTPC(hitItrVec, hitPairList);
605  }
606  }
607 
608  // Return the hit pair list but sorted by z and y positions (faster traversal in next steps)
609  hitPairList.sort(SetPairStartTimeOrder);
610 
611  // Where are we?
612  mf::LogDebug("Cluster3D") << "Total number hits: " << totalNumHits << std::endl;
613  mf::LogDebug("Cluster3D") << "Created a total of " << hitPairList.size()
614  << " hit pairs, counted: " << hitPairCntr << std::endl;
615  mf::LogDebug("Cluster3D") << "-- Triplets: " << nTriplets
616  << ", dead channel pairs: " << nDeadChanHits << std::endl;
617 
618  return hitPairList.size();
619  }
intermediate_table::iterator iterator
unsigned int NTPC(CryostatID const &cryoid=details::cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
Definition: GeometryCore.h:416
size_t BuildHitPairMapByTPC(PlaneHitVectorItrPairVec &planeHitVectorItrPairVec, reco::HitPairList &hitPairList) const
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:303
std::vector< const reco::ClusterHit2D * > HitVector
std::vector< std::pair< HitVector::iterator, HitVector::iterator >> PlaneHitVectorItrPairVec
Given the ClusterHit2D objects, build the HitPairMap.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
bool SetPairStartTimeOrder(const reco::ClusterHit3D &left, const reco::ClusterHit3D &right)
size_t lar_cluster3d::StandardHit3DBuilder::BuildHitPairMapByTPC ( PlaneHitVectorItrPairVec planeHitVectorItrPairVec,
reco::HitPairList hitPairList 
) const
private

Given input 2D hits, build out the lists of possible 3D hits

   The current strategy: ideally all 3D hits would be comprised of a triplet of 2D hits, one from each view
   However, we have concern that, in particular, the v-plane may have some inefficiency which we have to be
   be prepared to deal with. The idea, then, is to first make the association of hits in the U and W planes
   and then look for the match in the V plane. In the event we don't find the match in the V plane then we
   will evaluate the situation and in some instances keep the U-W pairs in order to keep efficiency high.

Definition at line 621 of file StandardHit3DBuilder_tool.cc.

References findGoodHitPairs(), findGoodTriplets(), reco::ClusterHit2D::getTimeTicks(), and m_numSigmaPeakTime.

Referenced by BuildHitPairMap().

623  {
634  // Define functions to set start/end iterators in the loop below
635  auto SetStartIterator =
636  [](HitVector::iterator startItr, HitVector::iterator endItr, float rms, float startTime) {
637  while (startItr != endItr) {
638  float numRMS(rms);
639  if ((*startItr)->getTimeTicks() + numRMS * (*startItr)->getHit()->RMS() < startTime)
640  startItr++;
641  else
642  break;
643  }
644  return startItr;
645  };
646 
647  auto SetEndIterator =
648  [](HitVector::iterator firstItr, HitVector::iterator endItr, float rms, float endTime) {
649  while (firstItr != endItr) {
650  float numRMS(rms);
651  if ((*firstItr)->getTimeTicks() - numRMS * (*firstItr)->getHit()->RMS() < endTime)
652  firstItr++;
653  else
654  break;
655  }
656  return firstItr;
657  };
658 
659  //*********************************************************************************
660  // Basically, we try to loop until done...
661  while (1) {
662  // Sort so that the earliest hit time will be the first element, etc.
663  std::sort(hitItrVec.begin(), hitItrVec.end(), SetStartTimeOrder(m_numSigmaPeakTime));
664 
665  // This loop iteration's golden hit
666  const reco::ClusterHit2D* goldenHit = *hitItrVec[0].first;
667 
668  // The range of history... (for this hit)
669  float goldenTimeStart = goldenHit->getTimeTicks() -
670  m_numSigmaPeakTime * goldenHit->getHit()->RMS() -
671  std::numeric_limits<float>::epsilon();
672  float goldenTimeEnd = goldenHit->getTimeTicks() +
673  m_numSigmaPeakTime * goldenHit->getHit()->RMS() +
674  std::numeric_limits<float>::epsilon();
675 
676  // Set iterators to insure we'll be in the overlap ranges
677  HitVector::iterator hitItr1Start = SetStartIterator(
678  hitItrVec[1].first, hitItrVec[1].second, m_numSigmaPeakTime, goldenTimeStart);
679  HitVector::iterator hitItr1End =
680  SetEndIterator(hitItr1Start, hitItrVec[1].second, m_numSigmaPeakTime, goldenTimeEnd);
681  HitVector::iterator hitItr2Start = SetStartIterator(
682  hitItrVec[2].first, hitItrVec[2].second, m_numSigmaPeakTime, goldenTimeStart);
683  HitVector::iterator hitItr2End =
684  SetEndIterator(hitItr2Start, hitItrVec[2].second, m_numSigmaPeakTime, goldenTimeEnd);
685 
686  // Since we'll use these many times in the internal loops, pre make the pairs for the second set of hits
687  HitMatchPairVecMap pair12Map;
688  HitMatchPairVecMap pair13Map;
689 
690  size_t n12Pairs = findGoodHitPairs(goldenHit, hitItr1Start, hitItr1End, pair12Map);
691  size_t n13Pairs = findGoodHitPairs(goldenHit, hitItr2Start, hitItr2End, pair13Map);
692 
693  if (n12Pairs > n13Pairs)
694  findGoodTriplets(pair12Map, pair13Map, hitPairList);
695  else
696  findGoodTriplets(pair13Map, pair12Map, hitPairList);
697 
698  hitItrVec[0].first++;
699 
700  int nPlanesWithHits(0);
701 
702  for (auto& pair : hitItrVec)
703  if (pair.first != pair.second) nPlanesWithHits++;
704 
705  if (nPlanesWithHits < 2) break;
706  }
707 
708  return hitPairList.size();
709  }
intermediate_table::iterator iterator
void findGoodTriplets(HitMatchPairVecMap &, HitMatchPairVecMap &, reco::HitPairList &) const
This algorithm takes lists of hit pairs and finds good triplets.
float getTimeTicks() const
Definition: Cluster3D.h:75
int findGoodHitPairs(const reco::ClusterHit2D *, HitVector::iterator &, HitVector::iterator &, HitMatchPairVecMap &) const
std::map< geo::WireID, HitMatchPairVec > HitMatchPairVecMap
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
float lar_cluster3d::StandardHit3DBuilder::chargeIntegral ( float  peakMean,
float  peakAmp,
float  peakSigma,
int  low,
int  hi 
) const
private

Perform charge integration between limits.

Definition at line 1236 of file StandardHit3DBuilder_tool.cc.

Referenced by makeHitTriplet().

1241  {
1242  float integral(0);
1243 
1244  for (int sigPos = low; sigPos < hi; sigPos++) {
1245  float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
1246  integral += peakAmp * std::exp(-0.5 * arg * arg);
1247  }
1248 
1249  return integral;
1250  }
void lar_cluster3d::StandardHit3DBuilder::clear ( )
private

clear the tuple vectors before processing next event

Definition at line 356 of file StandardHit3DBuilder_tool.cc.

References m_chiSquare3DVec, m_deltaTimeVec, m_hitAsymmetryVec, m_maxDeltaPeakVec, m_maxPullVec, m_maxSideVecVec, m_overlapFractionVec, m_overlapRangeVec, m_pairWireDistVec, m_qualityMetricVec, m_smallChargeDiffVec, m_smallIndexVec, and m_spacePointChargeVec.

Referenced by Hit3DBuilder(), and StandardHit3DBuilder().

357  {
358  m_deltaTimeVec.clear();
359  m_chiSquare3DVec.clear();
360  m_maxPullVec.clear();
361  m_overlapFractionVec.clear();
362  m_overlapRangeVec.clear();
363  m_maxDeltaPeakVec.clear();
364  m_maxSideVecVec.clear();
365  m_pairWireDistVec.clear();
366  m_smallChargeDiffVec.clear();
367  m_smallIndexVec.clear();
368  m_qualityMetricVec.clear();
369  m_spacePointChargeVec.clear();
370  m_hitAsymmetryVec.clear();
371  }
void lar_cluster3d::StandardHit3DBuilder::CollectArtHits ( const art::Event evt) const
private

Extract the ART hits and the ART hit-particle relationships.

Parameters
evt- the ART event

Recover the 2D hits from art and fill out the local data structures for the 3D clustering

Definition at line 1462 of file StandardHit3DBuilder_tool.cc.

References geo::WireReadoutGeom::ChannelToWire(), lar_cluster3d::IHit3DBuilder::COLLECTARTHITS, geo::CryostatID::Cryostat, art::ProductRetriever::getByLabel(), art::Handle< T >::isValid(), m_clusterHit2DMasterList, m_enableMonitoring, m_geometry, m_hitFinderTagVec, m_invalidTPCVec, m_planeToHitVectorMap, m_planeToWireToHitSetMap, m_timeVector, m_weHaveAllBeenHereBefore, m_wireReadoutGeom, geo::GeometryCore::Ncryostats(), geo::GeometryCore::NTPC(), geo::PlaneID::Plane, lar_cluster3d::SetHitTimeOrder(), geo::TPCID::TPC, and detinfo::trigger_offset().

Referenced by Hit3DBuilder().

1463  {
1468  // Start by getting a vector of valid, non empty hit collections to make sure we really have something to do here...
1469  // Here is a container for the hits...
1470  std::vector<const recob::Hit*> recobHitVec;
1471 
1472  auto const clock_data =
1474  auto const det_prop =
1476 
1477  // Loop through the list of input sources
1478  for (const auto& inputTag : m_hitFinderTagVec) {
1479  art::Handle<std::vector<recob::Hit>> recobHitHandle;
1480  evt.getByLabel(inputTag, recobHitHandle);
1481 
1482  if (!recobHitHandle.isValid() || recobHitHandle->size() == 0) continue;
1483 
1484  recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1485 
1486  for (const auto& hit : *recobHitHandle)
1487  recobHitVec.push_back(&hit);
1488  }
1489 
1490  // If the vector is empty there is nothing to do
1491  if (recobHitVec.empty()) return;
1492 
1493  cet::cpu_timer theClockMakeHits;
1494 
1495  if (m_enableMonitoring) theClockMakeHits.start();
1496 
1497  // We'll want to correct the hit times for the plane offsets
1498  // (note this is already taken care of when converting to position)
1499  std::map<geo::PlaneID, double> planeOffsetMap;
1500 
1501  // Try to output a formatted string
1502  std::string debugMessage("");
1503 
1504  // Initialize the plane to hit vector map
1505  for (size_t cryoIdx = 0; cryoIdx < m_geometry->Ncryostats(); cryoIdx++) {
1506  for (size_t tpcIdx = 0; tpcIdx < m_geometry->NTPC(); tpcIdx++) {
1507  m_planeToHitVectorMap[geo::PlaneID(cryoIdx, tpcIdx, 0)] = HitVector();
1508  m_planeToHitVectorMap[geo::PlaneID(cryoIdx, tpcIdx, 1)] = HitVector();
1509  m_planeToHitVectorMap[geo::PlaneID(cryoIdx, tpcIdx, 2)] = HitVector();
1510 
1511  // What we want here are the relative offsets between the planes
1512  // Note that plane 0 is assumed the "first" plane and is the reference
1513  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 0)] = 0.;
1514  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 1)] =
1515  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 1)) -
1516  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0));
1517  planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 2)] =
1518  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 2)) -
1519  det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0));
1520 
1521  // Should we provide output?
1523  std::ostringstream outputString;
1524 
1525  outputString << "***> plane 0 offset: "
1526  << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 0)]
1527  << ", plane 1: " << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 1)]
1528  << ", plane 2: " << planeOffsetMap[geo::PlaneID(cryoIdx, tpcIdx, 2)]
1529  << "\n";
1530  debugMessage += outputString.str();
1531  outputString << " Det prop plane 0: "
1532  << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 0))
1533  << ", plane 1: "
1534  << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 1))
1535  << ", plane 2: "
1536  << det_prop.GetXTicksOffset(geo::PlaneID(cryoIdx, tpcIdx, 2))
1537  << ", Trig: " << trigger_offset(clock_data) << "\n";
1538  debugMessage += outputString.str();
1539  }
1540  }
1541  }
1542 
1544  mf::LogDebug("Cluster3D") << debugMessage << std::endl;
1545 
1547  }
1548 
1549  // Cycle through the recob hits to build ClusterHit2D objects and insert
1550  // them into the map
1551  for (const auto& recobHit : recobHitVec) {
1552  // Reject hits with negative charge, these are misreconstructed
1553  if (recobHit->Integral() < 0.) continue;
1554 
1555  // For some detectors we can have multiple wire ID's associated to a given channel.
1556  // So we recover the list of these wire IDs
1557  const std::vector<geo::WireID>& wireIDs =
1558  m_wireReadoutGeom->ChannelToWire(recobHit->Channel());
1559 
1560  // And then loop over all possible to build out our maps
1561  for (const auto& wireID : wireIDs) {
1562  // Check if this is an invalid TPC
1563  // (for example, in protoDUNE there are logical TPC's which see no signal)
1564  if (std::find(m_invalidTPCVec.begin(), m_invalidTPCVec.end(), wireID.TPC) !=
1565  m_invalidTPCVec.end())
1566  continue;
1567 
1568  // Note that a plane ID will define cryostat, TPC and plane
1569  const geo::PlaneID& planeID = wireID.planeID();
1570 
1571  double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1572  double xPosition(det_prop.ConvertTicksToX(
1573  recobHit->PeakTime(), planeID.Plane, planeID.TPC, planeID.Cryostat));
1574 
1575  m_clusterHit2DMasterList.emplace_back(0, 0., 0., xPosition, hitPeakTime, wireID, recobHit);
1576 
1577  m_planeToHitVectorMap[planeID].push_back(&m_clusterHit2DMasterList.back());
1578  m_planeToWireToHitSetMap[planeID][wireID.Wire].insert(&m_clusterHit2DMasterList.back());
1579  }
1580  }
1581 
1582  // Make a loop through to sort the recover hits in time order
1583  for (auto& hitVectorMap : m_planeToHitVectorMap)
1584  std::sort(hitVectorMap.second.begin(), hitVectorMap.second.end(), SetHitTimeOrder);
1585 
1586  if (m_enableMonitoring) {
1587  theClockMakeHits.stop();
1588 
1589  m_timeVector[COLLECTARTHITS] = theClockMakeHits.accumulated_real_time();
1590  }
1591 
1592  mf::LogDebug("Cluster3D") << ">>>>> Number of ART hits: " << m_clusterHit2DMasterList.size()
1593  << std::endl;
1594  }
bool SetHitTimeOrder(const reco::ClusterHit2D *left, const reco::ClusterHit2D *right)
unsigned int NTPC(CryostatID const &cryoid=details::cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
Definition: GeometryCore.h:416
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:303
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
bool isValid() const noexcept
Definition: Handle.h:203
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
const geo::WireReadoutGeom * m_wireReadoutGeom
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
Detector simulation of raw signals on wires.
std::vector< const reco::ClusterHit2D * > HitVector
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
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
int trigger_offset(DetectorClocksData const &data)
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
void lar_cluster3d::StandardHit3DBuilder::CreateNewRecobHitCollection ( art::Event event,
reco::HitPairList hitPairList,
std::vector< recob::Hit > &  hitPtrVec,
RecobHitToPtrMap recobHitToPtrMap 
)
private

Create a new 2D hit collection from hits associated to 3D space points.

Definition at line 1598 of file StandardHit3DBuilder_tool.cc.

References lar_cluster3d::IHit3DBuilder::BUILDNEWHITS, reco::ClusterHit2D::getHit(), m_clusterHit2DMasterList, m_enableMonitoring, and m_timeVector.

Referenced by Hit3DBuilder().

1602  {
1603  // Set up the timing
1604  cet::cpu_timer theClockBuildNewHits;
1605 
1606  if (m_enableMonitoring) theClockBuildNewHits.start();
1607 
1608  // We want to build a unique list of hits from the input 3D points which, we know, reuse 2D points frequently
1609  // At the same time we need to create a new 2D hit with the "correct" WireID and replace the old 2D hit in the
1610  // ClusterHit2D object with this new one... while keeping track of the use of the old ones. My head is spinning...
1611  // Declare a set which will allow us to keep track of those CusterHit2D objects we have seen already
1612  std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1613 
1614  // Use this handy art utility to make art::Ptr objects to the new recob::Hits for use in the output phase
1615  art::PtrMaker<recob::Hit> ptrMaker(event);
1616 
1617  // Reserve enough memory to replace every recob::Hit we have considered (this is upper limit)
1618  hitPtrVec.reserve(m_clusterHit2DMasterList.size());
1619 
1620  // Scheme is to loop through all 3D hits, then through each associated ClusterHit2D object
1621  for (reco::ClusterHit3D& hit3D : hitPairList) {
1622  reco::ClusterHit2DVec& hit2DVec = hit3D.getHits();
1623 
1624  // The loop is over the index so we can recover the correct WireID to associate to the new hit when made
1625  for (size_t idx = 0; idx < hit3D.getHits().size(); idx++) {
1626  const reco::ClusterHit2D* hit2D = hit2DVec[idx];
1627 
1628  // Have we seen this 2D hit already?
1629  if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end()) {
1630  visitedHit2DSet.insert(hit2D);
1631 
1632  // Create and save the new recob::Hit with the correct WireID
1633  hitPtrVec.emplace_back(
1634  recob::HitCreator(*hit2D->getHit(), hit3D.getWireIDs()[idx]).copy());
1635 
1636  // Recover a pointer to it...
1637  recob::Hit* newHit = &hitPtrVec.back();
1638 
1639  // Create a mapping from this hit to an art Ptr representing it
1640  recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size() - 1);
1641 
1642  // And set the pointer to this hit in the ClusterHit2D object
1643  const_cast<reco::ClusterHit2D*>(hit2D)->setHit(newHit);
1644  }
1645  }
1646  }
1647 
1648  size_t numNewHits = hitPtrVec.size();
1649 
1650  if (m_enableMonitoring) {
1651  theClockBuildNewHits.stop();
1652 
1653  m_timeVector[BUILDNEWHITS] = theClockBuildNewHits.accumulated_real_time();
1654  }
1655 
1656  mf::LogDebug("Cluster3D") << ">>>>> New output recob::Hit size: " << numNewHits << " (vs "
1657  << m_clusterHit2DMasterList.size() << " input)" << std::endl;
1658 
1659  return;
1660  }
const recob::Hit * getHit() const
Definition: Cluster3D.h:77
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:87
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:90
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
float lar_cluster3d::StandardHit3DBuilder::DistanceFromPointToHitWire ( const Eigen::Vector3f &  position,
const geo::WireID wireID 
) const
private

Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range.

Definition at line 1408 of file StandardHit3DBuilder_tool.cc.

References geo::vect::dot(), reco::ClusterHit2D::getHit(), m_wireReadoutGeom, lar_cluster3d::Hit2DSetCompare::operator()(), recob::Hit::PeakTime(), lar_cluster3d::SetHitTimeOrder(), and geo::WireReadoutGeom::WireEndPoints().

Referenced by makeHitTriplet().

1410  {
1411  float distance;
1412 
1413  // Embed the call to the geometry's services nearest wire id method in a try-catch block
1414  try {
1415  // Get the wire endpoints
1416  Eigen::Vector3d wireStart;
1417  Eigen::Vector3d wireEnd;
1418 
1419  m_wireReadoutGeom->WireEndPoints(wireIDIn, &wireStart[0], &wireEnd[0]);
1420 
1421  // Want the hit position to have same x value as wire coordinates
1422  Eigen::Vector3d hitPosition(wireStart[0], position[1], position[2]);
1423 
1424  // Want the wire direction
1425  Eigen::Vector3d wireDir = wireEnd - wireStart;
1426 
1427  wireDir.normalize();
1428 
1429  // Get arc length to doca
1430  double arcLen = (hitPosition - wireStart).dot(wireDir);
1431 
1432  Eigen::Vector3d docaVec = hitPosition - (wireStart + arcLen * wireDir);
1433 
1434  distance = docaVec.norm();
1435  }
1436  catch (std::exception& exc) {
1437  // This can happen, almost always because the coordinates are **just** out of range
1438  mf::LogWarning("Cluster3D") << "Exception caught finding nearest wire, position - "
1439  << exc.what() << std::endl;
1440 
1441  // Assume extremum for wire number depending on z coordinate
1442  distance = 0.;
1443  }
1444 
1445  return distance;
1446  }
const geo::WireReadoutGeom * m_wireReadoutGeom
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void WireEndPoints(WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const reco::ClusterHit2D * lar_cluster3d::StandardHit3DBuilder::FindBestMatchingHit ( const Hit2DSet hit2DSet,
const reco::ClusterHit3D pair,
float  pairDeltaTimeLimits 
) const
private

A utility routine for finding a 2D hit closest in time to the given pair.

Definition at line 1325 of file StandardHit3DBuilder_tool.cc.

References reco::ClusterHit3D::getAvePeakTime().

1329  {
1330  static const float minCharge(0.);
1331 
1332  const reco::ClusterHit2D* bestVHit(0);
1333 
1334  float pairAvePeakTime(pair.getAvePeakTime());
1335 
1336  // Idea is to loop through the input set of hits and look for the best combination
1337  for (const auto& hit2D : hit2DSet) {
1338  if (hit2D->getHit()->Integral() < minCharge) continue;
1339 
1340  float hitVPeakTime(hit2D->getTimeTicks());
1341  float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1342 
1343  if (deltaPeakTime > pairDeltaTimeLimits) continue;
1344 
1345  if (deltaPeakTime < -pairDeltaTimeLimits) break;
1346 
1347  pairDeltaTimeLimits = fabs(deltaPeakTime);
1348  bestVHit = hit2D;
1349  }
1350 
1351  return bestVHit;
1352  }
float getAvePeakTime() const
Definition: Cluster3D.h:160
int lar_cluster3d::StandardHit3DBuilder::findGoodHitPairs ( const reco::ClusterHit2D goldenHit,
HitVector::iterator startItr,
HitVector::iterator endItr,
HitMatchPairVecMap hitMatchMap 
) const
private

Definition at line 711 of file StandardHit3DBuilder_tool.cc.

References m_hitWidthSclFctr, makeHitPair(), and reco::ClusterHit2D::WireID().

Referenced by BuildHitPairMapByTPC().

715  {
716  int numPairs(0);
717 
718  // Loop through the input secon hits and make pairs
719  while (startItr != endItr) {
720  const reco::ClusterHit2D* hit = *startItr++;
721  reco::ClusterHit3D pair;
722 
723  // pair returned with a negative ave time is signal of failure
724  if (!makeHitPair(pair, goldenHit, hit, m_hitWidthSclFctr)) continue;
725 
726  geo::WireID wireID = hit->WireID();
727 
728  hitMatchMap[wireID].emplace_back(hit, pair);
729 
730  numPairs++;
731  }
732 
733  return numPairs;
734  }
const geo::WireID & WireID() const
Definition: Cluster3D.h:76
bool makeHitPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, float hitWidthSclFctr=1., size_t hitPairCntr=0) const
Make a HitPair object by checking two hits.
Detector simulation of raw signals on wires.
void lar_cluster3d::StandardHit3DBuilder::findGoodTriplets ( HitMatchPairVecMap pair12Map,
HitMatchPairVecMap pair13Map,
reco::HitPairList hitPairList 
) const
private

This algorithm takes lists of hit pairs and finds good triplets.

Definition at line 736 of file StandardHit3DBuilder_tool.cc.

References art::left(), m_deltaPeakTimeSig, m_numBadChannels, makeDeadChannelPair(), makeHitTriplet(), art::right(), and reco::ClusterHit3D::setID().

Referenced by BuildHitPairMapByTPC().

739  {
740  // Build triplets from the two lists of hit pairs
741  if (!pair12Map.empty()) {
742  // temporary container for dead channel hits
743  std::vector<reco::ClusterHit3D> tempDeadChanVec;
744  reco::ClusterHit3D deadChanPair;
745 
746  // Keep track of which third plane hits have been used
747  std::map<const reco::ClusterHit3D*, bool> usedPairMap;
748 
749  // Initial population of this map with the pair13Map hits
750  for (const auto& pair13 : pair13Map) {
751  for (const auto& hit2Dhit3DPair : pair13.second)
752  usedPairMap[&hit2Dhit3DPair.second] = false;
753  }
754 
755  // The outer loop is over all hit pairs made from the first two plane combinations
756  for (const auto& pair12 : pair12Map) {
757  if (pair12.second.empty()) continue;
758 
759  // This loop is over hit pairs that share the same first two plane wires but may have different
760  // hit times on those wires
761  for (const auto& hit2Dhit3DPair12 : pair12.second) {
762  const reco::ClusterHit3D& pair1 = hit2Dhit3DPair12.second;
763 
764  // populate the map with initial value
765  usedPairMap[&pair1] = false;
766 
767  // The simplest approach here is to loop over all possibilities and let the triplet builder weed out the weak candidates
768  for (const auto& pair13 : pair13Map) {
769  if (pair13.second.empty()) continue;
770 
771  for (const auto& hit2Dhit3DPair13 : pair13.second) {
772  const reco::ClusterHit2D* hit2 = hit2Dhit3DPair13.first;
773  const reco::ClusterHit3D& pair2 = hit2Dhit3DPair13.second;
774 
775  // If success try for the triplet
776  reco::ClusterHit3D triplet;
777 
778  if (makeHitTriplet(triplet, pair1, hit2)) {
779  triplet.setID(hitPairList.size());
780  hitPairList.emplace_back(triplet);
781  usedPairMap[&pair1] = true;
782  usedPairMap[&pair2] = true;
783  }
784  }
785  }
786  }
787  }
788 
789  // One more loop through the other pairs to check for sick channels
790  if (m_numBadChannels > 0) {
791  for (const auto& pairMapPair : usedPairMap) {
792  if (pairMapPair.second) continue;
793 
794  const reco::ClusterHit3D* pair = pairMapPair.first;
795 
796  // Here we look to see if we failed to make a triplet because the partner wire was dead/noisy/sick
797  if (makeDeadChannelPair(deadChanPair, *pair, 4, 0))
798  tempDeadChanVec.emplace_back(deadChanPair);
799  }
800 
801  // Handle the dead wire triplets
802  if (!tempDeadChanVec.empty()) {
803  // If we have many then see if we can trim down a bit by keeping those with time significance
804  if (tempDeadChanVec.size() > 1) {
805  // Sort by "significance" of agreement
806  std::sort(tempDeadChanVec.begin(),
807  tempDeadChanVec.end(),
808  [](const auto& left, const auto& right) {
809  return left.getDeltaPeakTime() / left.getSigmaPeakTime() <
810  right.getDeltaPeakTime() / right.getSigmaPeakTime();
811  });
812 
813  // What is the range of "significance" from first to last?
814  float firstSig = tempDeadChanVec.front().getDeltaPeakTime() /
815  tempDeadChanVec.front().getSigmaPeakTime();
816  float lastSig =
817  tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
818  float sigRange = lastSig - firstSig;
819 
820  if (lastSig > 0.5 * m_deltaPeakTimeSig && sigRange > 0.5) {
821  // Declare a maximum of 1.5 * the average of the first and last pairs...
822  float maxSignificance = std::max(0.75 * (firstSig + lastSig), 1.0);
823 
824  std::vector<reco::ClusterHit3D>::iterator firstBadElem = std::find_if(
825  tempDeadChanVec.begin(),
826  tempDeadChanVec.end(),
827  [&maxSignificance](const auto& pair) {
828  return pair.getDeltaPeakTime() / pair.getSigmaPeakTime() > maxSignificance;
829  });
830 
831  // But only keep the best 10?
832  if (std::distance(tempDeadChanVec.begin(), firstBadElem) > 20)
833  firstBadElem = tempDeadChanVec.begin() + 20;
834  // Keep at least one hit...
835  else if (firstBadElem == tempDeadChanVec.begin())
836  firstBadElem++;
837 
838  tempDeadChanVec.resize(std::distance(tempDeadChanVec.begin(), firstBadElem));
839  }
840  }
841 
842  for (auto& pair : tempDeadChanVec) {
843  pair.setID(hitPairList.size());
844  hitPairList.emplace_back(pair);
845  }
846  }
847  }
848  }
849 
850  return;
851  }
intermediate_table::iterator iterator
bool makeHitTriplet(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pairIn, const reco::ClusterHit2D *hit2) const
Make a 3D HitPair object by checking two hits.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
float getSigmaPeakTime() const
Definition: Cluster3D.h:162
bool makeDeadChannelPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pair, size_t maxStatus, size_t minStatus) const
Make a 3D HitPair object from a valid pair and a dead channel in the missing plane.
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
void setID(const size_t &id) const
Definition: Cluster3D.h:176
float getDeltaPeakTime() const
Definition: Cluster3D.h:161
int lar_cluster3d::StandardHit3DBuilder::FindNumberInRange ( const Hit2DSet hit2DSet,
const reco::ClusterHit3D pair,
float  range 
) const
private

A utility routine for returning the number of 2D hits from the list in a given range.

Definition at line 1354 of file StandardHit3DBuilder_tool.cc.

References reco::ClusterHit3D::getAvePeakTime().

1357  {
1358  static const float minCharge(0.);
1359 
1360  int numberInRange(0);
1361  float pairAvePeakTime(pair.getAvePeakTime());
1362 
1363  // Idea is to loop through the input set of hits and look for the best combination
1364  for (const auto& hit2D : hit2DSet) {
1365  if (hit2D->getHit()->Integral() < minCharge) continue;
1366 
1367  float hitVPeakTime(hit2D->getTimeTicks());
1368  float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1369 
1370  if (deltaPeakTime > range) continue;
1371 
1372  if (deltaPeakTime < -range) break;
1373 
1374  numberInRange++;
1375  }
1376 
1377  return numberInRange;
1378  }
float getAvePeakTime() const
Definition: Cluster3D.h:160
float lar_cluster3d::StandardHit3DBuilder::getTimeToExecute ( IHit3DBuilder::TimeValues  index) const
inlineoverridevirtual

If monitoring, recover the time to execute a particular function.

Implements lar_cluster3d::IHit3DBuilder.

Definition at line 102 of file StandardHit3DBuilder_tool.cc.

References tca::evt.

103  {
104  return m_timeVector[index];
105  }
void lar_cluster3d::StandardHit3DBuilder::Hit3DBuilder ( art::Event evt,
reco::HitPairList hitPairList,
RecobHitToPtrMap clusterHitToArtPtrMap 
)
overridevirtual

Given a set of recob hits, run DBscan to form 3D clusters.

Parameters
hitPairListThe input list of 3D hits to run clustering on
clusterParametersListA list of cluster objects (parameters from associated hits)

Associations with wires.

Associations with raw digits.

Implements lar_cluster3d::IHit3DBuilder.

Definition at line 418 of file StandardHit3DBuilder_tool.cc.

References BuildHit3D(), clear(), CollectArtHits(), CreateNewRecobHitCollection(), m_clusterHit2DMasterList, m_outputHistograms, m_planeToHitVectorMap, m_planeToWireToHitSetMap, m_timeVector, m_tupleTree, makeRawDigitAssns(), makeWireAssns(), lar_cluster3d::IHit3DBuilder::NUMTIMEVALUES, and art::Event::put().

421  {
422  // Clear the internal data structures
423  m_clusterHit2DMasterList.clear();
424  m_planeToHitVectorMap.clear();
425  m_planeToWireToHitSetMap.clear();
426 
427  m_timeVector.resize(NUMTIMEVALUES, 0.);
428 
429  // Get a hit refiner
430  std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(new std::vector<recob::Hit>);
431 
432  // Recover the 2D hits and then organize them into data structures which will be used in the
433  // DBscan algorithm for building the 3D clusters
434  CollectArtHits(evt);
435 
436  // If there are no hits in our view/wire data structure then do not proceed with the full analysis
437  if (!m_planeToWireToHitSetMap.empty()) {
438  // Call the algorithm that builds 3D hits
439  BuildHit3D(hitPairList);
440 
441  // If we built 3D points then attempt to output a new hit list as well
442  if (!hitPairList.empty())
443  CreateNewRecobHitCollection(evt, hitPairList, *outputHitPtrVec, clusterHitToArtPtrMap);
444  }
445 
446  // Set up to make the associations (if desired)
448  std::unique_ptr<art::Assns<recob::Wire, recob::Hit>> wireAssns(
450 
451  makeWireAssns(evt, *wireAssns, clusterHitToArtPtrMap);
452 
454  std::unique_ptr<art::Assns<raw::RawDigit, recob::Hit>> rawDigitAssns(
456 
457  makeRawDigitAssns(evt, *rawDigitAssns, clusterHitToArtPtrMap);
458 
459  // Move everything into the event
460  evt.put(std::move(outputHitPtrVec));
461  evt.put(std::move(wireAssns));
462  evt.put(std::move(rawDigitAssns));
463 
464  // Handle tree output too
465  if (m_outputHistograms) {
466  m_tupleTree->Fill();
467 
468  clear();
469  }
470  }
void CreateNewRecobHitCollection(art::Event &, reco::HitPairList &, std::vector< recob::Hit > &, RecobHitToPtrMap &)
Create a new 2D hit collection from hits associated to 3D space points.
void BuildHit3D(reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
void makeWireAssns(const art::Event &, art::Assns< recob::Wire, recob::Hit > &, RecobHitToPtrMap &) const
Create recob::Wire to recob::Hit associations.
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
void CollectArtHits(const art::Event &evt) const
Extract the ART hits and the ART hit-particle relationships.
void makeRawDigitAssns(const art::Event &, art::Assns< raw::RawDigit, recob::Hit > &, RecobHitToPtrMap &) const
Create raw::RawDigit to recob::Hit associations.
void clear()
clear the tuple vectors before processing next event
bool lar_cluster3d::StandardHit3DBuilder::makeDeadChannelPair ( reco::ClusterHit3D pairOut,
const reco::ClusterHit3D pair,
size_t  maxStatus,
size_t  minStatus 
) const
private

Make a 3D HitPair object from a valid pair and a dead channel in the missing plane.

Definition at line 1252 of file StandardHit3DBuilder_tool.cc.

References geo::CryostatID::Cryostat, reco::ClusterHit3D::getHits(), reco::ClusterHit3D::getPosition(), reco::ClusterHit2D::getStatusBits(), m_channelStatus, m_wireReadoutGeom, m_zPosOffset, NearestWireID(), geo::PlaneID::Plane, reco::ClusterHit3D::setPosition(), reco::ClusterHit2D::setStatusBit(), reco::ClusterHit3D::setWireID(), reco::ClusterHit2D::SHAREDINTRIPLET, geo::TPCID::TPC, reco::ClusterHit2D::USEDINTRIPLET, geo::WireID::Wire, reco::ClusterHit2D::WireID(), and geo::WireReadoutGeom::WireIDsIntersect().

Referenced by findGoodTriplets().

1256  {
1257  // Assume failure (most common result)
1258  bool result(false);
1259 
1260  const reco::ClusterHit2D* hit0 = pair.getHits()[0];
1261  const reco::ClusterHit2D* hit1 = pair.getHits()[1];
1262 
1263  size_t missPlane(2);
1264 
1265  // u plane hit is missing
1266  if (!hit0) {
1267  hit0 = pair.getHits()[2];
1268  missPlane = 0;
1269  }
1270  // v plane hit is missing
1271  else if (!hit1) {
1272  hit1 = pair.getHits()[2];
1273  missPlane = 1;
1274  }
1275 
1276  // Which plane is missing?
1277  geo::WireID wireID0 = hit0->WireID();
1278  geo::WireID wireID1 = hit1->WireID();
1279 
1280  // Ok, recover the wireID expected in the third plane...
1281  geo::WireID wireIn(wireID0.Cryostat, wireID0.TPC, missPlane, 0);
1282  geo::WireID wireID = NearestWireID(pair.getPosition(), wireIn);
1283 
1284  // There can be a round off issue so check the next wire as well
1285  bool wireStatus = m_channelStatus[wireID.Plane][wireID.Wire] < maxChanStatus &&
1286  m_channelStatus[wireID.Plane][wireID.Wire] >= minChanStatus;
1287  bool wireOneStatus = m_channelStatus[wireID.Plane][wireID.Wire + 1] < maxChanStatus &&
1288  m_channelStatus[wireID.Plane][wireID.Wire + 1] >= minChanStatus;
1289 
1290  // Make sure they are of at least the minimum status
1291  if (wireStatus || wireOneStatus) {
1292  // Sort out which is the wire we're dealing with
1293  if (!wireStatus) wireID.Wire += 1;
1294 
1295  // Want to refine position since we "know" the missing wire
1296  if (auto widIntersect0 = m_wireReadoutGeom->WireIDsIntersect(wireID0, wireID)) {
1297  if (auto widIntersect1 = m_wireReadoutGeom->WireIDsIntersect(wireID1, wireID)) {
1298  Eigen::Vector3f newPosition(
1299  pair.getPosition()[0], pair.getPosition()[1], pair.getPosition()[2]);
1300 
1301  newPosition[1] = (newPosition[1] + widIntersect0->y + widIntersect1->y) / 3.;
1302  newPosition[2] =
1303  (newPosition[2] + widIntersect0->z + widIntersect1->z - 2. * m_zPosOffset) / 3.;
1304 
1305  pairOut = pair;
1306  pairOut.setWireID(wireID);
1307  pairOut.setPosition(newPosition);
1308 
1313 
1316 
1317  result = true;
1318  }
1319  }
1320  }
1321 
1322  return result;
1323  }
void setWireID(const geo::WireID &wid) const
Definition: Cluster3D.cxx:191
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
const geo::WireID & WireID() const
Definition: Cluster3D.h:76
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
geo::WireID NearestWireID(const Eigen::Vector3f &position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
const geo::WireReadoutGeom * m_wireReadoutGeom
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:168
void setPosition(const Eigen::Vector3f &pos) const
Definition: Cluster3D.h:183
unsigned getStatusBits() const
Definition: Cluster3D.h:71
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:79
bool lar_cluster3d::StandardHit3DBuilder::makeHitPair ( reco::ClusterHit3D pairOut,
const reco::ClusterHit2D hit1,
const reco::ClusterHit2D hit2,
float  hitWidthSclFctr = 1.,
size_t  hitPairCntr = 0 
) const
private

Make a HitPair object by checking two hits.

Definition at line 853 of file StandardHit3DBuilder_tool.cc.

References geo::CryostatID::Cryostat, recob::Hit::DegreesOfFreedom(), recob::Hit::EndTick(), reco::ClusterHit2D::getHit(), reco::ClusterHit2D::getStatusBits(), reco::ClusterHit2D::getTimeTicks(), reco::ClusterHit2D::getXPosition(), reco::ClusterHit3D::initialize(), recob::Hit::Integral(), m_deltaPeakTimeSig, m_wireReadoutGeom, m_zPosOffset, geo::PlaneID::Plane, recob::Hit::RMS(), reco::ClusterHit2D::setStatusBit(), reco::ClusterHit2D::SHAREDINPAIR, recob::Hit::StartTick(), geo::TPCID::TPC, reco::ClusterHit2D::USEDINPAIR, reco::ClusterHit2D::WireID(), and geo::WireReadoutGeom::WireIDsIntersect().

Referenced by findGoodHitPairs(), and makeHitTriplet().

858  {
859  // Assume failure
860  bool result(false);
861 
862  // We assume in this routine that we are looking at hits in different views
863  // The first mission is to check that the wires intersect
864  const geo::WireID& hit1WireID = hit1->WireID();
865  const geo::WireID& hit2WireID = hit2->WireID();
866 
867  if (auto widIntersect = m_wireReadoutGeom->WireIDsIntersect(hit1WireID, hit2WireID)) {
868  // Wires intersect so now we can check the timing
869  float hit1Peak = hit1->getTimeTicks();
870  float hit1Sigma = hit1->getHit()->RMS();
871 
872  float hit2Peak = hit2->getTimeTicks();
873  float hit2Sigma = hit2->getHit()->RMS();
874 
875  // "Long hits" are an issue... so we deal with these differently
876  int hit1NDF = hit1->getHit()->DegreesOfFreedom();
877  int hit2NDF = hit2->getHit()->DegreesOfFreedom();
878 
879  // Basically, allow the range to extend to the nearest end of the snippet
880  if (hit1NDF < 2)
881  hit1Sigma = std::min(hit1Peak - float(hit1->getHit()->StartTick()),
882  float(hit1->getHit()->EndTick()) - hit1Peak);
883  if (hit2NDF < 2)
884  hit2Sigma = std::min(hit2Peak - float(hit2->getHit()->StartTick()),
885  float(hit2->getHit()->EndTick()) - hit2Peak);
886 
887  // The "hit sigma" is the gaussian fit sigma of the hit, we need to expand a bit to allow hit overlap efficiency
888  float hit1Width = hitWidthSclFctr * hit1Sigma;
889  float hit2Width = hitWidthSclFctr * hit2Sigma;
890 
891  // Coarse check hit times are "in range"
892  if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width)) {
893  // Check to see that hit peak times are consistent with each other
894  float hit1SigSq = hit1Sigma * hit1Sigma;
895  float hit2SigSq = hit2Sigma * hit2Sigma;
896  float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
897  float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
898 
899  // delta peak time consistency check here
900  if (deltaPeakTime < m_deltaPeakTimeSig *
901  sigmaPeakTime) // 2 sigma consistency? (do this way to avoid divide)
902  {
903  float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
904  float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
905  float totalCharge = hit1->getHit()->Integral() + hit2->getHit()->Integral();
906  float hitChiSquare = std::pow((hit1Peak - avePeakTime), 2) / hit1SigSq +
907  std::pow((hit2Peak - avePeakTime), 2) / hit2SigSq;
908 
909  float xPositionHit1(hit1->getXPosition());
910  float xPositionHit2(hit2->getXPosition());
911  float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq *
912  hit2SigSq / (hit1SigSq + hit2SigSq);
913 
914  Eigen::Vector3f position(
915  xPosition, float(widIntersect->y), float(widIntersect->z) - m_zPosOffset);
916 
917  // If to here then we need to sort out the hit pair code telling what views are used
918  unsigned statusBits = 1 << hit1->WireID().Plane | 1 << hit2->WireID().Plane;
919 
920  // handle status bits for the 2D hits
925 
928 
929  reco::ClusterHit2DVec hitVector;
930 
931  hitVector.resize(3, NULL);
932 
933  hitVector[hit1->WireID().Plane] = hit1;
934  hitVector[hit2->WireID().Plane] = hit2;
935 
936  unsigned int cryostatIdx = hit1->WireID().Cryostat;
937  unsigned int tpcIdx = hit1->WireID().TPC;
938 
939  // Initialize the wireIdVec
940  std::vector<geo::WireID> wireIDVec = {geo::WireID(cryostatIdx, tpcIdx, 0, 0),
941  geo::WireID(cryostatIdx, tpcIdx, 1, 0),
942  geo::WireID(cryostatIdx, tpcIdx, 2, 0)};
943 
944  wireIDVec[hit1->WireID().Plane] = hit1->WireID();
945  wireIDVec[hit2->WireID().Plane] = hit2->WireID();
946 
947  // For compiling at the moment
948  std::vector<float> hitDelTSigVec = {0., 0., 0.};
949 
950  hitDelTSigVec[hit1->WireID().Plane] = deltaPeakTime / sigmaPeakTime;
951  hitDelTSigVec[hit2->WireID().Plane] = deltaPeakTime / sigmaPeakTime;
952 
953  // Create the 3D cluster hit
954  hitPair.initialize(hitPairCntr,
955  statusBits,
956  position,
957  totalCharge,
958  avePeakTime,
959  deltaPeakTime,
960  sigmaPeakTime,
961  hitChiSquare,
962  0.,
963  0.,
964  0.,
965  0.,
966  hitVector,
967  hitDelTSigVec,
968  wireIDVec);
969 
970  result = true;
971  }
972  }
973  }
974 
975  // Send it back
976  return result;
977  }
float getTimeTicks() const
Definition: Cluster3D.h:75
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:234
const geo::WireID & WireID() const
Definition: Cluster3D.h:76
int DegreesOfFreedom() const
Initial tdc tick for hit.
Definition: Hit.h:274
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:254
const recob::Hit * getHit() const
Definition: Cluster3D.h:77
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
const geo::WireReadoutGeom * m_wireReadoutGeom
float getXPosition() const
Definition: Cluster3D.h:74
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:218
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:90
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:222
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
unsigned getStatusBits() const
Definition: Cluster3D.h:71
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:79
bool lar_cluster3d::StandardHit3DBuilder::makeHitTriplet ( reco::ClusterHit3D pairOut,
const reco::ClusterHit3D pairIn,
const reco::ClusterHit2D hit2 
) const
private

Make a 3D HitPair object by checking two hits.

Definition at line 979 of file StandardHit3DBuilder_tool.cc.

References util::abs(), chargeIntegral(), geo::CryostatID::Cryostat, recob::Hit::DegreesOfFreedom(), DistanceFromPointToHitWire(), recob::Hit::EndTick(), reco::ClusterHit3D::getAvePeakTime(), reco::ClusterHit2D::getHit(), reco::ClusterHit3D::getHits(), reco::ClusterHit3D::getPosition(), reco::ClusterHit3D::getSigmaPeakTime(), reco::ClusterHit2D::getStatusBits(), reco::ClusterHit2D::getTimeTicks(), reco::ClusterHit2D::getXPosition(), reco::ClusterHit3D::initialize(), m_chiSquare3DVec, m_deltaTimeVec, m_hitAsymmetryVec, m_hitWidthSclFctr, m_maxDeltaPeakVec, m_maxPullVec, m_maxSideVecVec, m_outputHistograms, m_overlapFractionVec, m_overlapRangeVec, m_pairWireDistVec, m_qualityMetricVec, m_smallChargeDiffVec, m_smallIndexVec, m_spacePointChargeVec, m_wirePitch, m_wirePitchScaleFactor, makeHitPair(), recob::Hit::PeakAmplitude(), geo::PlaneID::Plane, recob::Hit::RMS(), reco::ClusterHit2D::setStatusBit(), reco::ClusterHit2D::SHAREDINTRIPLET, recob::Hit::StartTick(), geo::TPCID::TPC, reco::ClusterHit2D::USEDINTRIPLET, weight, geo::WireID::Wire, reco::ClusterHit2D::WireID(), and geo::WireID::WireID().

Referenced by findGoodTriplets().

982  {
983  // Assume failure
984  bool result(false);
985 
986  // We are going to force the wire pitch here, some time in the future we need to fix
987  static const double wirePitch =
988  0.5 * m_wirePitchScaleFactor * *std::max_element(m_wirePitch, m_wirePitch + 3);
989 
990  // Recover hit info
991  float hitTimeTicks = hit->getTimeTicks();
992  float hitSigma = hit->getHit()->RMS();
993 
994  // Special case check
995  if (hitSigma > 2. * hit->getHit()->PeakAmplitude())
996  hitSigma = 2. * hit->getHit()->PeakAmplitude();
997 
998  // Let's do a quick consistency check on the input hits to make sure we are in range...
999  // Require the W hit to be "in range" with the UV Pair
1000  if (fabs(hitTimeTicks - pair.getAvePeakTime()) <
1001  m_hitWidthSclFctr * (pair.getSigmaPeakTime() + hitSigma)) {
1002  // Check the distance from the point to the wire the hit is on
1003  float hitWireDist = DistanceFromPointToHitWire(pair.getPosition(), hit->WireID());
1004 
1005  if (m_outputHistograms) m_maxSideVecVec.push_back(hitWireDist);
1006 
1007  // Reject hits that are not within range
1008  if (hitWireDist < wirePitch) {
1009  if (m_outputHistograms) m_pairWireDistVec.push_back(hitWireDist);
1010 
1011  // Use the existing code to see the U and W hits are willing to pair with the V hit
1012  reco::ClusterHit3D pair0h;
1013  reco::ClusterHit3D pair1h;
1014 
1015  // Recover all the hits involved
1016  const reco::ClusterHit2DVec& pairHitVec = pair.getHits();
1017  const reco::ClusterHit2D* hit0 = pairHitVec[0];
1018  const reco::ClusterHit2D* hit1 = pairHitVec[1];
1019 
1020  if (!hit0)
1021  hit0 = pairHitVec[2];
1022  else if (!hit1)
1023  hit1 = pairHitVec[2];
1024 
1025  // If good pairs made here then we can try to make a triplet
1026  if (makeHitPair(pair0h, hit0, hit, m_hitWidthSclFctr) &&
1027  makeHitPair(pair1h, hit1, hit, m_hitWidthSclFctr)) {
1028  // Get a copy of the input hit vector (note the order is by plane - by definition)
1029  reco::ClusterHit2DVec hitVector = pair.getHits();
1030 
1031  // include the new hit
1032  hitVector[hit->WireID().Plane] = hit;
1033 
1034  // Set up to get average peak time, hitChiSquare, etc.
1035  unsigned int statusBits(0x7);
1036  float avePeakTime(0.);
1037  float weightSum(0.);
1038  float xPosition(0.);
1039 
1040  // And get the wire IDs
1041  std::vector<geo::WireID> wireIDVec = {geo::WireID(), geo::WireID(), geo::WireID()};
1042 
1043  // First loop through the hits to get WireIDs and calculate the averages
1044  for (size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
1045  const reco::ClusterHit2D* hit2D = hitVector[planeIdx];
1046 
1047  wireIDVec[planeIdx] = hit2D->WireID();
1048 
1051 
1053 
1054  float hitRMS = hit2D->getHit()->RMS();
1055  float peakTime = hit2D->getTimeTicks();
1056 
1057  // Basically, allow the range to extend to the nearest end of the snippet
1058  if (hit2D->getHit()->DegreesOfFreedom() < 2)
1059  hitRMS = std::min(hit2D->getTimeTicks() - float(hit2D->getHit()->StartTick()),
1060  float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1061 
1062  float weight = 1. / (hitRMS * hitRMS);
1063 
1064  avePeakTime += peakTime * weight;
1065  xPosition += hit2D->getXPosition() * weight;
1066  weightSum += weight;
1067  }
1068 
1069  avePeakTime /= weightSum;
1070  xPosition /= weightSum;
1071 
1072  Eigen::Vector2f pair0hYZVec(pair0h.getPosition()[1], pair0h.getPosition()[2]);
1073  Eigen::Vector2f pair1hYZVec(pair1h.getPosition()[1], pair1h.getPosition()[2]);
1074  Eigen::Vector2f pairYZVec(pair.getPosition()[1], pair.getPosition()[2]);
1075  Eigen::Vector3f position(xPosition,
1076  float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1077  float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1078 
1079  // Armed with the average peak time, now get hitChiSquare and the sig vec
1080  float hitChiSquare(0.);
1081  float sigmaPeakTime(std::sqrt(1. / weightSum));
1082  std::vector<float> hitDelTSigVec;
1083 
1084  for (const auto& hit2D : hitVector) {
1085  float hitRMS = hit2D->getHit()->RMS();
1086 
1087  // Basically, allow the range to extend to the nearest end of the snippet
1088  if (hit2D->getHit()->DegreesOfFreedom() < 2)
1089  hitRMS = std::min(hit2D->getTimeTicks() - float(hit2D->getHit()->StartTick()),
1090  float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1091 
1092  float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
1093  float peakTime = hit2D->getTimeTicks();
1094  float deltaTime = peakTime - avePeakTime;
1095  float hitSig = deltaTime / combRMS;
1096 
1097  hitChiSquare += hitSig * hitSig;
1098 
1099  hitDelTSigVec.emplace_back(std::fabs(hitSig));
1100  }
1101 
1102  if (m_outputHistograms) m_chiSquare3DVec.push_back(hitChiSquare);
1103 
1104  int lowMinIndex(std::numeric_limits<int>::max());
1105  int lowMaxIndex(std::numeric_limits<int>::min());
1106  int hiMinIndex(std::numeric_limits<int>::max());
1107  int hiMaxIndex(std::numeric_limits<int>::min());
1108 
1109  // First task is to get the min/max values for the common overlap region
1110  for (const auto& hit2D : hitVector) {
1111  float range = 2. * hit2D->getHit()->RMS();
1112 
1113  // Basically, allow the range to extend to the nearest end of the snippet
1114  if (hit2D->getHit()->DegreesOfFreedom() < 2)
1115  range = std::min(hit2D->getTimeTicks() - float(hit2D->getHit()->StartTick()),
1116  float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1117 
1118  int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1119  int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1120 
1121  lowMinIndex = std::min(hitStart, lowMinIndex);
1122  lowMaxIndex = std::max(hitStart, lowMaxIndex);
1123  hiMinIndex = std::min(hitStop + 1, hiMinIndex);
1124  hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
1125  }
1126 
1127  // Keep only "good" hits...
1128  if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
1129  // One more pass through hits to get charge
1130  std::vector<float> chargeVec;
1131 
1132  for (const auto& hit2D : hitVector)
1133  chargeVec.push_back(chargeIntegral(hit2D->getHit()->PeakTime(),
1134  hit2D->getHit()->PeakAmplitude(),
1135  hit2D->getHit()->RMS(),
1136  lowMaxIndex,
1137  hiMinIndex));
1138 
1139  float totalCharge =
1140  std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
1141  float overlapRange = float(hiMinIndex - lowMaxIndex);
1142  float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
1143 
1144  // Set up to compute the charge asymmetry
1145  std::vector<float> smallestChargeDiffVec;
1146  std::vector<float> chargeAveVec;
1147  float smallestDiff(std::numeric_limits<float>::max());
1148  float maxDeltaPeak(0.);
1149  size_t chargeIndex(0);
1150 
1151  for (size_t idx = 0; idx < 3; idx++) {
1152  size_t leftIdx = (idx + 2) % 3;
1153  size_t rightIdx = (idx + 1) % 3;
1154 
1155  smallestChargeDiffVec.push_back(std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1156  chargeAveVec.push_back(float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1157 
1158  if (smallestChargeDiffVec.back() < smallestDiff) {
1159  smallestDiff = smallestChargeDiffVec.back();
1160  chargeIndex = idx;
1161  }
1162 
1163  // Take opportunity to look at peak time diff
1164  float deltaPeakTime =
1165  hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1166 
1167  if (std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak = std::abs(deltaPeakTime);
1168 
1169  if (m_outputHistograms) m_deltaTimeVec.push_back(deltaPeakTime);
1170  }
1171 
1172  float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
1173  (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1174 
1175  // If this is true there has to be a negative charge that snuck in somehow
1176  if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
1177  const geo::WireID& hitWireID = hitVector[chargeIndex]->WireID();
1178 
1179  std::cout << "============> Charge asymmetry out of range: " << chargeAsymmetry
1180  << " <============" << std::endl;
1181  std::cout << " hit C: " << hitWireID.Cryostat << ", TPC: " << hitWireID.TPC
1182  << ", Plane: " << hitWireID.Plane << ", Wire: " << hitWireID.Wire
1183  << std::endl;
1184  std::cout << " charge: " << chargeVec[0] << ", " << chargeVec[1] << ", "
1185  << chargeVec[2] << std::endl;
1186  std::cout << " index: " << chargeIndex << ", smallest diff: " << smallestDiff
1187  << std::endl;
1188  return result;
1189  }
1190 
1191  // Usurping "deltaPeakTime" to be the maximum pull
1192  float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
1193 
1194  if (m_outputHistograms) {
1195  m_smallChargeDiffVec.push_back(smallestDiff);
1196  m_smallIndexVec.push_back(chargeIndex);
1197  m_maxPullVec.push_back(deltaPeakTime);
1198  m_qualityMetricVec.push_back(hitChiSquare);
1199  m_spacePointChargeVec.push_back(totalCharge);
1200  m_overlapFractionVec.push_back(overlapFraction);
1201  m_overlapRangeVec.push_back(overlapRange);
1202  m_maxDeltaPeakVec.push_back(maxDeltaPeak);
1203  m_hitAsymmetryVec.push_back(chargeAsymmetry);
1204  }
1205 
1206  // Try to weed out cases where overlap doesn't match peak separation
1207  if (maxDeltaPeak > overlapRange) return result;
1208 
1209  // Create the 3D cluster hit
1210  hitTriplet.initialize(0,
1211  statusBits,
1212  position,
1213  totalCharge,
1214  avePeakTime,
1215  deltaPeakTime,
1216  sigmaPeakTime,
1217  hitChiSquare,
1218  overlapFraction,
1219  chargeAsymmetry,
1220  0.,
1221  0.,
1222  hitVector,
1223  hitDelTSigVec,
1224  wireIDVec);
1225 
1226  result = true;
1227  }
1228  }
1229  }
1230  }
1231 
1232  // return success/fail
1233  return result;
1234  }
float m_wirePitchScaleFactor
Scaling factor to determine max distance allowed between candidate pairs.
float getTimeTicks() const
Definition: Cluster3D.h:75
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:155
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:234
const geo::WireID & WireID() const
Definition: Cluster3D.h:76
constexpr auto abs(T v)
Returns the absolute value of the argument.
int DegreesOfFreedom() const
Initial tdc tick for hit.
Definition: Hit.h:274
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
bool makeHitPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, float hitWidthSclFctr=1., size_t hitPairCntr=0) const
Make a HitPair object by checking two hits.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
const recob::Hit * getHit() const
Definition: Cluster3D.h:77
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:238
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
float chargeIntegral(float, float, float, int, int) const
Perform charge integration between limits.
float getXPosition() const
Definition: Cluster3D.h:74
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:218
Detector simulation of raw signals on wires.
float DistanceFromPointToHitWire(const Eigen::Vector3f &position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:90
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:222
double weight
Definition: plottest35.C:25
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:226
constexpr WireID()=default
Default constructor: an invalid TPC ID.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:315
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:168
unsigned getStatusBits() const
Definition: Cluster3D.h:71
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:79
void lar_cluster3d::StandardHit3DBuilder::makeRawDigitAssns ( const art::Event evt,
art::Assns< raw::RawDigit, recob::Hit > &  rawDigitAssns,
RecobHitToPtrMap recobHitPtrMap 
) const
private

Create raw::RawDigit to recob::Hit associations.

Definition at line 1708 of file StandardHit3DBuilder_tool.cc.

References art::Assns< L, R, D >::addSingle(), raw::RawDigit::Channel(), DEFINE_ART_CLASS_TOOL, art::Assns< L, R, D >::end(), art::ProductRetriever::getValidHandle(), and m_hitFinderTagVec.

Referenced by Hit3DBuilder().

1711  {
1712  // Let's make sure the input associations container is empty
1713  rawDigitAssns = art::Assns<raw::RawDigit, recob::Hit>();
1714 
1715  // First task is to recover all of the previous wire <--> hit associations and map them by channel number
1716  // Create the temporary container
1717  std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1718 
1719  // Go through the list of input sources and fill out the map
1720  for (const auto& inputTag : m_hitFinderTagVec) {
1722  evt.getValidHandle<std::vector<recob::Hit>>(inputTag);
1723 
1724  art::FindOneP<raw::RawDigit> hitToRawDigitAssns(hitHandle, evt, inputTag);
1725 
1726  if (hitToRawDigitAssns.isValid()) {
1727  for (size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++) {
1728  art::Ptr<raw::RawDigit> rawDigit = hitToRawDigitAssns.at(rawDigitIdx);
1729 
1730  channelToRawDigitMap[rawDigit->Channel()] = rawDigit;
1731  }
1732  }
1733  }
1734 
1735  // Now fill the container
1736  for (const auto& hitPtrPair : recobHitPtrMap) {
1737  raw::ChannelID_t channel = hitPtrPair.first->Channel();
1738 
1739  std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>::iterator chanRawDigitItr =
1740  channelToRawDigitMap.find(channel);
1741 
1742  if (!(chanRawDigitItr != channelToRawDigitMap.end())) {
1743  mf::LogDebug("Cluster3D") << "** Did not find channel to wire match! Skipping..."
1744  << std::endl;
1745  continue;
1746  }
1747 
1748  rawDigitAssns.addSingle(chanRawDigitItr->second, hitPtrPair.second);
1749  }
1750 
1751  return;
1752  }
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:213
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
const_iterator end() const
Definition: Assns.h:514
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:549
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
void lar_cluster3d::StandardHit3DBuilder::makeWireAssns ( const art::Event evt,
art::Assns< recob::Wire, recob::Hit > &  wireAssns,
RecobHitToPtrMap recobHitPtrMap 
) const
private

Create recob::Wire to recob::Hit associations.

Definition at line 1662 of file StandardHit3DBuilder_tool.cc.

References art::Assns< L, R, D >::addSingle(), recob::Wire::Channel(), art::Assns< L, R, D >::end(), art::ProductRetriever::getValidHandle(), and m_hitFinderTagVec.

Referenced by Hit3DBuilder().

1665  {
1666  // Let's make sure the input associations container is empty
1668 
1669  // First task is to recover all of the previous wire <--> hit associations and map them by channel number
1670  // Create the temporary container
1671  std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1672 
1673  // Go through the list of input sources and fill out the map
1674  for (const auto& inputTag : m_hitFinderTagVec) {
1676  evt.getValidHandle<std::vector<recob::Hit>>(inputTag);
1677 
1678  art::FindOneP<recob::Wire> hitToWireAssns(hitHandle, evt, inputTag);
1679 
1680  if (hitToWireAssns.isValid()) {
1681  for (size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++) {
1682  art::Ptr<recob::Wire> wire = hitToWireAssns.at(wireIdx);
1683 
1684  channelToWireMap[wire->Channel()] = wire;
1685  }
1686  }
1687  }
1688 
1689  // Now fill the container
1690  for (const auto& hitPtrPair : recobHitPtrMap) {
1691  raw::ChannelID_t channel = hitPtrPair.first->Channel();
1692 
1693  std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>::iterator chanWireItr =
1694  channelToWireMap.find(channel);
1695 
1696  if (!(chanWireItr != channelToWireMap.end())) {
1697  mf::LogDebug("Cluster3D") << "** Did not find channel to wire match! Skipping..."
1698  << std::endl;
1699  continue;
1700  }
1701 
1702  wireAssns.addSingle(chanWireItr->second, hitPtrPair.second);
1703  }
1704 
1705  return;
1706  }
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:223
const_iterator end() const
Definition: Assns.h:514
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:549
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Definition: fwd.h:26
geo::WireID lar_cluster3d::StandardHit3DBuilder::NearestWireID ( const Eigen::Vector3f &  position,
const geo::WireID wireID 
) const
private

Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range.

Definition at line 1380 of file StandardHit3DBuilder_tool.cc.

References geo::WireID::asPlaneID(), geo::TPCGeo::Length(), m_geometry, m_wireReadoutGeom, geo::WireReadoutGeom::Nwires(), geo::WireReadoutGeom::Plane(), geo::vect::toPoint(), geo::GeometryCore::TPC(), geo::WireID::Wire, and geo::PlaneGeo::WireCoordinate().

Referenced by makeDeadChannelPair().

1382  {
1383  geo::WireID wireID = wireIDIn;
1384 
1385  // Embed the call to the geometry's services nearest wire id method in a try-catch block
1386  try {
1387  // Switch from NearestWireID to this method to avoid the roundoff error issues...
1388  double distanceToWire =
1389  m_wireReadoutGeom->Plane(wireIDIn).WireCoordinate(geo::vect::toPoint(position.data()));
1390 
1391  wireID.Wire = int(distanceToWire);
1392  }
1393  catch (std::exception& exc) {
1394  // This can happen, almost always because the coordinates are **just** out of range
1395  mf::LogWarning("Cluster3D") << "Exception caught finding nearest wire, position - "
1396  << exc.what() << std::endl;
1397 
1398  // Assume extremum for wire number depending on z coordinate
1399  if (position[2] < 0.5 * m_geometry->TPC().Length())
1400  wireID.Wire = 0;
1401  else
1402  wireID.Wire = m_wireReadoutGeom->Nwires(wireIDIn.asPlaneID()) - 1;
1403  }
1404 
1405  return wireID;
1406  }
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:704
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
double Length() const
Length is associated with z coordinate [cm].
Definition: TPCGeo.h:110
const geo::WireReadoutGeom * m_wireReadoutGeom
Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:448
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_cluster3d::StandardHit3DBuilder::produces ( art::ProducesCollector collector)
overridevirtual

Each algorithm may have different objects it wants "produced" so use this to let the top level producer module "know" what it is outputting.

Implements lar_cluster3d::IHit3DBuilder.

Definition at line 347 of file StandardHit3DBuilder_tool.cc.

References art::ProducesCollector::produces().

348  {
349  collector.produces<std::vector<recob::Hit>>();
352  }
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)

Member Data Documentation

const lariov::ChannelStatusProvider* lar_cluster3d::StandardHit3DBuilder::m_channelFilter
private

Definition at line 292 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec(), and StandardHit3DBuilder().

ChannelStatusByPlaneVec lar_cluster3d::StandardHit3DBuilder::m_channelStatus
mutableprivate

Definition at line 285 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec(), and makeDeadChannelPair().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_chiSquare3DVec
mutableprivate

Definition at line 267 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

Hit2DList lar_cluster3d::StandardHit3DBuilder::m_clusterHit2DMasterList
mutableprivate
float lar_cluster3d::StandardHit3DBuilder::m_deltaPeakTimeSig
private
std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_deltaTimeVec
mutableprivate

Definition at line 266 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

bool lar_cluster3d::StandardHit3DBuilder::m_enableMonitoring
private
const geo::Geometry* lar_cluster3d::StandardHit3DBuilder::m_geometry
private
std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_hitAsymmetryVec
mutableprivate

Definition at line 278 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<art::InputTag> lar_cluster3d::StandardHit3DBuilder::m_hitFinderTagVec
private

Data members to follow.

Definition at line 247 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), makeRawDigitAssns(), makeWireAssns(), and StandardHit3DBuilder().

float lar_cluster3d::StandardHit3DBuilder::m_hitWidthSclFctr
private
std::vector<int> lar_cluster3d::StandardHit3DBuilder::m_invalidTPCVec
private

Definition at line 251 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_maxDeltaPeakVec
mutableprivate

Definition at line 271 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

float lar_cluster3d::StandardHit3DBuilder::m_maxHit3DChiSquare
private

Provide ability to select hits based on "chi square".

Definition at line 254 of file StandardHit3DBuilder_tool.cc.

Referenced by StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_maxPullVec
mutableprivate

Definition at line 268 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_maxSideVecVec
mutableprivate

Definition at line 272 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

size_t lar_cluster3d::StandardHit3DBuilder::m_numBadChannels
mutableprivate

Definition at line 286 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec(), and findGoodTriplets().

float lar_cluster3d::StandardHit3DBuilder::m_numSigmaPeakTime
private
bool lar_cluster3d::StandardHit3DBuilder::m_outputHistograms
private

Take the time to create and fill some histograms for diagnostics.

Definition at line 255 of file StandardHit3DBuilder_tool.cc.

Referenced by Hit3DBuilder(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_overlapFractionVec
mutableprivate

Definition at line 269 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_overlapRangeVec
mutableprivate

Definition at line 270 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_pairWireDistVec
mutableprivate

Definition at line 273 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

PlaneToHitVectorMap lar_cluster3d::StandardHit3DBuilder::m_planeToHitVectorMap
mutableprivate

Definition at line 282 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildHit3D(), CollectArtHits(), and Hit3DBuilder().

PlaneToWireToHitSetMap lar_cluster3d::StandardHit3DBuilder::m_planeToWireToHitSetMap
mutableprivate

Definition at line 283 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), and Hit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_qualityMetricVec
mutableprivate

Definition at line 276 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_smallChargeDiffVec
mutableprivate

Definition at line 274 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<int> lar_cluster3d::StandardHit3DBuilder::m_smallIndexVec
mutableprivate

Definition at line 275 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_spacePointChargeVec
mutableprivate

Definition at line 277 of file StandardHit3DBuilder_tool.cc.

Referenced by clear(), makeHitTriplet(), and StandardHit3DBuilder().

std::vector<float> lar_cluster3d::StandardHit3DBuilder::m_timeVector
mutableprivate
TTree* lar_cluster3d::StandardHit3DBuilder::m_tupleTree
private

output analysis tree

Definition at line 264 of file StandardHit3DBuilder_tool.cc.

Referenced by Hit3DBuilder(), and StandardHit3DBuilder().

bool lar_cluster3d::StandardHit3DBuilder::m_weHaveAllBeenHereBefore = false
mutableprivate

Definition at line 288 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits().

float lar_cluster3d::StandardHit3DBuilder::m_wirePitch[3]
private

Definition at line 258 of file StandardHit3DBuilder_tool.cc.

Referenced by makeHitTriplet(), and StandardHit3DBuilder().

float lar_cluster3d::StandardHit3DBuilder::m_wirePitchScaleFactor
private

Scaling factor to determine max distance allowed between candidate pairs.

Definition at line 253 of file StandardHit3DBuilder_tool.cc.

Referenced by makeHitTriplet(), and StandardHit3DBuilder().

const geo::WireReadoutGeom* lar_cluster3d::StandardHit3DBuilder::m_wireReadoutGeom
private
float lar_cluster3d::StandardHit3DBuilder::m_zPosOffset
private

The documentation for this class was generated from the following file: