LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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, NUMTIMEVALUES }
 enumerate the possible values for time checking if monitoring timing More...
 
using RecobHitToPtrMap = std::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...
 
 ~StandardHit3DBuilder ()
 Destructor. More...
 
void configure (const fhicl::ParameterSet &) override
 Interface for configuring the particular algorithm tool. More...
 
void Hit3DBuilder (const art::Event &evt, reco::HitPairList &hitPairList, RecobHitToPtrMap &) const 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, RecobHitToPtrMap &hitToPtrMap) 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...
 
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 &, bool=false) 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=4, size_t minStatus=0, float minOverlap=0.2) 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 float *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 (PlaneToWireToHitSetMap &planeToWiretoHitSetMap) const
 Create the internal channel status vector (assume will eventually be event-by-event) More...
 

Private Attributes

art::InputTag m_hitFinderTag
 Data members to follow. More...
 
float m_numSigmaPeakTime
 
float m_hitWidthSclFctr
 
float m_deltaPeakTimeSig
 
bool m_enableMonitoring
 
float m_wirePitch [3]
 
std::vector< float > m_timeVector
 
float m_zPosOffset
 
Hit2DVector m_clusterHit2DMasterVec
 
PlaneToHitVectorMap m_planeToHitVectorMap
 
PlaneToWireToHitSetMap m_planeToWireToHitSetMap
 
ChannelStatusByPlaneVec m_channelStatus
 
size_t m_numBadChannels
 
geo::Geometrym_geometry
 
const detinfo::DetectorPropertiesm_detector
 
const lariov::ChannelStatusProvider * m_channelFilter
 

Detailed Description

StandardHit3DBuilder class definiton.

Definition at line 64 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 183 of file StandardHit3DBuilder_tool.cc.

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

Definition at line 128 of file StandardHit3DBuilder_tool.cc.

Given the ClusterHit2D objects, build the HitPairMap.

Definition at line 121 of file StandardHit3DBuilder_tool.cc.

Defines a structure mapping art representation to internal.

Definition at line 44 of file IHit3DBuilder.h.

Member Enumeration Documentation

enumerate the possible values for time checking if monitoring timing

Enumerator
COLLECTARTHITS 
BUILDTHREEDHITS 
NUMTIMEVALUES 

Definition at line 57 of file IHit3DBuilder.h.

Constructor & Destructor Documentation

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

Constructor.

Parameters
pset

Definition at line 214 of file StandardHit3DBuilder_tool.cc.

References configure().

214  :
216 
217 {
218  this->configure(pset);
219 }
const lariov::ChannelStatusProvider * m_channelFilter
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
lar_cluster3d::StandardHit3DBuilder::~StandardHit3DBuilder ( )

Destructor.

Definition at line 223 of file StandardHit3DBuilder_tool.cc.

224 {
225 }

Member Function Documentation

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

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

Definition at line 248 of file StandardHit3DBuilder_tool.cc.

References geo::GeometryCore::ChannelToWire(), m_channelFilter, m_channelStatus, m_geometry, m_numBadChannels, geo::GeometryCore::Nchannels(), geo::GeometryCore::Nplanes(), geo::GeometryCore::Nwires(), geo::PlaneID::Plane, and geo::WireID::Wire.

Referenced by BuildHit3D().

249 {
250  // This is called each event, clear out the previous version and start over
251  if (!m_channelStatus.empty()) m_channelStatus.clear();
252 
253  m_numBadChannels = 0;
255 
256  // Loop through views/planes to set the wire length vectors
257  for(size_t idx = 0; idx < m_channelStatus.size(); idx++)
258  {
260  }
261 
262  // Loop through the channels and mark those that are "bad"
263  for(size_t channel = 0; channel < m_geometry->Nchannels(); channel++)
264  {
265  if( !m_channelFilter->IsGood(channel))
266  {
267  std::vector<geo::WireID> wireIDVec = m_geometry->ChannelToWire(channel);
268  geo::WireID wireID = wireIDVec[0];
269  lariov::ChannelStatusProvider::Status_t chanStat = m_channelFilter->Status(channel);
270 
271  m_channelStatus[wireID.Plane][wireID.Wire] = chanStat;
273  }
274  }
275 
276  // add quiet wires in U plane for microboone (this will done "correctly" in near term)
277  // PlaneToWireToHitSetMap::iterator plane0HitItr = planeToWireToHitSetMap.find(geo::PlaneID(0,0,0));
278 
279  // if (plane0HitItr != planeToWireToHitSetMap.end())
280  // {
282 
283  // for(size_t idx = 2016; idx < 2096; idx++) m_channelStatus[0][idx] = 3;
284  // for(size_t idx = 2192; idx < 2304; idx++) m_channelStatus[0][idx] = 3;
285  // for(size_t idx = 2352; idx < 2384; idx++) m_channelStatus[0][idx] = 3;
286  // //for(size_t idx = 2016; idx < 2096; idx++) if (wireToHitSetMap.find(idx) == wireToHitSetMap.end()) m_channelStatus[0][idx] = 3;
287  // //for(size_t idx = 2192; idx < 2304; idx++) if (wireToHitSetMap.find(idx) == wireToHitSetMap.end()) m_channelStatus[0][idx] = 3;
288  // //for(size_t idx = 2352; idx < 2384; idx++) if (wireToHitSetMap.find(idx) == wireToHitSetMap.end()) m_channelStatus[0][idx] = 3;
290  // }
291 
292  return;
293 }
std::vector< size_t > ChannelStatusVec
define data structure for keeping track of channel status
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
const lariov::ChannelStatusProvider * m_channelFilter
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 338 of file StandardHit3DBuilder_tool.cc.

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

Referenced by Hit3DBuilder().

