Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
lar_cluster3d::DBScanAlg_DUNE35t Class Reference

DBScanAlg_DUNE35t class definiton. More...

#include <DBScanAlg_DUNE35t.h>

Public Types

enum  TimeValues { BUILDTHREEDHITS = 0, BUILDHITTOHITMAP = 1, RUNDBSCAN = 2, NUMTIMEVALUES }
 enumerate the possible values for time checking if monitoring timing More...
 

Public Member Functions

 DBScanAlg_DUNE35t (fhicl::ParameterSet const &pset)
 Constructor. More...
 
virtual ~DBScanAlg_DUNE35t ()
 Destructor. More...
 
void reconfigure (fhicl::ParameterSet const &pset)
 
void ClusterHitsDBScan (ViewToHitVectorMap &viewToHitVectorMap, ViewToWireToHitSetMap &viewToWiretoHitSetMap, HitPairList &hitPairList, reco::HitPairClusterMap &hitPairClusterMap)
 Given a set of recob hits, run DBscan to form 3D clusters. More...
 
double getTimeToExecute (TimeValues index) const
 If monitoring, recover the time to execute a particular function. More...
 

Private Types

typedef std::list< const reco::ClusterHit3D * > EpsPairNeighborhoodList
 
typedef std::pair< DBScanParams, EpsPairNeighborhoodListEpsPairNeighborhoodPair
 
typedef std::map< const reco::ClusterHit3D *, EpsPairNeighborhoodPairEpsPairNeighborhoodMap
 
typedef std::pair< const reco::ClusterHit3D *, EpsPairNeighborhoodPairEpsPairNeighborhoodMapPair
 
typedef std::vector< EpsPairNeighborhoodMapPairEpsPairNeighborhoodMapVec
 

Private Member Functions

size_t BuildHitPairMap (ViewToHitVectorMap &viewToHitVectorMap, ViewToWireToHitSetMap &viewToWiretoHitSetMap, HitPairList &hitPairList) const
 Given the ClusterHit2D objects, build the HitPairMap. More...
 
reco::ClusterHit3D makeHitPair (const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, double hitWidthSclFctr=1., size_t hitPairCntr=0) const
 Make a HitPair object by checking two hits. More...
 
reco::ClusterHit3D makeHitTriplet (const reco::ClusterHit3D &pair, const reco::ClusterHit2D *hit2) const
 Make a HitPair object by checking two hits. More...
 
const reco::ClusterHit2DFindBestMatchingHit (const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, double 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, double range) const
 A utility routine for returning the number of 2D hits from the list in a given range. More...
 
bool consistentPairs (const reco::ClusterHit3D *pair1, const reco::ClusterHit3D *pair2) const
 The bigger question: are two pairs of hits consistent? More...
 
void expandCluster (EpsPairNeighborhoodMapVec &nMap, EpsPairNeighborhoodMapVec::iterator vecItr, reco::HitPairListPtr &cluster, size_t minPts) const
 the main routine for DBScan More...
 
size_t BuildNeighborhoodMap (HitPairList &hitPairList, EpsPairNeighborhoodMapVec &epsPairNeighborhoodMapVec) const
 Given an input HitPairList, build out the map of nearest neighbors. More...
 
geo::WireID NearestWireID (const double *position, const geo::View_t &view) const
 Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range. More...
 
geo::WireID NearestWireID_mod (const double *position, const geo::PlaneID &thePlaneID) const
 

Private Attributes

size_t m_minPairPts
 Data members to follow. More...
 
double m_timeAdvanceGap
 
double m_numSigmaPeakTime
 
double m_EpsMaxDist
 
bool m_enableMonitoring
 
int m_hits
 
std::vector< float > m_timeVector
 
geo::Geometrym_geometry
 

Detailed Description

DBScanAlg_DUNE35t class definiton.

Definition at line 86 of file DBScanAlg_DUNE35t.h.

Member Typedef Documentation

Definition at line 161 of file DBScanAlg_DUNE35t.h.

Definition at line 163 of file DBScanAlg_DUNE35t.h.

Definition at line 164 of file DBScanAlg_DUNE35t.h.

Definition at line 165 of file DBScanAlg_DUNE35t.h.

Definition at line 162 of file DBScanAlg_DUNE35t.h.

Member Enumeration Documentation

enumerate the possible values for time checking if monitoring timing

Enumerator
BUILDTHREEDHITS 
BUILDHITTOHITMAP 
RUNDBSCAN 
NUMTIMEVALUES 

Definition at line 114 of file DBScanAlg_DUNE35t.h.

Constructor & Destructor Documentation

lar_cluster3d::DBScanAlg_DUNE35t::DBScanAlg_DUNE35t ( fhicl::ParameterSet const &  pset)

Constructor.

Parameters
pset

Definition at line 36 of file DBScanAlg_DUNE35t.cxx.

37 {
38  this->reconfigure(pset);
39 }
void reconfigure(fhicl::ParameterSet const &pset)
lar_cluster3d::DBScanAlg_DUNE35t::~DBScanAlg_DUNE35t ( )
virtual

Destructor.

Definition at line 43 of file DBScanAlg_DUNE35t.cxx.

44 {
45 }

Member Function Documentation