339 {
344  cet::cpu_timer theClockMakeHits;
345 
346  if (m_enableMonitoring) theClockMakeHits.start();
347 
348  // The first task is to take the lists of input 2D hits (a map of view to sorted lists of 2D hits)
349  // and then to build a list of 3D hits to be used in downstream processing
351 
352  size_t numHitPairs = BuildHitPairMap(m_planeToHitVectorMap, hitPairList);
353 
354  if (m_enableMonitoring)
355  {
356  theClockMakeHits.stop();
357 
358  m_timeVector[BUILDTHREEDHITS] = theClockMakeHits.accumulated_real_time();
359  }
360 
361  mf::LogDebug("Cluster3D") << ">>>>> 3D hit building done, found " << numHitPairs << " 3D Hits" << std::endl;
362 
363  return;
364 }
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
size_t BuildHitPairMap(PlaneToHitVectorMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
void BuildChannelStatusVec(PlaneToWireToHitSetMap &planeToWiretoHitSetMap) const
Create the internal channel status vector (assume will eventually be event-by-event) ...
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 422 of file StandardHit3DBuilder_tool.cc.

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

Referenced by BuildHit3D().

423 {
433  size_t totalNumHits(0);
434  size_t hitPairCntr(0);
435 
436  size_t nTriplets(0);
437  size_t nDeadChanHits(0);
438 
439  // Set up to loop over cryostats and tpcs...
440  for(size_t cryoIdx = 0; cryoIdx < m_geometry->Ncryostats(); cryoIdx++)
441  {
442  for(size_t tpcIdx = 0; tpcIdx < m_geometry->NTPC(); tpcIdx++)
443  {
444  PlaneToHitVectorMap::iterator mapItr0 = planeToHitVectorMap.find(geo::PlaneID(cryoIdx,tpcIdx,0));
445  PlaneToHitVectorMap::iterator mapItr1 = planeToHitVectorMap.find(geo::PlaneID(cryoIdx,tpcIdx,1));
446  PlaneToHitVectorMap::iterator mapItr2 = planeToHitVectorMap.find(geo::PlaneID(cryoIdx,tpcIdx,2));
447 
448  size_t nPlanesWithHits = (mapItr0 != planeToHitVectorMap.end() && !mapItr0->second.empty() ? 1 : 0)
449  + (mapItr1 != planeToHitVectorMap.end() && !mapItr1->second.empty() ? 1 : 0)
450  + (mapItr2 != planeToHitVectorMap.end() && !mapItr2->second.empty() ? 1 : 0);
451 
452  if (nPlanesWithHits < 2) continue;
453 
454  HitVector& hitVector0 = mapItr0->second;
455  HitVector& hitVector1 = mapItr1->second;
456  HitVector& hitVector2 = mapItr2->second;
457 
458  // We are going to resort the hits into "start time" order...
459  std::sort(hitVector0.begin(), hitVector0.end(), SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
460  std::sort(hitVector1.begin(), hitVector1.end(), SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
461  std::sort(hitVector2.begin(), hitVector2.end(), SetHitEarliestTimeOrder(m_numSigmaPeakTime)); //SetHitStartTimeOrder);
462 
463  PlaneHitVectorItrPairVec hitItrVec = {HitVectorItrPair(hitVector0.begin(),hitVector0.end()),
464  HitVectorItrPair(hitVector1.begin(),hitVector1.end()),
465  HitVectorItrPair(hitVector2.begin(),hitVector2.end())};
466 
467  totalNumHits += BuildHitPairMapByTPC(hitItrVec, hitPairList);
468  }
469  }
470 
471  // Return the hit pair list but sorted by z and y positions (faster traversal in next steps)
472  hitPairList.sort(SetPairStartTimeOrder);
473 
474  // Where are we?
475  mf::LogDebug("Cluster3D") << "Total number hits: " << totalNumHits << std::endl;
476  mf::LogDebug("Cluster3D") << "Created a total of " << hitPairList.size() << " hit pairs, counted: " << hitPairCntr << std::endl;
477  mf::LogDebug("Cluster3D") << "-- Triplets: " << nTriplets << ", dead channel pairs: " << nDeadChanHits << std::endl;
478 
479  return hitPairList.size();
480 }
intermediate_table::iterator iterator
size_t BuildHitPairMapByTPC(PlaneHitVectorItrPairVec &planeHitVectorItrPairVec, reco::HitPairList &hitPairList) const
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< reco::ClusterHit2D * > HitVector
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
std::vector< std::pair< HitVector::iterator, HitVector::iterator >> PlaneHitVectorItrPairVec
Given the ClusterHit2D objects, build the HitPairMap.
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 482 of file StandardHit3DBuilder_tool.cc.

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

Referenced by BuildHitPairMap().

483 {
494  // Define functions to set start/end iterators in the loop below
495  auto SetStartIterator = [](HitVector::iterator startItr, HitVector::iterator endItr, float rms, float startTime)
496  {
497  while(startItr != endItr)
498  {
499  float numRMS(rms);
500  if ((*startItr)->getTimeTicks() + numRMS * (*startItr)->getHit().RMS() < startTime) startItr++;
501  else break;
502  }
503  return startItr;
504  };
505 
506  auto SetEndIterator = [](HitVector::iterator firstItr, HitVector::iterator endItr, float rms, float endTime)
507  {
508  while(firstItr != endItr)
509  {
510  float numRMS(rms);
511  if ((*firstItr)->getTimeTicks() - numRMS * (*firstItr)->getHit().RMS() < endTime) firstItr++;
512  else break;
513  }
514  return firstItr;
515  };
516 
517  size_t nTriplets(0);
518  size_t nDeadChanHits(0);
519 
520  //*********************************************************************************
521  // Basically, we try to loop until done...
522  while(1)
523  {
524  // Sort so that the earliest hit time will be the first element, etc.
525  std::sort(hitItrVec.begin(),hitItrVec.end(),SetStartTimeOrder(m_numSigmaPeakTime));
526 
527  // This loop iteration's golden hit
528  const reco::ClusterHit2D* goldenHit = *hitItrVec[0].first;
529 
530  // The range of history... (for this hit)
531  float goldenTimeStart = goldenHit->getTimeTicks() - m_numSigmaPeakTime * goldenHit->getHit().RMS() - std::numeric_limits<float>::epsilon();
532  float goldenTimeEnd = goldenHit->getTimeTicks() + m_numSigmaPeakTime * goldenHit->getHit().RMS() + std::numeric_limits<float>::epsilon();
533 
534  // Set iterators to insure we'll be in the overlap ranges
535  HitVector::iterator hitItr1Start = SetStartIterator(hitItrVec[1].first, hitItrVec[1].second, m_numSigmaPeakTime, goldenTimeStart);
536  HitVector::iterator hitItr1End = SetEndIterator( hitItr1Start, hitItrVec[1].second, m_numSigmaPeakTime, goldenTimeEnd);
537  HitVector::iterator hitItr2Start = SetStartIterator(hitItrVec[2].first, hitItrVec[2].second, m_numSigmaPeakTime, goldenTimeStart);
538  HitVector::iterator hitItr2End = SetEndIterator( hitItr2Start, hitItrVec[2].second, m_numSigmaPeakTime, goldenTimeEnd);
539 
540  // Since we'll use these many times in the internal loops, pre make the pairs for the second set of hits
541  size_t curHitListSize(hitPairList.size());
542  HitMatchPairVecMap pair12Map;
543  HitMatchPairVecMap pair13Map;
544 
545  size_t n12Pairs = findGoodHitPairs(goldenHit, hitItr1Start, hitItr1End, pair12Map);
546  size_t n13Pairs = findGoodHitPairs(goldenHit, hitItr2Start, hitItr2End, pair13Map);
547 
548  nDeadChanHits += hitPairList.size() - curHitListSize;
549  curHitListSize = hitPairList.size();
550 
551  if (n12Pairs > n13Pairs) findGoodTriplets(pair12Map, pair13Map, hitPairList);
552  else findGoodTriplets(pair13Map, pair12Map, hitPairList);
553 
554  nTriplets += hitPairList.size() - curHitListSize;
555 
556  hitItrVec[0].first++;
557 
558  int nPlanesWithHits(0);
559 
560  for(auto& pair : hitItrVec)
561  if (pair.first != pair.second) nPlanesWithHits++;
562 
563  if (nPlanesWithHits < 2) break;
564  }
565 
566  return hitPairList.size();
567 }
float getTimeTicks() const
Definition: Cluster3D.h:72
intermediate_table::iterator iterator
int findGoodHitPairs(const reco::ClusterHit2D *, HitVector::iterator &, HitVector::iterator &, HitMatchPairVecMap &) const
void findGoodTriplets(HitMatchPairVecMap &, HitMatchPairVecMap &, reco::HitPairList &, bool=false) const
This algorithm takes lists of hit pairs and finds good triplets.
std::map< geo::WireID, HitMatchPairVec > HitMatchPairVecMap
void lar_cluster3d::StandardHit3DBuilder::CollectArtHits ( const art::Event evt,
RecobHitToPtrMap hitToPtrMap 
) const
private

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

Parameters
evtthe ART event
hit2DVectorA container for the internal Cluster3D 2D hit objects
PlaneToHitVectorMapA map between view and the internal Cluster3D 2D hit objects
viewToWireToHitSetMapThis maps 2D hits to wires and stores by view
hitToPtrMapThis maps our Cluster2D hits back to art Ptr's to reco Hits

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

Definition at line 1161 of file StandardHit3DBuilder_tool.cc.

References lar_cluster3d::IHit3DBuilder::COLLECTARTHITS, detinfo::DetectorProperties::ConvertTicksToX(), DEFINE_ART_CLASS_TOOL, art::Ptr< T >::get(), art::DataViewImpl::getByLabel(), detinfo::DetectorProperties::GetXTicksOffset(), art::Handle< T >::isValid(), m_clusterHit2DMasterVec, m_detector, m_enableMonitoring, m_geometry, m_hitFinderTag, m_planeToHitVectorMap, m_planeToWireToHitSetMap, m_timeVector, geo::GeometryCore::Ncryostats(), geo::GeometryCore::NTPC(), recob::Hit::PeakTime(), geo::WireID::planeID(), lar_cluster3d::SetHitTimeOrder(), detinfo::DetectorProperties::TriggerOffset(), geo::WireID::Wire, and recob::Hit::WireID().

Referenced by Hit3DBuilder().

1163 {
1167  art::Handle< std::vector<recob::Hit> > recobHitHandle;
1168  evt.getByLabel(m_hitFinderTag, recobHitHandle);
1169 
1170  if (!recobHitHandle.isValid()) return;
1171 
1172  cet::cpu_timer theClockMakeHits;
1173 
1174  if (m_enableMonitoring) theClockMakeHits.start();
1175 
1176  // We'll want to correct the hit times for the plane offsets
1177  // (note this is already taken care of when converting to position)
1178  std::map<geo::PlaneID, double> planeOffsetMap;
1179 
1180  // Reserve memory for the hit vector
1181  m_clusterHit2DMasterVec.reserve(recobHitHandle->size());
1182 
1183  // Initialize the plane to hit vector map
1184  for(size_t cryoIdx = 0; cryoIdx < m_geometry->Ncryostats(); cryoIdx++)
1185  {
1186  for(size_t tpcIdx = 0; tpcIdx < m_geometry->NTPC(); tpcIdx++)
1187  {
1188  m_planeToHitVectorMap[geo::PlaneID(cryoIdx,tpcIdx,0)] = HitVector();
1189  m_planeToHitVectorMap[geo::PlaneID(cryoIdx,tpcIdx,1)] = HitVector();
1190  m_planeToHitVectorMap[geo::PlaneID(cryoIdx,tpcIdx,2)] = HitVector();
1191 
1192  // What we want here are the relative offsets between the planes
1193  // Note that plane 0 is assumed the "first" plane and is the reference
1194  planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,0)] = 0.;
1195  planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,1)] = m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,1))
1196  - m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,0));
1197  planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,2)] = m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,2))
1198  - m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,0));
1199 
1200  std::cout << "***> plane 0 offset: " << planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,0)] << ", plane 1: " << planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,1)] << ", plane 2: " << planeOffsetMap[geo::PlaneID(cryoIdx,tpcIdx,2)] << std::endl;
1201  std::cout << " Det prop plane 0: " << m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,0)) << ", plane 1: " << m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,1)) << ", plane 2: " << m_detector->GetXTicksOffset(geo::PlaneID(cryoIdx,tpcIdx,2)) << ", Trig: " << m_detector->TriggerOffset() << std::endl;
1202  }
1203  }
1204 
1205  // Cycle through the recob hits to build ClusterHit2D objects and insert
1206  // them into the map
1207  for (size_t cIdx = 0; cIdx < recobHitHandle->size(); cIdx++)
1208  {
1209  art::Ptr<recob::Hit> recobHit(recobHitHandle, cIdx);
1210 
1211  // Skip junk hits
1212 // if (recobHit->DegreesOfFreedom() > 1 && recobHit->Multiplicity() > 1 && (recobHit->RMS() < 3.8 || recobHit->PeakAmplitude() < 10)) continue;
1213 
1214  const geo::WireID& hitWireID(recobHit->WireID());
1215 
1216  double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[recobHit->WireID().planeID()]);
1217  double xPosition(m_detector->ConvertTicksToX(recobHit->PeakTime(), hitWireID.Plane, hitWireID.TPC, hitWireID.Cryostat));
1218 
1219  m_clusterHit2DMasterVec.emplace_back(0, 0., 0., xPosition, hitPeakTime, *recobHit);
1220 
1221  m_planeToHitVectorMap[recobHit->WireID().planeID()].push_back(&m_clusterHit2DMasterVec.back());
1222  m_planeToWireToHitSetMap[recobHit->WireID().planeID()][recobHit->WireID().Wire].insert(&m_clusterHit2DMasterVec.back());
1223 
1224  const recob::Hit* recobHitPtr = recobHit.get();
1225  hitToPtrMap[recobHitPtr] = recobHit;
1226  }
1227 
1228  // Make a loop through to sort the recover hits in time order
1229  for(auto& hitVectorMap : m_planeToHitVectorMap)
1230  std::sort(hitVectorMap.second.begin(), hitVectorMap.second.end(), SetHitTimeOrder);
1231 
1232  if (m_enableMonitoring)
1233  {
1234  theClockMakeHits.stop();
1235 
1236  m_timeVector[COLLECTARTHITS] = theClockMakeHits.accumulated_real_time();
1237  }
1238 
1239  mf::LogDebug("Cluster3D") << ">>>>> Number of ART hits: " << m_clusterHit2DMasterVec.size() << std::endl;
1240 }
virtual int TriggerOffset() const =0
const detinfo::DetectorProperties * m_detector
bool SetHitTimeOrder(const reco::ClusterHit2D *left, const reco::ClusterHit2D *right)
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
art::InputTag m_hitFinderTag
Data members to follow.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< reco::ClusterHit2D * > HitVector
bool isValid() const
Definition: Handle.h:190
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
virtual double GetXTicksOffset(int p, int t, int c) const =0
void lar_cluster3d::StandardHit3DBuilder::configure ( const fhicl::ParameterSet )
overridevirtual

Interface for configuring the particular algorithm tool.

Parameters
ParameterSetThe input set of parameters for configuration

Implements lar_cluster3d::IHit3DBuilder.

Definition at line 229 of file StandardHit3DBuilder_tool.cc.

References fhicl::ParameterSet::get(), m_deltaPeakTimeSig, m_detector, m_enableMonitoring, m_geometry, m_hitFinderTag, m_hitWidthSclFctr, m_numSigmaPeakTime, m_wirePitch, m_zPosOffset, and geo::GeometryCore::WirePitch().

Referenced by StandardHit3DBuilder().

230 {
231  m_hitFinderTag = pset.get<art::InputTag>("HitFinderTag");
232  m_enableMonitoring = pset.get<bool> ("EnableMonitoring", true);
233  m_numSigmaPeakTime = pset.get<float> ("NumSigmaPeakTime", 3. );
234  m_hitWidthSclFctr = pset.get<float> ("HitWidthScaleFactor", 6. );
235  m_deltaPeakTimeSig = pset.get<float> ("DeltaPeakTimeSig", 1.7 );
236  m_zPosOffset = pset.get<float> ("ZPosOffset", 0.0 );
237 
239 
240  m_geometry = &*geometry;
241  m_detector = lar::providerFrom<detinfo::DetectorPropertiesService>();
242 
244  m_wirePitch[1] = m_geometry->WirePitch(1);
245  m_wirePitch[2] = m_geometry->WirePitch(2);
246 }
const detinfo::DetectorProperties * m_detector
art::InputTag m_hitFinderTag
Data members to follow.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
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 1071 of file StandardHit3DBuilder_tool.cc.