size_t lar_cluster3d::DBScanAlg_DUNE35t::BuildHitPairMap ( ViewToHitVectorMap viewToHitVectorMap,
ViewToWireToHitSetMap viewToWiretoHitSetMap,
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 306 of file DBScanAlg_DUNE35t.cxx.

307 {
308  /**
309  * @brief Given input 2D hits, build out the lists of possible 3D hits
310  *
311  * The current strategy: ideally all 3D hits would be comprised of a triplet of 2D hits, one from each view
312  * However, we have concern that, in particular, the v-plane may have some inefficiency which we have to be
313  * be prepared to deal with. The idea, then, is to first make the association of hits in the U and W planes
314  * 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
315  * will evaluate the situation and in some instances keep the U-W pairs in order to keep efficiency high.
316  */
317 
318 
319  // Should we set a minimum total charge for a hit?
320  size_t totalNumHits(0);
321  size_t hitPairCntr(0);
322  double minCharge[] = {0., 0., 0.};
323 
324  //-********************************************************************************
325  // First job is to find all pairs of hits in different views which are "consistent"
326  // Start loops over rows in HitVectorMap
327  ViewToHitVectorMap::iterator mapItrU = viewToHitVectorMap.find(geo::kU);
328 
329  if (mapItrU != viewToHitVectorMap.end())
330  {
331  HitVector& hitVectorU = mapItrU->second;
332 
333  totalNumHits += hitVectorU.size();
334 
335  ViewToHitVectorMap::iterator mapItrW = viewToHitVectorMap.find(geo::kW);
336 
337  if (mapItrW != viewToHitVectorMap.end())
338  {
339  HitVector& hitVectorW = mapItrW->second;
340 
341  totalNumHits += hitVectorW.size();
342 
343  if (viewToHitVectorMap.find(geo::kV) != viewToHitVectorMap.end())
344  totalNumHits += viewToHitVectorMap[geo::kV].size();
345 
346  // Take advantage that hits are sorted in "start time order"
347  // Set the inner loop iterator before starting loop over outer hits
348  HitVector::iterator hitVectorWStartItr = hitVectorW.begin();
349 
350  // Now we loop over the hits in these two layers
351  for (HitVector::iterator hitItrU = hitVectorU.begin(); hitItrU != hitVectorU.end(); hitItrU++)
352  {
353 
354  const reco::ClusterHit2D* hitPtrU = *hitItrU;
355 
356  if (hitPtrU->getHit().Integral() < minCharge[hitPtrU->getHit().View()]) continue;
357 
358 
359  // This will be used in each loop so dereference the peak time here
360  double hitUPeakTime = hitPtrU->getTimeTicks();
361 
362  // Inner loop is over hits within the time range of the outer hit
363  for (HitVector::iterator hitItrW = hitVectorWStartItr; hitItrW != hitVectorW.end(); hitItrW++)
364  {
365  const reco::ClusterHit2D* hitPtrW = *hitItrW;
366 
367  //Check to make sure that this hit is in the same TPC as the previous hit
368  if( hitPtrW->getHit().WireID().TPC != hitPtrU->getHit().WireID().TPC ) continue;
369 
370  if (hitPtrW->getHit().Integral() < minCharge[hitPtrW->getHit().View()]) continue;
371 
372  // Hits are sorted in "peak time order" which we can take advantage of to try to speed
373  // the loops. Basically, we can compare the peak time for the outer loop hit against
374  // the current hit's peak time and if outside the range of interest we can take action.
375  // The range of interest is eyeballed but is meant to account for large pulse widths
376  // Start by dereferencing the inner hit peak time
377  double hitWPeakTime = hitPtrW->getTimeTicks();
378 
379  // If the outer loop's peak time is well past the current hit's then
380  // we should advance the inner loop's start iterator and keep going
381  if (hitUPeakTime > hitWPeakTime + m_timeAdvanceGap)
382  {
383 
384 
385  hitVectorWStartItr++;
386  continue;
387  }
388 
389  // If the inner loop hit start time is past the end of the outer's end time, then break out loop
390  if (hitUPeakTime + m_timeAdvanceGap < hitWPeakTime) break;
391 
392  // We have a candidate hit pair combination, try to make a hit
393  reco::ClusterHit3D pair = makeHitPair(hitPtrU, hitPtrW);
394 
395 
396  // The sign of success here is that the average peak time of the combined hits is > 0
397  // (note that when hits are combined the first window offset is accounted for)
398  if (pair.getAvePeakTime() > 0.)
399  {
400  //bool hitInVNotFound(true);
401 
402 
403  //I need to know the plane ID to find the nearest wire in this TPC. In order to do that, I need to
404  //loop through the viewToHitVector map and find the plane ID corresponding to a hit in this plane and this TPC
405  size_t thePlane = 9999;
406  for( HitVector::iterator hitVect_iter = viewToHitVectorMap[geo::kV].begin(); hitVect_iter != viewToHitVectorMap[geo::kV].end(); ++hitVect_iter ){
407  if( (*(hitVect_iter))->getHit().WireID().TPC == hitPtrW->getHit().WireID().TPC ){
408  thePlane = (*(hitVect_iter))->getHit().WireID().Plane;
409  break;
410  }
411  }
412  geo::PlaneID thePlaneID(0,hitPtrW->getHit().WireID().TPC,thePlane);
413 
414  // Recover the WireID nearest in the V plane to the position of the pair
415  //REL Use plane ids here to avoid TPC ambiguity introduced by just using view type
416  const geo::WireID wireIDV = NearestWireID_mod(pair.getPosition(), thePlaneID);
417 
418  //Some debug printing
419  if( wireIDV.TPC != hitPtrW->getHit().WireID().TPC )
420  std::cout << "TPC of third (nearest) wire is not the same as the TPC of the first two." << std::endl;
421  if( hitPtrU->getHit().WireID().TPC != hitPtrW->getHit().WireID().TPC )
422  std::cout << "TPC of wire 1 is not TPC of wire 2." << std::endl;
423 
424  // We believe the code that returns the ID is offset by one
425  //Get the hits associated with the nearest wire
426  WireToHitSetMap::iterator wireToHitSetMapVItr = viewToWireToHitSetMap[geo::kV].find(wireIDV.Wire);
427 
428  if (wireToHitSetMapVItr != viewToWireToHitSetMap[geo::kV].end())
429  {
430  const reco::ClusterHit2D* hit2DV = FindBestMatchingHit(wireToHitSetMapVItr->second, pair, m_numSigmaPeakTime*pair.getSigmaPeakTime());
431 
432 
433  // If a V hit found then it should be straightforward to make the triplet
434 
435  if (hit2DV){
436  if( hitPtrW->getHit().WireID().TPC == hit2DV->getHit().WireID().TPC ){
437 
438  reco::ClusterHit3D triplet = makeHitTriplet(pair, hit2DV);
439 
440  if (triplet.getAvePeakTime() > 0.)
441  {
442 
443  triplet.setID(hitPairCntr++);
444  hitPairList.emplace_back(std::unique_ptr<reco::ClusterHit3D>(new reco::ClusterHit3D(triplet)));
445  // goodBool = true;
446  }
447 
448  //hitInVNotFound = false;
449  }
450  }
451  }
452 
453  }
454  }
455  }
456  }
457  }
458  hitPairList.sort(SetPositionOrderZ);
459  return hitPairList.size();
460 
461 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::iterator iterator
float getTimeTicks() const
Definition: Cluster3D.h:76
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:158
Planes which measure V.
Definition: geo_types.h:130
geo::WireID WireID() const
Definition: Hit.h:233
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
float getSigmaPeakTime() const
Definition: Cluster3D.h:165
reco::ClusterHit3D makeHitPair(const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, double hitWidthSclFctr=1., size_t hitPairCntr=0) const
Make a HitPair object by checking two hits.
const recob::Hit * getHit() const
Definition: Cluster3D.h:78
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
float getAvePeakTime() const
Definition: Cluster3D.h:163
const reco::ClusterHit2D * FindBestMatchingHit(const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, double pairDeltaTimeLimits) const
A utility routine for finding a 2D hit closest in time to the given pair.
Planes which measure U.
Definition: geo_types.h:129
reco::ClusterHit3D makeHitTriplet(const reco::ClusterHit3D &pair, const reco::ClusterHit2D *hit2) const
Make a HitPair object by checking two hits.
bool SetPositionOrderZ(const std::unique_ptr< reco::ClusterHit3D > &left, const std::unique_ptr< reco::ClusterHit3D > &right)
std::vector< reco::ClusterHit2D * > HitVector
What follows are several highly useful typedefs which we want to expose to the outside world...
void setID(const size_t &id) const
Definition: Cluster3D.h:179
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:131
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
geo::WireID NearestWireID_mod(const double *position, const geo::PlaneID &thePlaneID) const
QTextStream & endl(QTextStream &s)
size_t lar_cluster3d::DBScanAlg_DUNE35t::BuildNeighborhoodMap ( HitPairList hitPairList,
EpsPairNeighborhoodMapVec epsPairNeighborhoodMapVec 
) const
private

Given an input HitPairList, build out the map of nearest neighbors.

Definition at line 468 of file DBScanAlg_DUNE35t.cxx.

471 {
472  size_t consistentPairsCnt = 0;
473  size_t pairsChecked = 0;
474 
475  for (HitPairList::const_iterator pairItrO = hitPairList.begin(); pairItrO != hitPairList.end(); pairItrO++){
476 
477  const reco::ClusterHit3D* hitPairO = (*pairItrO).get();
478  const size_t hitPairOID = hitPairO->getID();
479 
480  // Need to initialize the "first" part of the vector pseudo map
481  epsPairNeighborhoodMapVec[hitPairOID].first = hitPairO;
482 
483  // Get reference to the list for this hit so we don't look it up inside the loop
484  EpsPairNeighborhoodPair& hitPairOPair(epsPairNeighborhoodMapVec[hitPairOID].second);
485 
486  HitPairList::const_iterator pairItrI = pairItrO;
487 
488  std::map<int, std::pair<double, const reco::ClusterHit3D*> > bestTripletMap;
489 
490  // Get the X,Y, and Z for this triplet
491  double pairO_X = hitPairO->getPosition()[0];
492  double pairO_Y = hitPairO->getPosition()[1];
493  double pairO_Z = hitPairO->getPosition()[2];
494 
495  // Set maximums
496  double maxDist = m_EpsMaxDist; //REL 4.0; //Was 2, then 4 REL
497 
498  //Loop over second iterator
499  while (++pairItrI != hitPairList.end())
500  {
501  const reco::ClusterHit3D* hitPairI = (*pairItrI).get();
502 
503  //OLD WAY
504  // Note that the hits have been sorted by z, then y and then in x
505  // Translation: hits are sorted by W wire, then in Y (increasing u, decreasing v)
506  // and then in time.
507 
508  //NEW WAY
509  // Hits have been sorted by Z position, then by Y, then by X (each in ascending order).
510  // There is no reference to wire number here, since we need to consider clustering
511  // across TPCs.
512 
513  // Get the X,Y, and Z for this triplet
514  double pairI_X = hitPairI->getPosition()[0];
515  double pairI_Y = hitPairI->getPosition()[1];
516  double pairI_Z = hitPairI->getPosition()[2];
517 
518  //Sorting allows us to break this loop after the maxDist is surpassed in z
519  if( pairI_Z - pairO_Z > maxDist ) break;
520 
521  //Form the distance so we can check ranges
522  double distance = pow(
523  pow(pairO_X-pairI_X,2) +
524  pow(pairO_Y-pairI_Y,2) +
525  pow(pairO_Z-pairI_Z,2),0.5);
526 
527  // If we have passed the 3d distance then we are done with the loop
528  if( distance > maxDist )continue;
529 
530 
531  // This is the tight constraint on the hits
532  if (consistentPairs(hitPairO, hitPairI))
533  {
534  double bestBin = distance;
535  double bestDist = 10000.;
536 
537  if (bestTripletMap.find(bestBin) != bestTripletMap.end()) //Look at a given case of error (a given bin) and pull out the best (shortest) distance
538  {
539  bestDist = bestTripletMap[bestBin].first;
540  }
541 
542  double newDist = fabs(hitPairI->getX() - hitPairO->getX());
543 
544  // This is an attempt to "prefer" triplets over pairs
545  if (hitPairI->getHits().size() < 3) newDist += 25.;
546 
547  if (newDist < bestDist) bestTripletMap[bestBin] = std::pair<double, const reco::ClusterHit3D*>(newDist, hitPairI); //Select the pair of hits that is closest in time
548 
549  }
550 
551  bestTripletMap[distance] = std::pair<double,const reco::ClusterHit3D*>(distance,hitPairI);
552 
553  }
554 
555  for(const auto& bestMapItr : bestTripletMap)
556  {
557  const reco::ClusterHit3D* hitPairI(bestMapItr.second.second);
558 
559  hitPairOPair.first.incrementCount();
560  hitPairOPair.second.emplace_back(hitPairI);
561 
562  epsPairNeighborhoodMapVec[hitPairI->getID()].second.first.incrementCount();
563  epsPairNeighborhoodMapVec[hitPairI->getID()].second.second.emplace_back(hitPairO);
564 
565  consistentPairsCnt++;
566  }
567  }
568 
569  mf::LogDebug("Cluster3D") << "Consistent pairs: " << consistentPairsCnt << " of " << pairsChecked << " checked." << std::endl;
570 
571  return consistentPairsCnt;
572 
573 }
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:158
constexpr T pow(T x)
Definition: pow.h:72
intermediate_table::const_iterator const_iterator
std::pair< DBScanParams, EpsPairNeighborhoodList > EpsPairNeighborhoodPair
size_t getID() const
Definition: Cluster3D.h:156
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:171
QTextStream & endl(QTextStream &s)
float getX() const
Definition: Cluster3D.h:159
bool consistentPairs(const reco::ClusterHit3D *pair1, const reco::ClusterHit3D *pair2) const
The bigger question: are two pairs of hits consistent?
void lar_cluster3d::DBScanAlg_DUNE35t::ClusterHitsDBScan ( ViewToHitVectorMap viewToHitVectorMap,
ViewToWireToHitSetMap viewToWiretoHitSetMap,
HitPairList hitPairList,
reco::HitPairClusterMap hitPairClusterMap 
)

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

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

Definition at line 208 of file DBScanAlg_DUNE35t.cxx.

212 {
213  /**
214  * @brief Driver for processing input 2D hits, transforming to 3D hits and building lists
215  * of associated 3D hits (candidate 3D clusters)
216  */
217  cet::cpu_timer theClockMakeHits;
218  cet::cpu_timer theClockBuildNeighborhood;
219  cet::cpu_timer theClockDBScan;
220 
221  m_timeVector.resize(NUMTIMEVALUES, 0.);
222 
223  if (m_enableMonitoring) theClockMakeHits.start();
224 
225 
226  // The first task is to take the lists of input 2D hits (a map of view to sorted lists of 2D hits)
227  // and then to build a list of 3D hits to be used in downstream processing
228  size_t numHitPairs = BuildHitPairMap(viewToHitVectorMap, viewToWiretoHitSetMap, hitPairList);
229 
230  //Monitoring activity
231  if (m_enableMonitoring)
232  {
233  theClockMakeHits.stop();
234  theClockBuildNeighborhood.start();
235  }
236 
237  // The container of pairs and those in each pair's epsilon neighborhood
238  EpsPairNeighborhoodMapVec epsPairNeighborhoodMapVec;
239  epsPairNeighborhoodMapVec.resize(numHitPairs, EpsPairNeighborhoodMapPair(0,EpsPairNeighborhoodPair())); //<-- initialize too!
240 
241  // DBScan is driven of its "epsilon neighborhood". Computing adjacency within DBScan can be time
242  // consuming so the idea is the prebuild the adjaceny map and then run DBScan.
243  // The following call does this work
244  BuildNeighborhoodMap(hitPairList, epsPairNeighborhoodMapVec);
245 
246  //Monitoring activity
247  if (m_enableMonitoring)
248  {
249  theClockBuildNeighborhood.stop();
250  theClockDBScan.start();
251  }
252 
253  // With the neighborhood built we can now form "clusters" with DBScan
254  int pairClusterIdx(0);
255 
256  // Clear the cluster list just for something to do here...
257  hitPairClusterMap.clear();
258 
259  // Ok, here we go!
260  // We can simply iterate over the map we have just built to loop through the hits "simply"
261  for(EpsPairNeighborhoodMapVec::iterator epsPairVecItr = epsPairNeighborhoodMapVec.begin();
262  epsPairVecItr != epsPairNeighborhoodMapVec.end();
263  epsPairVecItr++)
264  {
265  // Skip the null entries (they were filtered out)
266  if (!epsPairVecItr->first) continue;
267 
268  // If this hit has been "visited" already then skip
269  if (epsPairVecItr->second.first.visited()) continue;
270 
271  // We are now visiting it so mark it as so
272  epsPairVecItr->second.first.setVisited();
273 
274  // Check that density is sufficient
275  if (epsPairVecItr->second.first.getCount() < m_minPairPts)
276  {
277  epsPairVecItr->second.first.setNoise();
278  }
279  else
280  {
281  // "Create" a new cluster and get a reference to it
282  reco::HitPairListPtr& curCluster = hitPairClusterMap[pairClusterIdx++];
283 
284  // expand the cluster
285  expandCluster(epsPairNeighborhoodMapVec, epsPairVecItr, curCluster, m_minPairPts);
286  }
287  }
288 
289  //Monitoring activity
290  if (m_enableMonitoring)
291  {
292  theClockDBScan.stop();
293 
294  m_timeVector[BUILDTHREEDHITS] = theClockMakeHits.accumulated_real_time();
295  m_timeVector[BUILDHITTOHITMAP] = theClockBuildNeighborhood.accumulated_real_time();
296  m_timeVector[RUNDBSCAN] = theClockDBScan.accumulated_real_time();
297  }
298 
299  mf::LogDebug("Cluster3D") << ">>>>> DBScan done, found " << hitPairClusterMap.size() << " clusters" << std::endl;
300 
301  return;
302 }
intermediate_table::iterator iterator
std::vector< EpsPairNeighborhoodMapPair > EpsPairNeighborhoodMapVec
size_t BuildNeighborhoodMap(HitPairList &hitPairList, EpsPairNeighborhoodMapVec &epsPairNeighborhoodMapVec) const
Given an input HitPairList, build out the map of nearest neighbors.
std::pair< DBScanParams, EpsPairNeighborhoodList > EpsPairNeighborhoodPair
size_t BuildHitPairMap(ViewToHitVectorMap &viewToHitVectorMap, ViewToWireToHitSetMap &viewToWiretoHitSetMap, HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
std::list< const reco::ClusterHit3D * > HitPairListPtr
Definition: Cluster3D.h:335
size_t m_minPairPts
Data members to follow.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
std::pair< const reco::ClusterHit3D *, EpsPairNeighborhoodPair > EpsPairNeighborhoodMapPair
void expandCluster(EpsPairNeighborhoodMapVec &nMap, EpsPairNeighborhoodMapVec::iterator vecItr, reco::HitPairListPtr &cluster, size_t minPts) const
the main routine for DBScan
double accumulated_real_time() const
Definition: cpu_timer.cc:66
void start()
Definition: cpu_timer.cc:83
QTextStream & endl(QTextStream &s)
bool lar_cluster3d::DBScanAlg_DUNE35t::consistentPairs ( const reco::ClusterHit3D pair1,
const reco::ClusterHit3D pair2 
) const
private

The bigger question: are two pairs of hits consistent?

Definition at line 578 of file DBScanAlg_DUNE35t.cxx.

579 {
580  // Most likely this will fail
581  bool consistent(false);
582 
583  // Strategy: We assume that our mission is to check only in the time direction
584  // The idea is to check each 2D hit individually but to account for
585  // skipped wires if necessary. The criterion applied here is that 2
586  // of 3 times in the views must match the "tight" tolerance with the
587  // largest deltaT must still in "in range"
588  // Note that the input values can be either pairs of hits in U-W plane
589  // or a triplet of U-V-W 2D hits
590  // Start with U plane
591  std::vector<bool> matchedHits = {false, false, false};
592  double maxDeltaT(0.);
593  double maxAllowedDeltaT(0.);
594 
595  const recob::Hit& pair1UHit(pair1->getHits().front()->getHit());
596  const recob::Hit& pair2UHit(pair2->getHits().front()->getHit());
597 
598  int maxDeltaWires = pair1->getHits().size() < pair2->getHits().size()
599  ? int(pair1->getHits().size())
600  : int(pair2->getHits().size());
601 
602  int pair1UWire = pair1UHit.WireID().Wire;
603  double pair1UPeakTime = pair1UHit.PeakTime();
604  double pair1ULimit = pair1UHit.RMS() * 2.;
605 
606  int pair2UWire = pair2UHit.WireID().Wire;
607  double pair2UPeakTime = pair2UHit.PeakTime();
608  double pair2ULimit = pair2UHit.RMS() * 2.;
609 
610  int deltaUWire = fabs(pair1UWire - pair2UWire);
611  double limitTotalU = pair1ULimit + pair2ULimit;
612 
613  // Do we need to constrain this?
614  limitTotalU = std::min(limitTotalU, 100.);
615 
616  // Special conditions
617  if (deltaUWire == 0) limitTotalU *= 1.5; //3.;
618  else if (deltaUWire > 1) limitTotalU *= 3.; //2.;
619 
620  // If we are happy with U wires then go to the next step
621  if (deltaUWire < maxDeltaWires && fabs(pair1UPeakTime - pair2UPeakTime) < limitTotalU) matchedHits[0] = true;
622 
623  maxDeltaT = std::max(maxDeltaT, fabs(pair1UPeakTime - pair2UPeakTime));
624  maxAllowedDeltaT = std::max(maxAllowedDeltaT, limitTotalU);
625 
626  if (deltaUWire < maxDeltaWires)
627  {
628  // Now do the W plane which will always be the "back" element
629  const recob::Hit& pair1WHit(pair1->getHits().back()->getHit());
630  const recob::Hit& pair2WHit(pair2->getHits().back()->getHit());
631 
632  int pair1WWire = pair1WHit.WireID().Wire;
633  double pair1WPeakTime = pair1WHit.PeakTime();
634  double pair1WLimit = pair1WHit.RMS() * 2.;
635 
636  int pair2WWire = pair2WHit.WireID().Wire;
637  double pair2WPeakTime = pair2WHit.PeakTime();
638  double pair2WLimit = pair2WHit.RMS() * 2.;
639 
640  int deltaWWire = fabs(pair1WWire - pair2WWire);
641  double limitTotalW = pair1WLimit + pair2WLimit;
642 
643  // Do we need to constrain this?
644  limitTotalW = std::min(limitTotalW, 100.);
645 
646  // Special conditions
647  if (deltaWWire == 0) limitTotalW *= 1.5; //3.;
648  else if (deltaWWire > 1) limitTotalW *= 3.0; //2.;
649 
650  // If we are happy with U wires then go to the next step
651  if (deltaWWire < maxDeltaWires && fabs(pair1WPeakTime - pair2WPeakTime) < limitTotalW) matchedHits[1] = true;
652 
653  maxDeltaT = std::max(maxDeltaT, fabs(pair1WPeakTime - pair2WPeakTime));
654  maxAllowedDeltaT = std::max(maxAllowedDeltaT, limitTotalW);
655 
656  if (deltaWWire < maxDeltaWires)
657  {
658  // If we are triplet then keep going
659  if (pair1->getHits().size() > 2 && pair2->getHits().size() > 2)
660  {
661  // Now do the W plane which will always be the "back" element
662  const recob::Hit& pair1VHit(pair1->getHits()[1]->getHit());
663  const recob::Hit& pair2VHit(pair2->getHits()[1]->getHit());
664 
665  int pair1VWire = pair1VHit.WireID().Wire;
666  double pair1VPeakTime = pair1VHit.PeakTime();
667  double pair1VLimit = pair1VHit.RMS() * 2.;
668 
669  int pair2VWire = pair2VHit.WireID().Wire;
670  double pair2VPeakTime = pair2VHit.PeakTime();
671  double pair2VLimit = pair2VHit.RMS() * 2.;
672 
673  int deltaVWire = fabs(pair1VWire - pair2VWire);
674  double limitTotalV = pair1VLimit + pair2VLimit;
675 
676  // Do we need to constrain this?
677  limitTotalV = std::min(limitTotalV, 100.);
678 
679  // Special conditions
680  if (deltaVWire == 0) limitTotalV *= 2.; //4.;
681  else if (deltaVWire > 1) limitTotalV *= 4.; //2.;
682 
683  // If we are happy with U wires then go to the next step
684  if (deltaVWire < maxDeltaWires)
685  {
686  if (fabs(pair1VPeakTime - pair2VPeakTime) < limitTotalV) matchedHits[2] = true;
687 
688  maxDeltaT = std::max(maxDeltaT, fabs(pair1VPeakTime - pair2VPeakTime));
689  maxAllowedDeltaT = std::max(maxAllowedDeltaT, limitTotalV);
690  }
691  else
692  {
693  // If wires are not in range then we zap the total vector
694  matchedHits[0] = false;
695  matchedHits[1] = false;
696  }
697  }
698  }
699  }
700 
701  // Now count the number of matches
702  int numMatches = std::count(matchedHits.begin(), matchedHits.end(), true);
703 
704  if (numMatches > 2) consistent = true;
705  else if (numMatches > 1)
706  {
707  maxAllowedDeltaT = std::min(5.*maxAllowedDeltaT, 50.);
708 
709  if (maxDeltaT < maxAllowedDeltaT) consistent = true;
710  }
711 
712  return consistent;
713 }
geo::WireID WireID() const
Definition: Hit.h:233
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
static int max(int a, int b)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:171
void lar_cluster3d::DBScanAlg_DUNE35t::expandCluster ( EpsPairNeighborhoodMapVec nMap,
EpsPairNeighborhoodMapVec::iterator  vecItr,
reco::HitPairListPtr cluster,
size_t  minPts 
) const
private

the main routine for DBScan

Definition at line 66 of file DBScanAlg_DUNE35t.cxx.

70 {
71  // This is the main inside loop for the DBScan based clustering algorithm
72  //
73  // Add the current hit to the current cluster
74  epsVecItr->second.first.setInCluster();
75  curCluster.push_back(epsVecItr->first);
76 
77  // Get the list of points in this hit's epsilon neighborhood
78  // Note this is a copy so we can modify locally
79  EpsPairNeighborhoodList epsNeighborhoodList = epsVecItr->second.second;
80 
81  while(!epsNeighborhoodList.empty())
82  {
83  // Dereference the point so we can see in the debugger...
84  const reco::ClusterHit3D* neighborPtr = epsNeighborhoodList.front();
85 
86  // Use that to look up the iterator in the general neighborhood map
87  EpsPairNeighborhoodMapVec::iterator curPtEpsVecItr = epsNeighborhoodMapVec.begin();
88 
89  std::advance(curPtEpsVecItr, neighborPtr->getID());
90 
91  // If we've not been here before then take action...
92  if (!curPtEpsVecItr->second.first.visited())
93  {
94  curPtEpsVecItr->second.first.setVisited();
95 
96  // If this epsilon neighborhood of this point is large enough then add its points to our list
97  if (curPtEpsVecItr->second.first.getCount() >= minPts)
98  {
99  // Plan is to loop through the hits in this point's neighborhood and add them to our list provided
100  // they have not already been added, or are part of a cluster, etc.
101  // So, get the list of points in the neighborhood
102  EpsPairNeighborhoodList& locList = curPtEpsVecItr->second.second;
103 
104  // And loop through them...
105  for(EpsPairNeighborhoodList::iterator hitItr = locList.begin(); hitItr != locList.end(); hitItr++)
106  {
107  epsNeighborhoodList.push_back(*hitItr);
108  }
109  }
110  }
111 
112  // If the point is not yet in a cluster then we now add
113  if (!curPtEpsVecItr->second.first.inCluster())
114  {
115  curPtEpsVecItr->second.first.setInCluster();
116  curCluster.push_back(curPtEpsVecItr->first);
117  }
118 
119  epsNeighborhoodList.pop_front();
120  }
121 
122  return;
123 }
intermediate_table::iterator iterator
size_t getID() const
Definition: Cluster3D.h:156
std::list< const reco::ClusterHit3D * > EpsPairNeighborhoodList
const reco::ClusterHit2D * lar_cluster3d::DBScanAlg_DUNE35t::FindBestMatchingHit ( const Hit2DSet hit2DSet,
const reco::ClusterHit3D pair,
double  pairDeltaTimeLimits 
) const
private

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

Definition at line 929 of file DBScanAlg_DUNE35t.cxx.

930 {
931  static const double minCharge(0.);
932 
933  const reco::ClusterHit2D* bestVHit(0);
934 
935  double pairAvePeakTime(pair.getAvePeakTime());
936 
937  // Idea is to loop through the input set of hits and look for the best combination
938  for (const auto& hit2D : hit2DSet)
939  {
940  if (hit2D->getHit().Integral() < minCharge) continue;
941 
942  double hitVPeakTime(hit2D->getTimeTicks());
943  double deltaPeakTime(pairAvePeakTime-hitVPeakTime);
944 
945  if (deltaPeakTime > pairDeltaTimeLimits) continue;
946 
947  // if (deltaPeakTime < -pairDeltaTimeLimits) break;
948  //REL
949  if (deltaPeakTime < -pairDeltaTimeLimits) continue;
950 
951  pairDeltaTimeLimits = fabs(deltaPeakTime);
952  bestVHit = hit2D;
953  }
954 
955  return bestVHit;
956 }
float getAvePeakTime() const
Definition: Cluster3D.h:163
int lar_cluster3d::DBScanAlg_DUNE35t::FindNumberInRange ( const Hit2DSet hit2DSet,
const reco::ClusterHit3D pair,
double  range 
) const
private

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

Definition at line 958 of file DBScanAlg_DUNE35t.cxx.

959 {
960  static const double minCharge(0.);
961 
962  int numberInRange(0);
963  double pairAvePeakTime(pair.getAvePeakTime());
964 
965  // Idea is to loop through the input set of hits and look for the best combination
966  for (const auto& hit2D : hit2DSet)
967  {
968  if (hit2D->getHit().Integral() < minCharge) continue;
969 
970  double hitVPeakTime(hit2D->getTimeTicks());
971  double deltaPeakTime(pairAvePeakTime-hitVPeakTime);
972 
973  if (deltaPeakTime > range) continue;
974 
975  if (deltaPeakTime < -range) break;
976 
977  numberInRange++;
978  }
979 
980  return numberInRange;
981 }
float getAvePeakTime() const
Definition: Cluster3D.h:163
double lar_cluster3d::DBScanAlg_DUNE35t::getTimeToExecute ( TimeValues  index) const
inline

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

Definition at line 123 of file DBScanAlg_DUNE35t.h.

reco::ClusterHit3D lar_cluster3d::DBScanAlg_DUNE35t::makeHitPair ( const reco::ClusterHit2D hit1,
const reco::ClusterHit2D hit2,
double  hitWidthSclFctr = 1.,
size_t  hitPairCntr = 0 
) const
private

Make a HitPair object by checking two hits.

Definition at line 716 of file DBScanAlg_DUNE35t.cxx.

720 {
721  // No matter what happens, we will return a HitPair object
722  unsigned statusBits(0);
723  double position[] = {0.,0.,0.};
724  double totalCharge(0.);
725  double avePeakTime(0.);
726  double deltaPeakTime(0.);
727  double sigmaPeakTime(0.);
728  double overlapFraction(0.);
729  double hitDocaToAxis(9999.);
730  double hitArclenToPoca(0.);
731 
732  std::vector<const reco::ClusterHit2D*> hitVector;
733 
734  hitVector.push_back(hit1);
735  hitVector.push_back(hit2);
736 
737  // We assume in this routine that we are looking at hits in different views
738  // The first mission is to check that the wires intersect
739  const geo::WireID& hit1WireID = hit1->getHit().WireID();
740  const geo::WireID& hit2WireID = hit2->getHit().WireID();
741 
742  geo::WireIDIntersection widIntersect;
743 
744  if (m_geometry->WireIDsIntersect(hit1WireID, hit2WireID, widIntersect))
745  {
746  // Wires intersect so now we can check the timing
747  // We'll need the plane offsets to proceed, these can be inferred from the "time ticks" stored in the 2D hit
748  double hit1Offset = hit1->getHit().PeakTime() - hit1->getTimeTicks();
749  double hit2Offset = hit2->getHit().PeakTime() - hit2->getTimeTicks();
750 
751  // Basically, require that the hit times "overlap"
752  // Check here is that they are inconsistent
753  double hit1Peak = hit1->getHit().PeakTime() - hit1Offset;
754  double hit1Sigma = hit1->getHit().RMS() * 2. / 2.355;
755 
756  double hit2Peak = hit2->getHit().PeakTime() - hit2Offset;
757  double hit2Sigma = hit2->getHit().RMS() * 2. / 2.355;
758 
759 // double hit1Width = 2.*0.5*hit1->getHit().RMS() * 2.;
760 // double hit2Width = 2.*0.5*hit2->getHit().RMS() * 2.;
761  double hit1Width = hitWidthSclFctr * hit1->getHit().RMS() * 2.;
762  double hit2Width = hitWidthSclFctr * hit2->getHit().RMS() * 2.;
763 
764  // Check hit times are consistent
765  if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width))
766  {
767  double maxUpper = std::min(hit1Peak+hit1Width,hit2Peak+hit2Width);
768  double minLower = std::max(hit1Peak-hit1Width,hit2Peak-hit2Width);
769  double overlap = maxUpper - minLower;
770 
771  overlapFraction = 0.5 * overlap / std::min(hit1Width,hit2Width);
772 
773  if (overlapFraction > 0.)
774  {
775  avePeakTime = 0.5 * (hit1Peak + hit2Peak);
776  deltaPeakTime = fabs(hit1Peak - hit2Peak);
777  sigmaPeakTime = sqrt(hit1Sigma*hit1Sigma + hit2Sigma*hit2Sigma);
778  totalCharge = hit1->getHit().Integral() + hit2->getHit().Integral();
779 
780  sigmaPeakTime = std::max(sigmaPeakTime, 0.1);
781 
782  double xPositionHit1(hit1->getXPosition());
783  double xPositionHit2(hit2->getXPosition());
784  double xPosition = 0.5 * (xPositionHit1 + xPositionHit2);
785 
786  position[0] = xPosition;
787  position[1] = widIntersect.y;
788  position[2] = widIntersect.z;
789 
790  // If to here then we need to sort out the hit pair code telling what views are used
791  statusBits = (unsigned(hit1->getHit().View()) + 1) * unsigned(hit2->getHit().View());
792  }
793  }
794  }
795 
796  // Create the 3D cluster hit
797  reco::ClusterHit3D hitPair(hitPairCntr,
798  statusBits,
799  position,
800  totalCharge,
801  avePeakTime,
802  deltaPeakTime,
803  sigmaPeakTime,
804  overlapFraction,
805  hitDocaToAxis,
806  hitArclenToPoca,
807  hitVector);
808  // Send it back
809  return hitPair;
810 }
double z
z position of intersection
Definition: geo_types.h:805
float getTimeTicks() const
Definition: Cluster3D.h:76
geo::WireID WireID() const
Definition: Hit.h:233
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:220
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
const recob::Hit * getHit() const
Definition: Cluster3D.h:78
float getXPosition() const
Definition: Cluster3D.h:75
static int max(int a, int b)
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
double y
y position of intersection
Definition: geo_types.h:804
reco::ClusterHit3D lar_cluster3d::DBScanAlg_DUNE35t::makeHitTriplet ( const reco::ClusterHit3D pair,
const reco::ClusterHit2D hit2 
) const
private

Make a HitPair object by checking two hits.

Definition at line 813 of file DBScanAlg_DUNE35t.cxx.

815 {
816  // No matter what happens, we will return a HitPair object
817  unsigned statusBits(0x8); // This one is easy... 0x8 means triplet
818  double position[] = {0.,0.,0.};
819  double totalCharge(0.);
820  double avePeakTime(0.);
821  double deltaPeakTime(1000.);
822  double sigmaPeakTime(0.);
823  double overlapFraction(0.);
824  double hitDocaToAxis(9999.);
825  double hitArclenToPoca(0.);
826 
827  std::vector<const reco::ClusterHit2D*> hitVector;
828 
829  // Recover all the hits involved
830  const reco::ClusterHit2D* hitU(pairUW.getHits()[0]);
831  const reco::ClusterHit2D* hitW(pairUW.getHits()[1]);
832 
833  // Let's do a quick consistency check on the input hits to make sure we are in range...
834  //double uvDeltaT = std::max(pairUV.getDeltaPeakTime(), 2.); // Set a lower limit
835  //double uvSigma = pairUV.getSigmaPeakTime();
836  //double wSigma = (hitW->getHit().RMS() * 2) / 2.355;
837  double uwDeltaT = 1.;
838  double uwSigma = 2.355 * pairUW.getSigmaPeakTime();
839  double vSigma = 2. * hitV->getHit().RMS();
840 
841  // Require the W hit to be "in range" with the UV Pair
842  if (fabs(hitV->getTimeTicks() - pairUW.getAvePeakTime()) < uwDeltaT * (uwSigma + vSigma))
843  {
844  // Use the existing code to see the U and W hits are willing to pair with the V hit
845  reco::ClusterHit3D pairUV = makeHitPair(hitU, hitV, 1.); //3.);
846  reco::ClusterHit3D pairVW = makeHitPair(hitW, hitV, 1.); //3.);
847 
848  // If pairs made here then we can make a triplet
849  // This condition means one of the two must be good
850  if (pairUV.getAvePeakTime() > 0. || pairVW.getAvePeakTime() > 0.)
851  {
852  double numGoodPairs(1.);
853 
854  // Position is simply the average
855  position[0] = pairUW.getPosition()[0];
856  position[1] = pairUW.getPosition()[1];
857  position[2] = pairUW.getPosition()[2];
858 
859  // Ave, delta and sigmas
860  avePeakTime = pairUW.getAvePeakTime();
861  deltaPeakTime = pairUW.getDeltaPeakTime();
862  sigmaPeakTime = pairUW.getSigmaPeakTime() * pairUW.getSigmaPeakTime();
863 
864  // Overlap fraction... hmmm....
865  overlapFraction = pairUW.getOverlapFraction();
866 
867  // Finally, total charge
868  totalCharge = pairUW.getTotalCharge();
869 
870  // Is the first W pair good?
871  if (pairUV.getAvePeakTime() > 0.)
872  {
873  position[0] += pairUV.getPosition()[0];
874  position[1] += pairUV.getPosition()[1];
875  position[2] += pairUV.getPosition()[2];
876  avePeakTime += pairUV.getAvePeakTime();
877  deltaPeakTime = std::max(deltaPeakTime, pairUV.getDeltaPeakTime());
878  sigmaPeakTime += pairUV.getSigmaPeakTime() * pairUV.getSigmaPeakTime();
879  overlapFraction = std::max(overlapFraction, pairUV.getOverlapFraction());
880  totalCharge += pairUV.getTotalCharge();
881  numGoodPairs++;
882  }
883 
884  // Is the second W pair good?
885  if (pairVW.getAvePeakTime() > 0.)
886  {
887  position[0] += pairVW.getPosition()[0];
888  position[1] += pairVW.getPosition()[1];
889  position[2] += pairVW.getPosition()[2];
890  avePeakTime += pairVW.getAvePeakTime();
891  deltaPeakTime = std::max(deltaPeakTime, pairVW.getDeltaPeakTime());
892  sigmaPeakTime += pairUV.getSigmaPeakTime() * pairVW.getSigmaPeakTime();
893  overlapFraction = std::max(overlapFraction, pairVW.getOverlapFraction());
894  totalCharge += pairVW.getTotalCharge();
895  numGoodPairs++;
896  }
897 
898  // Get averages
899  position[0] /= numGoodPairs;
900  position[1] /= numGoodPairs;
901  position[2] /= numGoodPairs;
902  avePeakTime /= numGoodPairs;
903  sigmaPeakTime = sqrt(sigmaPeakTime);
904 
905  // Remember our hits!
906  hitVector.push_back(hitU);
907  hitVector.push_back(hitV);
908  hitVector.push_back(hitW);
909  }
910  }
911 
912  // Create the 3D cluster hit
913  reco::ClusterHit3D hitTriplet(0,
914  statusBits,
915  position,
916  totalCharge,
917  avePeakTime,
918  deltaPeakTime,
919  sigmaPeakTime,
920  overlapFraction,
921  hitDocaToAxis,
922  hitArclenToPoca,
923  hitVector);
924  // Send it back
925  return hitTriplet;
926 }
const Eigen::Vector3f getPosition() const
Definition: Cluster3D.h:158
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:220
float getTotalCharge() const
Definition: Cluster3D.h:162
float getSigmaPeakTime() const
Definition: Cluster3D.h:165
reco::ClusterHit3D makeHitPair(const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, double hitWidthSclFctr=1., size_t hitPairCntr=0) const
Make a HitPair object by checking two hits.
float getOverlapFraction() const
Definition: Cluster3D.h:167
const recob::Hit * getHit() const
Definition: Cluster3D.h:78
float getAvePeakTime() const
Definition: Cluster3D.h:163
static int max(int a, int b)
float getDeltaPeakTime() const
Definition: Cluster3D.h:164
geo::WireID lar_cluster3d::DBScanAlg_DUNE35t::NearestWireID ( const double *  position,
const geo::View_t view 
) const
private

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

Definition at line 984 of file DBScanAlg_DUNE35t.cxx.

985 {
986  geo::WireID wireID(0,view,0,0);
987 
988  // Embed the call to the geometry's services nearest wire id method in a try-catch block
989  try {
990  wireID = m_geometry->NearestWireID(position, view);
991  }
992  catch(std::exception& exc)
993  {
994  // This can happen, almost always because the coordinates are **just** out of range
995  mf::LogWarning("Cluster3D") << "Exception caught finding nearest wire, position - " << exc.what() << std::endl;
996 
997  // Assume extremum for wire number depending on z coordinate
998  if (position[2] < 0.5 * m_geometry->DetLength()) wireID.Wire = 0;
999  else wireID.Wire = m_geometry->Nwires(view) - 1;
1000  }
1001 
1002  return wireID;
1003 }
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
geo::WireID NearestWireID(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
geo::WireID lar_cluster3d::DBScanAlg_DUNE35t::NearestWireID_mod ( const double *  position,
const geo::PlaneID thePlaneID 
) const
private

Definition at line 1006 of file DBScanAlg_DUNE35t.cxx.

1007 {
1008  geo::WireID wireID(0,0,0,0);
1009 
1010  // Embed the call to the geometry's services nearest wire id method in a try-catch block
1011  try {
1012  wireID = m_geometry->NearestWireID(position, thePlaneID.Plane, thePlaneID.TPC, thePlaneID.Cryostat);
1013  }
1014  catch(std::exception& exc)
1015  {
1016  // This can happen, almost always because the coordinates are **just** out of range
1017  mf::LogWarning("Cluster3D") << "Exception caught finding nearest wire, position - " << exc.what() << std::endl;
1018  std::cout << "Exception caught finding nearest wire." << std::endl;
1019 
1020 
1021  // Assume extremum for wire number depending on z coordinate
1022  if (position[2] < 0.5 * m_geometry->DetLength()) wireID.Wire = 0;
1023  else wireID.Wire = m_geometry->Nwires(thePlaneID.Plane) - 1; //Could be a problem here.Testing for now...
1024 
1025  std::cout << "WireID: " << wireID.Wire << std::endl;
1026 
1027  }
1028 
1029  return wireID;
1030 }
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
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.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
geo::WireID NearestWireID(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
void lar_cluster3d::DBScanAlg_DUNE35t::reconfigure ( fhicl::ParameterSet const &  pset)

Definition at line 49 of file DBScanAlg_DUNE35t.cxx.

50 {
51  m_enableMonitoring = pset.get<bool>("EnableMonitoring", true);
52  m_minPairPts = pset.get<size_t>("MinPairPts", 2 );
53  m_timeAdvanceGap = pset.get<double>("TimeAdvanceGap", 50.);
54  m_numSigmaPeakTime = pset.get<double>("NumSigmaPeakTime", 5.);
55  m_EpsMaxDist = pset.get<double>("EpsilonDistanceDBScan", 5.);
56 
58 
59  m_geometry = &*geometry;
60 
61  m_timeVector.resize(NUMTIMEVALUES, 0.);
62 
63 
64 }
size_t m_minPairPts
Data members to follow.

Member Data Documentation

bool lar_cluster3d::DBScanAlg_DUNE35t::m_enableMonitoring
private

Definition at line 198 of file DBScanAlg_DUNE35t.h.

double lar_cluster3d::DBScanAlg_DUNE35t::m_EpsMaxDist
private

Definition at line 196 of file DBScanAlg_DUNE35t.h.

geo::Geometry* lar_cluster3d::DBScanAlg_DUNE35t::m_geometry
private

Definition at line 202 of file DBScanAlg_DUNE35t.h.

int lar_cluster3d::DBScanAlg_DUNE35t::m_hits
private

Definition at line 199 of file DBScanAlg_DUNE35t.h.

size_t lar_cluster3d::DBScanAlg_DUNE35t::m_minPairPts
private

Data members to follow.

Definition at line 193 of file DBScanAlg_DUNE35t.h.

double lar_cluster3d::DBScanAlg_DUNE35t::m_numSigmaPeakTime
private

Definition at line 195 of file DBScanAlg_DUNE35t.h.

double lar_cluster3d::DBScanAlg_DUNE35t::m_timeAdvanceGap
private

Definition at line 194 of file DBScanAlg_DUNE35t.h.

std::vector<float> lar_cluster3d::DBScanAlg_DUNE35t::m_timeVector
private

Definition at line 200 of file DBScanAlg_DUNE35t.h.


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