References reco::ClusterHit3D::getAvePeakTime().

1072 {
1073  static const float minCharge(0.);
1074 
1075  const reco::ClusterHit2D* bestVHit(0);
1076 
1077  float pairAvePeakTime(pair.getAvePeakTime());
1078 
1079  // Idea is to loop through the input set of hits and look for the best combination
1080  for (const auto& hit2D : hit2DSet)
1081  {
1082  if (hit2D->getHit().Integral() < minCharge) continue;
1083 
1084  float hitVPeakTime(hit2D->getTimeTicks());
1085  float deltaPeakTime(pairAvePeakTime-hitVPeakTime);
1086 
1087  if (deltaPeakTime > pairDeltaTimeLimits) continue;
1088 
1089  if (deltaPeakTime < -pairDeltaTimeLimits) break;
1090 
1091  pairDeltaTimeLimits = fabs(deltaPeakTime);
1092  bestVHit = hit2D;
1093  }
1094 
1095  return bestVHit;
1096 }
float getAvePeakTime() const
Definition: Cluster3D.h:152
int lar_cluster3d::StandardHit3DBuilder::findGoodHitPairs ( const reco::ClusterHit2D goldenHit,
HitVector::iterator startItr,
HitVector::iterator endItr,
HitMatchPairVecMap hitMatchMap 
) const
private

Definition at line 569 of file StandardHit3DBuilder_tool.cc.

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

Referenced by BuildHitPairMapByTPC().

573 {
574  int numPairs(0);
575 
576  // Loop through the input secon hits and make pairs
577  while(startItr != endItr)
578  {
579  reco::ClusterHit2D* hit = *startItr++;
580  reco::ClusterHit3D pair;
581 
582  // pair returned with a negative ave time is signal of failure
583  if (!makeHitPair(pair, goldenHit, hit, m_hitWidthSclFctr)) continue;
584 
585  geo::WireID wireID = hit->getHit().WireID();
586 
587  hitMatchMap[wireID].emplace_back(hit,pair);
588 
589  numPairs++;
590  }
591 
592  return numPairs;
593 }
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
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.
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
Detector simulation of raw signals on wires.
void lar_cluster3d::StandardHit3DBuilder::findGoodTriplets ( HitMatchPairVecMap pair12Map,
HitMatchPairVecMap pair13Map,
reco::HitPairList hitPairList,
bool  tagged = false 
) const
private

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

Definition at line 595 of file StandardHit3DBuilder_tool.cc.

References reco::ClusterHit3D::getPosition(), art::left(), m_deltaPeakTimeSig, m_numBadChannels, makeDeadChannelPair(), makeHitTriplet(), max, NearestWireID(), geo::PlaneID::Plane, art::right(), reco::ClusterHit3D::setID(), and geo::WireID::Wire.

Referenced by BuildHitPairMapByTPC().

596 {
597  // Build triplets from the two lists of hit pairs
598  if (!pair12Map.empty())
599  {
600  // temporary container for dead channel hits
601  std::vector<reco::ClusterHit3D> tempDeadChanVec;
602  reco::ClusterHit3D deadChanPair;
603 
604  // Keep track of which third plane hits have been used
605  std::map<const reco::ClusterHit3D*,bool> usedPairMap;
606 
607  // Initial population of this map with the pair13Map hits
608  for(const auto& pair13 : pair13Map)
609  {
610  for(const auto& hit2Dhit3DPair : pair13.second) usedPairMap[&hit2Dhit3DPair.second] = false;
611  }
612 
613  // The outer loop is over all hit pairs made from the first two plane combinations
614  for(const auto& pair12 : pair12Map)
615  {
616  if (pair12.second.empty()) continue;
617 
618  // Use the planeID for the first hit
619  geo::WireID missingPlaneID = pair12.first;
620 
621  // "Discover" the missing view (and we can't rely on assuming there are hits in the pair13Map at this point)
622  size_t missPlane = 0;
623 
624  if (!pair12.second.front().second.getHits()[1]) missPlane = 1;
625  else if (!pair12.second.front().second.getHits()[2]) missPlane = 2;
626 
627  missingPlaneID.Plane = missPlane;
628 
629  // This loop is over hit pairs that share the same first two plane wires but may have different
630  // hit times on those wires
631  for(const auto& hit2Dhit3DPair : pair12.second)
632  {
633  const reco::ClusterHit3D& pair1 = hit2Dhit3DPair.second;
634 
635  // Get the wire ID for the nearest wire to the position of this hit
636  geo::WireID wireID = NearestWireID(pair1.getPosition(), missingPlaneID);
637 
638  // populate the map with initial value
639  usedPairMap[&pair1] = false;
640 
641  // For TPC's with 60 degree wire pitch the position returned for the the pair will
642  // lie between two wires in the missing plane. The call to nearestWireID should return
643  // the lower of the pair.
644  // So we really want to do a loop here so we can consider both wire combinations
645  for(int loopIdx = 0; loopIdx < 2; loopIdx++)
646  {
647  // Now look up the hit pairs on the wire which matches the current hit pair
648  HitMatchPairVecMap::iterator thirdPlaneHitMapItr = pair13Map.find(wireID);
649 
650  // Loop over third plane hits and try to form a triplet
651  if (thirdPlaneHitMapItr != pair13Map.end())
652  {
653  for(const auto& thirdPlaneHitItr : thirdPlaneHitMapItr->second)
654  {
655  const reco::ClusterHit2D* hit2 = thirdPlaneHitItr.first;
656  const reco::ClusterHit3D& pair2 = thirdPlaneHitItr.second;
657 
658  // If success try for the triplet
659  reco::ClusterHit3D triplet;
660 
661  if (makeHitTriplet(triplet, pair1, hit2))
662  {
663  triplet.setID(hitPairList.size());
664  hitPairList.emplace_back(new reco::ClusterHit3D(triplet));
665  usedPairMap[&pair1] = true;
666  usedPairMap[&pair2] = true;
667  }
668  }
669  }
670 
671  // Now bump the wire id to the next wire and do this again
672  wireID.Wire += 1;
673  }
674  }
675  }
676 
677  // One more loop through the other pairs to check for sick channels
678  if (m_numBadChannels > 0)
679  {
680  for(const auto& pairMapPair : usedPairMap)
681  {
682  if (pairMapPair.second) continue;
683 
684  const reco::ClusterHit3D* pair = pairMapPair.first;
685 
686  // Here we look to see if we failed to make a triplet because the partner wire was dead/noisy/sick
687  if (makeDeadChannelPair(deadChanPair, *pair, 4, 0, 0.)) tempDeadChanVec.emplace_back(deadChanPair);
688  }
689 
690  // Handle the dead wire triplets
691  if(!tempDeadChanVec.empty())
692  {
693  // If we have many then see if we can trim down a bit by keeping those with time significance
694  if (tempDeadChanVec.size() > 1)
695  {
696  // Sort by "significance" of agreement
697  std::sort(tempDeadChanVec.begin(),tempDeadChanVec.end(),[](const auto& left, const auto& right){return left.getDeltaPeakTime()/left.getSigmaPeakTime() < right.getDeltaPeakTime()/right.getSigmaPeakTime();});
698 
699  // What is the range of "significance" from first to last?
700  float firstSig = tempDeadChanVec.front().getDeltaPeakTime() / tempDeadChanVec.front().getSigmaPeakTime();
701  float lastSig = tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
702  float sigRange = lastSig - firstSig;
703 
704  if (lastSig > 0.5 * m_deltaPeakTimeSig && sigRange > 0.5)
705  {
706  // Declare a maximum of 1.5 * the average of the first and last pairs...
707  float maxSignificance = std::max(0.75 * (firstSig + lastSig),1.0);
708 
709  std::vector<reco::ClusterHit3D>::iterator firstBadElem = std::find_if(tempDeadChanVec.begin(),tempDeadChanVec.end(),[&maxSignificance](const auto& pair){return pair.getDeltaPeakTime()/pair.getSigmaPeakTime() > maxSignificance;});
710 
711  // But only keep the best 10?
712  if (std::distance(tempDeadChanVec.begin(),firstBadElem) > 20) firstBadElem = tempDeadChanVec.begin() + 20;
713  // Keep at least one hit...
714  else if (firstBadElem == tempDeadChanVec.begin()) firstBadElem++;
715 
716  tempDeadChanVec.resize(std::distance(tempDeadChanVec.begin(),firstBadElem));
717  }
718  }
719 
720  for(auto& pair : tempDeadChanVec)
721  {
722  pair.setID(hitPairList.size());
723  hitPairList.emplace_back(new reco::ClusterHit3D(pair));
724  }
725  }
726  }
727  }
728 
729  return;
730 }
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:112
intermediate_table::iterator iterator
geo::WireID NearestWireID(const float *position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
float getSigmaPeakTime() const
Definition: Cluster3D.h:154
Int_t max
Definition: plot.C:27
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
const float * getPosition() const
Definition: Cluster3D.h:147
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
void setID(const size_t &id) const
Definition: Cluster3D.h:164
float getDeltaPeakTime() const
Definition: Cluster3D.h:153
bool makeDeadChannelPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pair, size_t maxStatus=4, size_t minStatus=0, float minOverlap=0.2) const
Make a 3D HitPair object from a valid pair and a dead channel in the missing plane.
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 1098 of file StandardHit3DBuilder_tool.cc.

References reco::ClusterHit3D::getAvePeakTime().

1099 {
1100  static const float minCharge(0.);
1101 
1102  int numberInRange(0);
1103  float pairAvePeakTime(pair.getAvePeakTime());
1104 
1105  // Idea is to loop through the input set of hits and look for the best combination
1106  for (const auto& hit2D : hit2DSet)
1107  {
1108  if (hit2D->getHit().Integral() < minCharge) continue;
1109 
1110  float hitVPeakTime(hit2D->getTimeTicks());
1111  float deltaPeakTime(pairAvePeakTime-hitVPeakTime);
1112 
1113  if (deltaPeakTime > range) continue;
1114 
1115  if (deltaPeakTime < -range) break;
1116 
1117  numberInRange++;
1118  }
1119 
1120  return numberInRange;
1121 }
float getAvePeakTime() const
Definition: Cluster3D.h:152
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 92 of file StandardHit3DBuilder_tool.cc.

92 {return m_timeVector.at(index);}
void lar_cluster3d::StandardHit3DBuilder::Hit3DBuilder ( const art::Event evt,
reco::HitPairList hitPairList,
RecobHitToPtrMap clusterHitToArtPtrMap 
) const
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)

Implements lar_cluster3d::IHit3DBuilder.

Definition at line 313 of file StandardHit3DBuilder_tool.cc.

References BuildHit3D(), CollectArtHits(), m_clusterHit2DMasterVec, m_planeToHitVectorMap, m_planeToWireToHitSetMap, m_timeVector, and lar_cluster3d::IHit3DBuilder::NUMTIMEVALUES.

314 {
315  // Clear the internal data structures
316  m_clusterHit2DMasterVec.clear();
317  m_planeToHitVectorMap.clear();
318  m_planeToWireToHitSetMap.clear();
319 
320  m_timeVector.resize(NUMTIMEVALUES, 0.);
321 
322  // Recover the 2D hits and then organize them into data structures which will be used in the
323  // DBscan algorithm for building the 3D clusters
324  this->CollectArtHits(evt, clusterHitToArtPtrMap);
325 
326 // if (m_enableMonitoring) theClockArtHits.stop();
327 
328  // If there are no hits in our view/wire data structure then do not proceed with the full analysis
329  if (!m_planeToWireToHitSetMap.empty())
330  {
331  // Call the algorithm that builds 3D hits
332  this->BuildHit3D(hitPairList);
333  }
334 
335  return;
336 }
void BuildHit3D(reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
void CollectArtHits(const art::Event &evt, RecobHitToPtrMap &hitToPtrMap) const
Extract the ART hits and the ART hit-particle relationships.
bool lar_cluster3d::StandardHit3DBuilder::makeDeadChannelPair ( reco::ClusterHit3D pairOut,
const reco::ClusterHit3D pair,
size_t  maxStatus = 4,
size_t  minStatus = 0,
float  minOverlap = 0.2 
) const
private

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

Definition at line 994 of file StandardHit3DBuilder_tool.cc.

References geo::CryostatID::Cryostat, reco::ClusterHit2D::getHit(), reco::ClusterHit3D::getHits(), reco::ClusterHit3D::getPosition(), reco::ClusterHit2D::getStatusBits(), m_channelStatus, m_geometry, 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, recob::Hit::WireID(), geo::GeometryCore::WireIDsIntersect(), geo::WireIDIntersection::y, and geo::WireIDIntersection::z.

Referenced by findGoodTriplets().

999 {
1000  // Assume failure (most common result)
1001  bool result(false);
1002 
1003  const reco::ClusterHit2D* hit0 = pair.getHits().at(0);
1004  const reco::ClusterHit2D* hit1 = pair.getHits().at(1);
1005 
1006  size_t missPlane(2);
1007 
1008  // u plane hit is missing
1009  if (!hit0)
1010  {
1011  hit0 = pair.getHits().at(2);
1012  missPlane = 0;
1013  }
1014  // v plane hit is missing
1015  else if (!hit1)
1016  {
1017  hit1 = pair.getHits().at(2);
1018  missPlane = 1;
1019  }
1020 
1021  // Which plane is missing?
1022  geo::WireID wireID0 = hit0->getHit().WireID();
1023  geo::WireID wireID1 = hit1->getHit().WireID();
1024 
1025  // Ok, recover the wireID expected in the third plane...
1026  geo::WireID wireIn(wireID0.Cryostat,wireID0.TPC,missPlane,0);
1027  geo::WireID wireID = NearestWireID(pair.getPosition(), wireIn);
1028 
1029  // There can be a round off issue so check the next wire as well
1030  bool wireStatus = m_channelStatus[wireID.Plane][wireID.Wire] < maxChanStatus && m_channelStatus[wireID.Plane][wireID.Wire] >= minChanStatus;
1031  bool wireOneStatus = m_channelStatus[wireID.Plane][wireID.Wire+1] < maxChanStatus && m_channelStatus[wireID.Plane][wireID.Wire+1] >= minChanStatus;
1032 
1033  // Make sure they are of at least the minimum status
1034  if(wireStatus || wireOneStatus)
1035  {
1036  // Sort out which is the wire we're dealing with
1037  if (!wireStatus) wireID.Wire += 1;
1038 
1039  // Want to refine position since we "know" the missing wire
1040  geo::WireIDIntersection widIntersect0;
1041 
1042  if (m_geometry->WireIDsIntersect(wireID0, wireID, widIntersect0))
1043  {
1044  geo::WireIDIntersection widIntersect1;
1045 
1046  if (m_geometry->WireIDsIntersect(wireID1, wireID, widIntersect1))
1047  {
1048  float newPosition[] = {pair.getPosition()[0],pair.getPosition()[1],pair.getPosition()[2]};
1049 
1050  newPosition[1] = (newPosition[1] + widIntersect0.y + widIntersect1.y) / 3.;
1051  newPosition[2] = (newPosition[2] + widIntersect0.z + widIntersect1.z - 2. * m_zPosOffset) / 3.;
1052 
1053  pairOut = pair;
1054  pairOut.setWireID(wireID);
1055  pairOut.setPosition(newPosition);
1056 
1059 
1062 
1063  result = true;
1064  }
1065  }
1066  }
1067 
1068  return result;
1069 }
void setWireID(const geo::WireID &wid) const
Definition: Cluster3D.cxx:155
double z
z position of intersection
Definition: geo_types.h:494
geo::WireID NearestWireID(const float *position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
const float * getPosition() const
Definition: Cluster3D.h:147
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
void setPosition(const float *pos) const
Definition: Cluster3D.h:171
double y
y position of intersection
Definition: geo_types.h:493
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:158
unsigned getStatusBits() const
Definition: Cluster3D.h:68
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:75
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 732 of file StandardHit3DBuilder_tool.cc.

References geo::CryostatID::Cryostat, reco::ClusterHit2D::getHit(), reco::ClusterHit2D::getStatusBits(), reco::ClusterHit2D::getTimeTicks(), reco::ClusterHit2D::getXPosition(), reco::ClusterHit3D::initialize(), recob::Hit::Integral(), m_deltaPeakTimeSig, m_geometry, m_zPosOffset, recob::Hit::PeakAmplitude(), geo::PlaneID::Plane, recob::Hit::RMS(), reco::ClusterHit2D::setStatusBit(), reco::ClusterHit2D::SHAREDINPAIR, geo::TPCID::TPC, reco::ClusterHit2D::USEDINPAIR, recob::Hit::WireID(), geo::GeometryCore::WireIDsIntersect(), geo::WireIDIntersection::y, and geo::WireIDIntersection::z.

Referenced by findGoodHitPairs(), and makeHitTriplet().

737 {
738  // Assume failure
739  bool result(false);
740 
741  // We assume in this routine that we are looking at hits in different views
742  // The first mission is to check that the wires intersect
743  const geo::WireID& hit1WireID = hit1->getHit().WireID();
744  const geo::WireID& hit2WireID = hit2->getHit().WireID();
745 
746  geo::WireIDIntersection widIntersect;
747 
748  if (m_geometry->WireIDsIntersect(hit1WireID, hit2WireID, widIntersect))
749  {
750  // Wires intersect so now we can check the timing
751  float hit1Peak = hit1->getTimeTicks();
752  float hit1Sigma = hit1->getHit().RMS();
753 
754  float hit2Peak = hit2->getTimeTicks();
755  float hit2Sigma = hit2->getHit().RMS();
756 
757  // ad hoc correction for most bad fits...
758  if (hit1Sigma > 2. * hit1->getHit().PeakAmplitude()) hit1Sigma = 2. * hit1->getHit().PeakAmplitude();
759  if (hit2Sigma > 2. * hit2->getHit().PeakAmplitude()) hit2Sigma = 2. * hit2->getHit().PeakAmplitude();
760 
761  float hit1Width = hitWidthSclFctr * hit1Sigma;
762  float hit2Width = hitWidthSclFctr * hit2Sigma;
763 
764  // Coarse check hit times are "in range"
765  if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width))
766  {
767  // Check to see that hit peak times are consistent with each other
768  float hit1SigSq = hit1Sigma * hit1Sigma;
769  float hit2SigSq = hit2Sigma * hit2Sigma;
770  float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
771  float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
772  float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
773 
774  // delta peak time consistency check here
775  if (deltaPeakTime < m_deltaPeakTimeSig * sigmaPeakTime) // 2 sigma consistency? (do this way to avoid divide)
776  {
777  float totalCharge = hit1->getHit().Integral() + hit2->getHit().Integral();
778  float hitChiSquare = std::pow((hit1Peak - avePeakTime),2) / hit1SigSq
779  + std::pow((hit2Peak - avePeakTime),2) / hit2SigSq;
780 
781  float xPositionHit1(hit1->getXPosition());
782  float xPositionHit2(hit2->getXPosition());
783  float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
784 
785  float position[] = {xPosition, float(widIntersect.y), float(widIntersect.z)-m_zPosOffset};
786 
787  // If to here then we need to sort out the hit pair code telling what views are used
788  unsigned statusBits = 1 << hit1->getHit().WireID().Plane | 1 << hit2->getHit().WireID().Plane;
789 
790  // handle status bits for the 2D hits
793 
796 
797  reco::ClusterHit2DVec hitVector;
798 
799  hitVector.resize(3, NULL);
800 
801  hitVector.at(hit1->getHit().WireID().Plane) = hit1;
802  hitVector.at(hit2->getHit().WireID().Plane) = hit2;
803 
804  unsigned int cryostatIdx = hit1->getHit().WireID().Cryostat;
805  unsigned int tpcIdx = hit1->getHit().WireID().TPC;
806 
807  // Initialize the wireIdVec
808  std::vector<geo::WireID> wireIDVec = {geo::WireID(cryostatIdx,tpcIdx,0,0),
809  geo::WireID(cryostatIdx,tpcIdx,1,0),
810  geo::WireID(cryostatIdx,tpcIdx,2,0)};
811 
812  wireIDVec[hit1->getHit().WireID().Plane] = hit1->getHit().WireID();
813  wireIDVec[hit2->getHit().WireID().Plane] = hit2->getHit().WireID();
814 
815  // For compiling at the moment
816  std::vector<float> hitDelTSigVec = {0.,0.,0.};
817 
818  hitDelTSigVec.at(hit1->getHit().WireID().Plane) = deltaPeakTime / sigmaPeakTime;
819  hitDelTSigVec.at(hit2->getHit().WireID().Plane) = deltaPeakTime / sigmaPeakTime;
820 
821  // Create the 3D cluster hit
822  hitPair.initialize(hitPairCntr,
823  statusBits,
824  position,
825  totalCharge,
826  avePeakTime,
827  deltaPeakTime,
828  sigmaPeakTime,
829  hitChiSquare,
830  0.,
831  0.,
832  hitVector,
833  hitDelTSigVec,
834  wireIDVec);
835 
836  result = true;
837  }
838  }
839  }
840 
841  // Send it back
842  return result;
843 }
double z
z position of intersection
Definition: geo_types.h:494
float getTimeTicks() const
Definition: Cluster3D.h:72
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:221
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:225
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:222
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
float getXPosition() const
Definition: Cluster3D.h:71
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:85
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
double y
y position of intersection
Definition: geo_types.h:493
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
unsigned getStatusBits() const
Definition: Cluster3D.h:68
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:75
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 846 of file StandardHit3DBuilder_tool.cc.

References 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(), recob::Hit::Integral(), geo::kU, geo::kV, geo::kW, m_hitWidthSclFctr, makeHitPair(), NearestWireID(), norm, recob::Hit::PeakAmplitude(), geo::PlaneID::Plane, recob::Hit::RMS(), reco::ClusterHit2D::setStatusBit(), reco::ClusterHit2D::SHAREDINTRIPLET, reco::ClusterHit2D::USEDINTRIPLET, weight, geo::WireID::Wire, and recob::Hit::WireID().

Referenced by findGoodTriplets().

849 {
850  // Assume failure
851  bool result(false);
852 
853  static const float rmsToSig(1.0); //0.75); //0.57735027);
854 
855  // We are going to force the wire pitch here, some time in the future we need to fix
856  static const double wirePitch(0.3);
857 
858  // Recover hit info
859  float hitTimeTicks = hit->getTimeTicks();
860  float hitSigma = hit->getHit().RMS();
861 
862  // Special case check
863  if (hitSigma > 2. * hit->getHit().PeakAmplitude()) hitSigma = 2. * hit->getHit().PeakAmplitude();
864 
865  // Let's do a quick consistency check on the input hits to make sure we are in range...
866  // Require the W hit to be "in range" with the UV Pair
867  if (fabs(hitTimeTicks - pair.getAvePeakTime()) < m_hitWidthSclFctr * (pair.getSigmaPeakTime() + hitSigma))
868  {
869  // Timing in range, now check that the input hit wire "intersects" with the input pair's wires
870  geo::WireID wireID = NearestWireID(pair.getPosition(), hit->getHit().WireID());
871 
872  // There is an interesting round off issue that we need to watch for...
873  if (wireID.Wire == hit->getHit().WireID().Wire || wireID.Wire + 1 == hit->getHit().WireID().Wire)
874  {
875  // Use the existing code to see the U and W hits are willing to pair with the V hit
876  reco::ClusterHit3D pair0h;
877  reco::ClusterHit3D pair1h;
878 
879  // Recover all the hits involved
880  const reco::ClusterHit2DVec& pairHitVec = pair.getHits();
881  const reco::ClusterHit2D* hit0 = pairHitVec.at(0);
882  const reco::ClusterHit2D* hit1 = pairHitVec.at(1);
883 
884  if (!hit0) hit0 = pairHitVec.at(2);
885  else if (!hit1) hit1 = pairHitVec.at(2);
886 
887  // If good pairs made here then we can try to make a triplet
888  if (makeHitPair(pair0h, hit0, hit, m_hitWidthSclFctr) && makeHitPair(pair1h, hit1, hit, m_hitWidthSclFctr))
889  {
890  // We want to make sure the 3 sets of pair are really consistent
891  // For TPC's with a 60 degree pitch the wire "intersection" will be an equilateral triangle
892  // with equal sides of length wire pitch / sin(60 degrees) / 2
893  // So we make sure all three achieve this
894  Eigen::Vector2f pair0hYZVec(pair0h.getPosition()[1],pair0h.getPosition()[2]);
895  Eigen::Vector2f pair1hYZVec(pair1h.getPosition()[1],pair1h.getPosition()[2]);
896  Eigen::Vector2f pairYZVec(pair.getPosition()[1],pair.getPosition()[2]);
897 
898  std::vector<float> sideVec = {(pair0hYZVec - pair1hYZVec).norm(),(pair1hYZVec - pairYZVec).norm(),(pairYZVec - pair0hYZVec).norm()};
899 
900  // The three sides will not be identically equal because of numeric issues. It is really sufficient to simply
901  // check that the longest side is less than the wire pitch
902  if (*std::max_element(sideVec.begin(),sideVec.end()) < wirePitch)
903  {
904  // Get a copy of the input hit vector (note the order is by plane - by definition)
905  reco::ClusterHit2DVec hitVector = pair.getHits();
906 
907  // include the new hit
908  hitVector.at(hit->getHit().WireID().Plane) = hit;
909 
910  // Set up to get average peak time, hitChiSquare, etc.
911  unsigned int statusBits(0x7);
912  float totalCharge(0.);
913  float avePeakTime(0.);
914  float weightSum(0.);
915  float xPosition(0.);
916 
917  // And get the wire IDs
918  std::vector<geo::WireID> wireIDVec = {geo::WireID(0,0,geo::kU,0), geo::WireID(0,0,geo::kV,0), geo::WireID(0,0,geo::kW,0)};
919 
920  // First loop through the hits to get WireIDs and calculate the averages
921  for(size_t planeIdx = 0; planeIdx < 3; planeIdx++)
922  {
923  const reco::ClusterHit2D* hit2D = hitVector.at(planeIdx);
924 
925  wireIDVec.at(planeIdx) = hit2D->getHit().WireID();
926 
928 
930 
931  float hitRMS = rmsToSig * hit2D->getHit().RMS();
932  float weight = 1. / (hitRMS * hitRMS);
933  float peakTime = hit2D->getTimeTicks();
934 
935  avePeakTime += peakTime * weight;
936  xPosition += hit2D->getXPosition() * weight;
937  weightSum += weight;
938  totalCharge += hit2D->getHit().Integral();
939  }
940 
941  avePeakTime /= weightSum;
942  xPosition /= weightSum;
943 
944  float position[] = { xPosition,
945  float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
946  float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.)};
947 
948  // Armed with the average peak time, now get hitChiSquare and the sig vec
949  float hitChiSquare(0.);
950  float sigmaPeakTime(std::sqrt(1./weightSum));
951  std::vector<float> hitDelTSigVec;
952 
953  for(const auto& hit2D : hitVector)
954  {
955  float hitRMS = rmsToSig * hit2D->getHit().RMS();
956  float combRMS = std::sqrt(hitRMS*hitRMS - sigmaPeakTime*sigmaPeakTime);
957  float peakTime = hit2D->getTimeTicks();
958  float deltaTime = peakTime - avePeakTime;
959  float hitSig = deltaTime / combRMS; //hitRMS;
960 
961  hitChiSquare += hitSig * hitSig;
962 
963  hitDelTSigVec.emplace_back(std::fabs(hitSig));
964  }
965 
966  // Usurping "deltaPeakTime" to be the maximum pull
967  float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(),hitDelTSigVec.end());
968 
969  // Create the 3D cluster hit
970  hitTriplet.initialize(0,
971  statusBits,
972  position,
973  totalCharge,
974  avePeakTime,
975  deltaPeakTime,
976  sigmaPeakTime,
977  hitChiSquare,
978  0.,
979  0.,
980  hitVector,
981  hitDelTSigVec,
982  wireIDVec);
983 
984  result = true;
985  }
986  }
987  }
988  }
989 
990  // return success/fail
991  return result;
992 }
float getTimeTicks() const
Definition: Cluster3D.h:72
geo::WireID NearestWireID(const float *position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
Planes which measure V.
Definition: geo_types.h:77
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:221
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.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:225
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
Planes which measure U.
Definition: geo_types.h:76
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
float getXPosition() const
Definition: Cluster3D.h:71
const float * getPosition() const
Definition: Cluster3D.h:147
Detector simulation of raw signals on wires.
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:85
double weight
Definition: plottest35.C:25
Float_t norm
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:158
unsigned getStatusBits() const
Definition: Cluster3D.h:68
void setStatusBit(unsigned bits) const
Definition: Cluster3D.h:75
geo::WireID lar_cluster3d::StandardHit3DBuilder::NearestWireID ( const float *  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 1123 of file StandardHit3DBuilder_tool.cc.

References geo::GeometryCore::DetLength(), m_geometry, geo::GeometryCore::Nwires(), geo::PlaneID::Plane, geo::GeometryCore::Plane(), geo::WireID::Wire, and geo::PlaneGeo::WireCoordinate().

Referenced by findGoodTriplets(), makeDeadChannelPair(), and makeHitTriplet().

1124 {
1125  geo::WireID wireID = wireIDIn;
1126 
1127  // Embed the call to the geometry's services nearest wire id method in a try-catch block
1128  try
1129  {
1130  // Switch from NearestWireID to this method to avoid the roundoff error issues...
1131  double distanceToWire = m_geometry->Plane(wireIDIn).WireCoordinate(position);
1132 
1133  wireID.Wire = int(distanceToWire);
1134  }
1135  catch(std::exception& exc)
1136  {
1137  // This can happen, almost always because the coordinates are **just** out of range
1138  mf::LogWarning("Cluster3D") << "Exception caught finding nearest wire, position - " << exc.what() << std::endl;
1139 
1140  // Assume extremum for wire number depending on z coordinate
1141  if (position[2] < 0.5 * m_geometry->DetLength()) wireID.Wire = 0;
1142  else wireID.Wire = m_geometry->Nwires(wireIDIn.Plane) - 1;
1143  }
1144 
1145  return wireID;
1146 }
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double WireCoordinate(Point const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:725
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33

Member Data Documentation

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

Definition at line 211 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec().

ChannelStatusByPlaneVec lar_cluster3d::StandardHit3DBuilder::m_channelStatus
mutableprivate

Definition at line 206 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec(), and makeDeadChannelPair().

Hit2DVector lar_cluster3d::StandardHit3DBuilder::m_clusterHit2DMasterVec
mutableprivate

Definition at line 201 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), and Hit3DBuilder().

float lar_cluster3d::StandardHit3DBuilder::m_deltaPeakTimeSig
private

Definition at line 192 of file StandardHit3DBuilder_tool.cc.

Referenced by configure(), findGoodTriplets(), and makeHitPair().

const detinfo::DetectorProperties* lar_cluster3d::StandardHit3DBuilder::m_detector
private

Definition at line 210 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), and configure().

bool lar_cluster3d::StandardHit3DBuilder::m_enableMonitoring
private

Definition at line 194 of file StandardHit3DBuilder_tool.cc.

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

geo::Geometry* lar_cluster3d::StandardHit3DBuilder::m_geometry
private
art::InputTag lar_cluster3d::StandardHit3DBuilder::m_hitFinderTag
private

Data members to follow.

Definition at line 189 of file StandardHit3DBuilder_tool.cc.

Referenced by CollectArtHits(), and configure().

float lar_cluster3d::StandardHit3DBuilder::m_hitWidthSclFctr
private

Definition at line 191 of file StandardHit3DBuilder_tool.cc.

Referenced by configure(), findGoodHitPairs(), and makeHitTriplet().

size_t lar_cluster3d::StandardHit3DBuilder::m_numBadChannels
mutableprivate

Definition at line 207 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildChannelStatusVec(), and findGoodTriplets().

float lar_cluster3d::StandardHit3DBuilder::m_numSigmaPeakTime
private

Definition at line 190 of file StandardHit3DBuilder_tool.cc.

Referenced by BuildHitPairMap(), BuildHitPairMapByTPC(), and configure().

PlaneToHitVectorMap lar_cluster3d::StandardHit3DBuilder::m_planeToHitVectorMap
mutableprivate

Definition at line 202 of file StandardHit3DBuilder_tool.cc.

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

PlaneToWireToHitSetMap lar_cluster3d::StandardHit3DBuilder::m_planeToWireToHitSetMap
mutableprivate

Definition at line 203 of file StandardHit3DBuilder_tool.cc.

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

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

Definition at line 196 of file StandardHit3DBuilder_tool.cc.

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

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

Definition at line 195 of file StandardHit3DBuilder_tool.cc.

Referenced by configure().

float lar_cluster3d::StandardHit3DBuilder::m_zPosOffset
private

Definition at line 198 of file StandardHit3DBuilder_tool.cc.

Referenced by configure(), makeDeadChannelPair(), and makeHitPair().


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