LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
cluster::fuzzyClusterAlg Class Reference

#include "fuzzyClusterAlg.h"

Classes

class  baseCluster
 This stores information about a cluster. More...
 
class  showerCluster
 This stores information about a showerlike cluster. More...
 
class  trackCluster
 This stores information about a tracklike cluster. More...
 

Public Member Functions

 fuzzyClusterAlg (fhicl::ParameterSet const &pset)
 
virtual ~fuzzyClusterAlg ()
 
void reconfigure (fhicl::ParameterSet const &p)
 
void InitFuzzy (std::vector< art::Ptr< recob::Hit > > &allhits, std::set< uint32_t > badChannels)
 
void run_fuzzy_cluster (const std::vector< art::Ptr< recob::Hit > > &allhits)
 

Public Attributes

std::vector< std::vector< unsigned int > > fclusters
 collection of something More...
 
std::vector< std::vector< double > > fps
 the collection of points we are working on More...
 
std::vector< unsigned int > fpointId_to_clusterId
 mapping point_id -> clusterId More...
 
std::vector< std::vector< double > > fsim
 
std::vector< std::vector< double > > fsim2
 
std::vector< std::vector< double > > fsim3
 
double fMaxWidth
 
std::vector< std::vector< double > > data
 

Private Member Functions

void mergeHoughLinesBySegment (unsigned int k, std::vector< protoTrack > *protoTracks, double xyScale, int mergeStyle, double wire_dist, double tickToDist)
 
bool mergeTrackClusters (unsigned int k, std::vector< trackCluster > *trackClusters, double xyScale, double wire_dist, double tickToDist)
 
bool mergeShowerClusters (unsigned int k, std::vector< showerCluster > *showerClusters, double xyScale, double wire_dist, double tickToDist)
 
bool mergeShowerTrackClusters (showerCluster *showerClusterI, trackCluster *trackClusterJ, double xyScale, double wire_dist, double tickToDist)
 
double HoughLineDistance (double p0MinLine1, double p1MinLine1, double p0MaxLine1, double p1MaxLine1, double p0MinLine2, double p1MinLine2, double p0MaxLine2, double p1MaxLine2)
 
bool HoughLineIntersect (double x11, double y11, double x12, double y12, double x21, double y21, double x22, double y22)
 
double PointSegmentDistance (double px, double py, double x1, double y1, double x2, double y2)
 
double DistanceBetweenHits (art::Ptr< recob::Hit > hit0, art::Ptr< recob::Hit > hit1, double wire_dist, double tickToDist)
 

Private Attributes

double fNumberTimeBoundaries
 Number of boundaries in ticks for the drift window to be divided up to make the Hough line finder easier on memory. More...
 
double fNumberWireBoundaries
 Number of boundaries in wires for the drift window to be divided up to make the Hough line finder easier on memory. More...
 
bool fRunHough
 
bool fGenerateHoughLinesOnly
 Show only the results of the Hough line finder, hits not in a line will not be clustered. More...
 
bool fDoFuzzyRemnantMerge
 Tell the algorithm to merge fuzzy cluster remnants into showers or tracks (0-off, 1-on) More...
 
double fFuzzyRemnantMergeCutoff
 cut off on merging the fuzzy cluster remnants into the nearest shower or track More...
 
bool fDoTrackClusterMerge
 Turn on cut on product of charge asymmetry and sin of angle between slopes of lines. More...
 
double fTrackClusterMergeCutoff
 Max distance between Hough lines before two lines are merged (muon tracks),. More...
 
double fChargeAsymAngleCut
 Cut on product of charge asymmetry and sin of angle between slopes of lines. More...
 
double fSigmaChargeAsymAngleCut
 Cut on product of charge asymmetry and sin of angle between slopes of lines. More...
 
bool fDoShowerClusterMerge
 Turns on shower Hough line merging (0-off, 1-on) More...
 
double fShowerClusterMergeAngle
 Max angle between slopes before two lines are merged, for lines in shower line regions. More...
 
double fShowerClusterMergeCutoff
 Max distance between Hough lines before two lines are merged (electron showers),. More...
 
bool fDoShowerTrackClusterMerge
 Turn on cut on product of charge asymmetry and sin of angle between slopes of lines. More...
 
double fShowerTrackClusterMergeCutoff
 Max distance between Hough lines before two lines are merged (electron showers),. More...
 
double fShowerTrackClusterMergeAngle
 Max angle between slopes before two lines are merged, for lines in shower line regions. More...
 
double fShowerLikenessCut
 Cut on shower likeness (larger the more shower like, smaller the less shower like) More...
 
int fMaxVertexLines
 Max number of line end points allowed in a Hough line merge region for a merge to happen. More...
 
double fVertexLinesCutoff
 Size of the vertex region to count up lines for fMaxVertexLines. More...
 
std::vector< bool > fnoise
 
std::vector< bool > fvisited
 
std::vector< double > fWirePitch
 the pitch of the wires in each plane More...
 
std::set< uint32_t > fBadChannels
 set of bad channels in this detector More...
 
std::vector< uint32_t > fBadWireSum
 
HoughBaseAlg fHBAlg
 
DBScanAlg fDBScan
 
art::ServiceHandle< geo::GeometryfGeom
 handle to geometry service More...
 

Detailed Description

Definition at line 26 of file fuzzyClusterAlg.h.

Constructor & Destructor Documentation

cluster::fuzzyClusterAlg::fuzzyClusterAlg ( fhicl::ParameterSet const &  pset)

Definition at line 112 of file fuzzyClusterAlg.cxx.

References reconfigure().

113  : fHBAlg(pset.get< fhicl::ParameterSet >("HoughBaseAlg")),
114  fDBScan(pset.get< fhicl::ParameterSet >("DBScanAlg"))
115 
116 {
117  this->reconfigure(pset);
118 }
void reconfigure(fhicl::ParameterSet const &p)
cluster::fuzzyClusterAlg::~fuzzyClusterAlg ( )
virtual

Definition at line 121 of file fuzzyClusterAlg.cxx.

122 {
123 }

Member Function Documentation

double cluster::fuzzyClusterAlg::DistanceBetweenHits ( art::Ptr< recob::Hit hit0,
art::Ptr< recob::Hit hit1,
double  wire_dist,
double  tickToDist 
)
private

Definition at line 1410 of file fuzzyClusterAlg.cxx.

References recob::Hit::Channel(), norm, and recob::Hit::PeakTime().

Referenced by mergeShowerClusters(), mergeShowerTrackClusters(), and mergeTrackClusters().

1414 {
1415  const double pHit0[2] = {
1416  (hit0->Channel())*wire_dist,
1417  hit0->PeakTime()*tickToDist
1418  };
1419  const double pHit1[2] = {
1420  (hit1->Channel())*wire_dist,
1421  hit1->PeakTime()*tickToDist
1422  };
1423 
1424  return ::norm( pHit0[0] - pHit1[0], pHit0[1] - pHit1[1]);
1425 
1426 }
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
Float_t norm
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:231
double cluster::fuzzyClusterAlg::HoughLineDistance ( double  p0MinLine1,
double  p1MinLine1,
double  p0MaxLine1,
double  p1MaxLine1,
double  p0MinLine2,
double  p1MinLine2,
double  p0MaxLine2,
double  p1MaxLine2 
)
private

Definition at line 1431 of file fuzzyClusterAlg.cxx.

References HoughLineIntersect(), and PointSegmentDistance().

Referenced by mergeShowerClusters(), mergeShowerTrackClusters(), and mergeTrackClusters().

1439 {
1440  //distance between two segments in the plane:
1441  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
1442  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
1443  double x11 = p0MinLine1;
1444  double y11 = p1MinLine1;
1445  double x12 = p0MaxLine1;
1446  double y12 = p1MaxLine1;
1447  double x21 = p0MinLine2;
1448  double y21 = p1MinLine2;
1449  double x22 = p0MaxLine2;
1450  double y22 = p1MaxLine2;
1451 
1452  if(HoughLineIntersect(x11, y11, x12, y12, x21, y21, x22, y22)) return 0;
1453  // try each of the 4 vertices w/the other segment
1454  std::vector<double> distances;
1455  distances.push_back(PointSegmentDistance(x11, y11, x21, y21, x22, y22));
1456  distances.push_back(PointSegmentDistance(x12, y12, x21, y21, x22, y22));
1457  distances.push_back(PointSegmentDistance(x21, y21, x11, y11, x12, y12));
1458  distances.push_back(PointSegmentDistance(x22, y22, x11, y11, x12, y12));
1459 
1460  double minDistance = 999999;
1461  for(unsigned int j = 0; j < distances.size(); j++){
1462  if (distances[j] < minDistance)
1463  minDistance = distances[j];
1464  }
1465 
1466  return minDistance;
1467 
1468 }
bool HoughLineIntersect(double x11, double y11, double x12, double y12, double x21, double y21, double x22, double y22)
double PointSegmentDistance(double px, double py, double x1, double y1, double x2, double y2)
bool cluster::fuzzyClusterAlg::HoughLineIntersect ( double  x11,
double  y11,
double  x12,
double  y12,
double  x21,
double  y21,
double  x22,
double  y22 
)
private

Definition at line 1473 of file fuzzyClusterAlg.cxx.

References s.

Referenced by HoughLineDistance().

1481 {
1482  //whether two segments in the plane intersect:
1483  //one segment is (x11, y11) to (x12, y12)
1484  //the other is (x21, y21) to (x22, y22)
1485 
1486  double dx1 = x12 - x11; // x2-x1
1487  double dy1 = y12 - y11; // y2-y1
1488  double dx2 = x22 - x21; // x4-x3
1489  double dy2 = y22 - y21; // y4-y3
1490  //double delta = dx2*dy1 - dy2*dx1; // (x4-x3)(y2-y1) - (y4-y3)(x2-x1)
1491  double delta = dy2*dx1 - dx2*dy1; // (y4-y3)(x2-x1) - (x4-x3)(y2-y1)
1492  if (delta == 0) return false; // parallel segments
1493 
1494  double t = (dx2*(y11 - y21) + dy2*(x21 - x11)) / delta; // ua
1495  double s = (dx1*(y11 - y21) + dy1*(x21 - x11)) / delta; // ub
1496 
1497  return (0 <= s && s <= 1 && 0 <= t && t <= 1);
1498 
1499 }
Float_t s
Definition: plot.C:23
void cluster::fuzzyClusterAlg::InitFuzzy ( std::vector< art::Ptr< recob::Hit > > &  allhits,
std::set< uint32_t >  badChannels 
)

Definition at line 154 of file fuzzyClusterAlg.cxx.

References geo::GeometryCore::Cryostat(), detinfo::DetectorProperties::DriftVelocity(), detinfo::DetectorProperties::Efield(), fBadChannels, fBadWireSum, fclusters, fMaxWidth, fnoise, fpointId_to_clusterId, fps, fsim, fsim2, fsim3, fvisited, fWirePitch, detinfo::DetectorProperties::SamplingRate(), detinfo::DetectorProperties::Temperature(), and geo::CryostatGeo::TPC().

Referenced by cluster::fuzzyCluster::produce().

156 {
157  // clear all the data member vectors for the new set of hits
158  fps.clear();
159  fpointId_to_clusterId.clear();
160  fnoise.clear();
161  fvisited.clear();
162  fsim.clear();
163  fsim2.clear();
164  fsim3.clear();
165  fclusters.clear();
166  fWirePitch.clear();
167 
168  fBadChannels = badChannels;
169  fBadWireSum.clear();
170 
171  const detinfo::DetectorProperties* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
173 
174 
175  unsigned int cs=allhits[0]->WireID().Cryostat;
176  unsigned int t=allhits[0]->WireID().TPC;
177 
178  fWirePitch.resize(geom->Nplanes(t, cs), 0.);
179  for (size_t p = 0; p < fWirePitch.size(); ++p) {
180  fWirePitch[p] = geom->WirePitch(p);
181  }
182 
183 
184 
185  // Collect the hits in a useful form,
186  // and take note of the maximum time width
187  fMaxWidth=0.0;
188 
189  double tickToDist = detp->DriftVelocity(detp->Efield(),detp->Temperature());
190  tickToDist *= 1.e-3 * detp->SamplingRate(); // 1e-3 is conversion of 1/us to 1/ns
191  int dims = 3;//our point is defined by 3 elements:wire#,center of the hit, and the hit width
192  std::vector<double> p(dims);
193  for (auto allhitsItr = allhits.begin(); allhitsItr < allhits.end(); allhitsItr++){
194 
195  p[0] = ((*allhitsItr)->WireID().Wire)*fWirePitch[(*allhitsItr)->WireID().Plane];
196  p[1] = (*allhitsItr)->PeakTime()*tickToDist;
197  p[2] = (*allhitsItr)->Integral(); //width of a hit in cm
198 
199  // check on the maximum width condition
200  if ( p[2] > fMaxWidth ) fMaxWidth = p[2];
201 
202  fps.push_back(p);
203 
204  }
205 
206  mf::LogInfo("fuzzyCluster") << "Initfuzzy: hits vector size is " << fps.size();
207 
208  return;
209 }
std::vector< std::vector< double > > fsim3
std::vector< bool > fnoise
std::vector< bool > fvisited
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< std::vector< double > > fsim2
std::set< uint32_t > fBadChannels
set of bad channels in this detector
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
std::vector< std::vector< double > > fsim
virtual double Temperature() const =0
std::vector< uint32_t > fBadWireSum
std::vector< std::vector< double > > fps
the collection of points we are working on
std::vector< unsigned int > fpointId_to_clusterId
mapping point_id -> clusterId
std::vector< double > fWirePitch
the pitch of the wires in each plane
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
std::vector< std::vector< unsigned int > > fclusters
collection of something
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
void cluster::fuzzyClusterAlg::mergeHoughLinesBySegment ( unsigned int  k,
std::vector< protoTrack > *  protoTracks,
double  xyScale,
int  mergeStyle,
double  wire_dist,
double  tickToDist 
)
private
bool cluster::fuzzyClusterAlg::mergeShowerClusters ( unsigned int  k,
std::vector< showerCluster > *  showerClusters,
double  xyScale,
double  wire_dist,
double  tickToDist 
)
private

Definition at line 1212 of file fuzzyClusterAlg.cxx.

References DistanceBetweenHits(), fShowerClusterMergeAngle, fShowerClusterMergeCutoff, HoughLineDistance(), and norm.

Referenced by run_fuzzy_cluster().

1217 {
1218 
1219  // If we have zero or one Hough lines, move on
1220  if(showerClusters->size() == 0 || showerClusters->size() == 1)
1221  return false;
1222 
1223  // If we reach the last Hough line, move on
1224  if(showerClusters->size() == clusIndexStart+1)
1225  return false;
1226 
1227  std::vector<unsigned int> toMerge;
1228  std::vector<double> mergeSlope;
1229  std::vector<double> mergeTheta;
1230 
1231  // toMerge trackCluster index, toMerge trackCluster proto track index
1232  //bool potentialBestMerge=false;
1233  bool performedBestMerge=false;
1234  unsigned int bestToMergeShowerCluster;
1235  unsigned int bestShowerClustersClusIndexStartProtoTrack;
1236  unsigned int bestToMergeShowerClusterProtoTrack;
1237  int bestToMergeRightLeft = -1;
1238  //int bestClusIndexStartRightLeft = -1;
1239  double bestToMergeShowerClusterProtoTrackDistance=999999;
1240 
1241 
1242  for(auto showerClustersClusIndexStartProtoTrackItr = showerClusters->at(clusIndexStart).clusterProtoTracks.begin();
1243  showerClustersClusIndexStartProtoTrackItr != showerClusters->at(clusIndexStart).clusterProtoTracks.end();
1244  ++showerClustersClusIndexStartProtoTrackItr){
1245 
1246  for(auto showerClustersToMergeItr = showerClusters->begin()+clusIndexStart+1; showerClustersToMergeItr != showerClusters->end(); ++showerClustersToMergeItr){
1247  //std::cout << "Made it here" << std::endl;
1248 
1249  toMerge.clear();
1250  mergeSlope.clear();
1251  mergeTheta.clear();
1252 
1253  for(auto showerClustersToMergeProtoTrackItr = showerClustersToMergeItr->clusterProtoTracks.begin();
1254  showerClustersToMergeProtoTrackItr != showerClustersToMergeItr->clusterProtoTracks.end();
1255  ++showerClustersToMergeProtoTrackItr){
1256 
1257  if(showerClustersToMergeProtoTrackItr->clusterNumber == showerClustersClusIndexStartProtoTrackItr->clusterNumber)
1258  continue;
1259 
1260 
1261  double segmentDistance = HoughLineDistance(showerClustersClusIndexStartProtoTrackItr->pMin0,showerClustersClusIndexStartProtoTrackItr->pMin1,
1262  showerClustersClusIndexStartProtoTrackItr->pMax0,showerClustersClusIndexStartProtoTrackItr->pMax1,
1263  showerClustersToMergeProtoTrackItr->pMin0,showerClustersToMergeProtoTrackItr->pMin1,
1264  showerClustersToMergeProtoTrackItr->pMax0,showerClustersToMergeProtoTrackItr->pMax1);
1265  if(segmentDistance<fShowerClusterMergeCutoff)
1266  {
1267  toMerge.push_back(showerClustersToMergeProtoTrackItr-showerClustersToMergeItr->clusterProtoTracks.begin());
1268  mergeSlope.push_back(showerClustersClusIndexStartProtoTrackItr->clusterSlope*xyScale);
1269  }
1270 
1271  }// End of loop over showerClustersToMergeItr->clusterProtoTracks.begin()
1272 
1273 
1274  mergeTheta.resize(toMerge.size());
1275 
1276  // Find the angle between the slopes
1277  for(auto mergeThetaItr = mergeTheta.begin(); mergeThetaItr != mergeTheta.end(); ++mergeThetaItr){
1278  double toMergeSlope = showerClustersToMergeItr->clusterProtoTracks[toMerge[mergeThetaItr-mergeTheta.begin()]].clusterSlope*xyScale;
1279  mergeTheta[mergeThetaItr-mergeTheta.begin()] = std::atan(std::abs(( toMergeSlope - mergeSlope[mergeThetaItr-mergeTheta.begin()])/(1 + toMergeSlope*mergeSlope[mergeThetaItr-mergeTheta.begin()] )))*(180/TMath::Pi());
1280  }
1281 
1282 
1283  // Perform the merge
1284  for(auto toMergeItr = toMerge.begin(); toMergeItr != toMerge.end(); ++toMergeItr){
1285 
1286  // Apply the angle cut
1287  if(mergeTheta[toMergeItr-toMerge.begin()] > fShowerClusterMergeAngle)
1288  continue;
1289 
1290  // Find the closest distance
1291  //int closestToMerge=-1;
1292  //int closestClusIndexStart=-1;
1293  double closestDistance=999999;
1294  for (auto toMergeHitItr = showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin(); toMergeHitItr != showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.end(); ++toMergeHitItr) {
1295  for (auto clusIndStHitItr = showerClustersClusIndexStartProtoTrackItr->hits.begin(); clusIndStHitItr != showerClustersClusIndexStartProtoTrackItr->hits.end(); ++clusIndStHitItr) {
1296  //double distance = ::norm(clusIndStHitItr->first-(*toMergeHitItr).first+
1297  //clusIndStHitItr->second-toMergeHitItr->second);
1298 
1299  double distance = DistanceBetweenHits(*clusIndStHitItr,
1300  *toMergeHitItr,
1301  wire_dist,
1302  tickToDist);
1303  if(distance < closestDistance){
1304  closestDistance = distance;
1305  //closestToMerge=toMergeHitItr-showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin();
1306  //closestClusIndexStart=clusIndStHitItr-showerClustersClusIndexStartProtoTrackItr->hits.begin();
1307  }
1308  }
1309  }
1310 
1311 
1312  // Veto the merge if the lines are not colinear
1313 
1314  //distance between two segments in the plane:
1315  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
1316  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
1317  double x11 = showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMin0;
1318  double y11 = showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMin1;
1319  double x12 = showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMax0;
1320  double y12 = showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMax1;
1321  double x21 = showerClustersClusIndexStartProtoTrackItr->pMin0;
1322  double y21 = showerClustersClusIndexStartProtoTrackItr->pMin1;
1323  double x22 = showerClustersClusIndexStartProtoTrackItr->pMax0;
1324  double y22 = showerClustersClusIndexStartProtoTrackItr->pMax1;
1325  // BUG the double brace syntax is required to work around clang bug 21629
1326  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1327  std::array<double, 4> distances = {{
1328  // Compare toMergerItr min with clusIndexStart min, if this is the min distance, lines are not colinear, merge is vetoed
1329  ::norm(x11-x21, y11-y21),
1330  ::norm(x11-x22, y11-y22), // Compare toMergerItr min with clusIndexStart max
1331  ::norm(x12-x21, y12-y21), // Compare toMergerItr max with clusIndexStart min
1332  // Compare toMergerItr max with clusIndexStart max, if this is the min distance, lines are not colinear, merge is vetoed
1333  ::norm(x12-x22, y12-y22)
1334  }}; // distances
1335 
1336  double minDistance = 999999;
1337  int minDistanceIndex = -1;
1338  for(unsigned int j = 0; j < distances.size(); ++j){
1339  if (distances[j] < minDistance){
1340  minDistance = distances[j];
1341  minDistanceIndex = j;
1342  }
1343  }
1344 
1345  if(minDistanceIndex == 0 || minDistanceIndex == 3)
1346  continue;
1347 
1348 
1349 
1350  // Check if we merged left or right already for clusIndexStart, we only do it once for each side
1351  //if(showerClustersClusIndexStartProtoTrackItr->mergedLeft == true && minDistanceIndex == 2)
1352  //continue;
1353  //if(showerClustersClusIndexStartProtoTrackItr->mergedRight == true && minDistanceIndex == 1)
1354  //continue;
1355  //if(showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedLeft == true && minDistanceIndex == 1)
1356  //continue;
1357  //if(showerClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedRight == true && minDistanceIndex == 2)
1358  //continue;
1359 
1360  //std::cout << "Potential merge" << std::endl;
1361  //std::cout << "main showerClustersItr slope: " << showerClusters->at(*toMergeItr).clusterSlope << " clusIndexStart slope: " << showerClusters->at(clusIndexStart).clusterSlope << std::endl;
1362  performedBestMerge=true;
1363 
1364 
1365  if(closestDistance < bestToMergeShowerClusterProtoTrackDistance){
1366  bestToMergeShowerCluster=showerClustersToMergeItr-showerClusters->begin();
1367  bestToMergeShowerClusterProtoTrack=*toMergeItr;
1368  bestShowerClustersClusIndexStartProtoTrack=showerClustersClusIndexStartProtoTrackItr-showerClusters->at(clusIndexStart).clusterProtoTracks.begin();
1369  // Did we merge left (0) or right (1)?
1370  if(minDistanceIndex == 1){
1371  bestToMergeRightLeft = 0;
1372  //bestClusIndexStartRightLeft = 1;
1373  }
1374  if(minDistanceIndex == 2){
1375  bestToMergeRightLeft = 1;
1376  //bestClusIndexStartRightLeft = 0;
1377  }
1378 
1379  }
1380 
1381  }// End of loop over toMerge
1382  }// End of loop over showerClusters->begin()+clusIndexStart+1
1383  }//End of loop over showerClusters->at(clusIndexStart).clusterProtoTracks
1384 
1385  if(performedBestMerge){
1386  showerClusters->at(bestToMergeShowerCluster).clusterProtoTracks[bestToMergeShowerClusterProtoTrack].merged=true;
1387  showerClusters->at(clusIndexStart).clusterProtoTracks[bestShowerClustersClusIndexStartProtoTrack].merged=true;
1388  if(bestToMergeRightLeft == 0){
1389  showerClusters->at(bestToMergeShowerCluster).clusterProtoTracks[bestToMergeShowerClusterProtoTrack].mergedLeft = true;
1390  showerClusters->at(clusIndexStart).clusterProtoTracks[bestShowerClustersClusIndexStartProtoTrack].mergedRight = true;
1391  }
1392  if(bestToMergeRightLeft == 1){
1393  showerClusters->at(bestToMergeShowerCluster).clusterProtoTracks[bestToMergeShowerClusterProtoTrack].mergedRight = true;
1394  showerClusters->at(clusIndexStart).clusterProtoTracks[bestShowerClustersClusIndexStartProtoTrack].mergedLeft = true;
1395  }
1396 
1397  showerClusters->at(clusIndexStart).addProtoTracks(showerClusters->at(bestToMergeShowerCluster).clusterProtoTracks);
1398  showerClusters->at(bestToMergeShowerCluster).clearProtoTracks();
1399  //std::cout << "Merged shower-shower" << std::endl;
1400 
1401  }
1402 
1403  return performedBestMerge;
1404 
1405 }
double HoughLineDistance(double p0MinLine1, double p1MinLine1, double p0MaxLine1, double p1MaxLine1, double p0MinLine2, double p1MinLine2, double p0MaxLine2, double p1MaxLine2)
double fShowerClusterMergeAngle
Max angle between slopes before two lines are merged, for lines in shower line regions.
Float_t norm
double fShowerClusterMergeCutoff
Max distance between Hough lines before two lines are merged (electron showers),. ...
double DistanceBetweenHits(art::Ptr< recob::Hit > hit0, art::Ptr< recob::Hit > hit1, double wire_dist, double tickToDist)
bool cluster::fuzzyClusterAlg::mergeShowerTrackClusters ( showerCluster showerClusterI,
trackCluster trackClusterJ,
double  xyScale,
double  wire_dist,
double  tickToDist 
)
private

Definition at line 588 of file fuzzyClusterAlg.cxx.

References cluster::fuzzyClusterAlg::baseCluster::addProtoTracks(), cluster::fuzzyClusterAlg::baseCluster::clearProtoTracks(), cluster::fuzzyClusterAlg::baseCluster::clusterProtoTracks, DistanceBetweenHits(), fMaxVertexLines, fShowerTrackClusterMergeAngle, fShowerTrackClusterMergeCutoff, fVertexLinesCutoff, HoughLineDistance(), and norm.

Referenced by run_fuzzy_cluster().

593 {
594 
595  // If we have zero or one Hough lines, move on
596  //if(trackCluster->size() == 0 || trackCluster->size() == 1)
597  //return false;
598 
600  //if(trackCluster->size() == clusIndexStart+1)
601  //return false;
602 
603  std::vector<unsigned int> toMerge;
604  std::vector<double> mergeSlope;
605  std::vector<double> mergeTheta;
606 
607  // toMerge trackCluster index, toMerge trackCluster proto track index
608  bool potentialBestMerge=false;
609  bool performedBestMerge=false;
610  unsigned int bestTrackClusterProtoTrack;
611  unsigned int bestShowerClusterProtoTrack;
612  // Did we merge left (0) or right (1)?
613  int bestShowerRightLeft = -1;
614  //int bestClusIndexStartRightLeft = -1;
615  double bestToMergeTrackClusterProtoTrackDistance=999999;
616  double x11;
617  double y11;
618  double x12;
619  double y12;
620  double x21;
621  double y21;
622  double x22;
623  double y22;
624 
625  for(auto trackClusterProtoTrackItr = trackClusterJ->clusterProtoTracks.begin();
626  trackClusterProtoTrackItr != trackClusterJ->clusterProtoTracks.end();
627  trackClusterProtoTrackItr++){
628 
629  //for(auto trackClustersToMergeItr = trackClusters->begin()+clusIndexStart+1; trackClustersToMergeItr != trackClusters->end(); trackClustersToMergeItr++){
630  //if(trackClusters->at(clusIndexStart).clusterNumber == trackClustersToMergeItr->clusterNumber)
631  //continue;
632  //std::cout << "Made it here" << std::endl;
633 
634  toMerge.clear();
635  mergeSlope.clear();
636  mergeTheta.clear();
637 
638  //Count up how many lines are in merging distance to clusIndexStartProtoTrackItr
639  int nInDistanceTrackClusterLeft = 1;
640  int nInDistanceTrackClusterRight = 1;
641 
642 
643 
644  for(auto showerClusterProtoTrackItr = showerClusterI->clusterProtoTracks.begin();
645  showerClusterProtoTrackItr != showerClusterI->clusterProtoTracks.end();
646  ++showerClusterProtoTrackItr){
647 
648  double segmentDistance = HoughLineDistance(trackClusterProtoTrackItr->pMin0,trackClusterProtoTrackItr->pMin1,
649  trackClusterProtoTrackItr->pMax0,trackClusterProtoTrackItr->pMax1,
650  showerClusterProtoTrackItr->pMin0,showerClusterProtoTrackItr->pMin1,
651  showerClusterProtoTrackItr->pMax0,showerClusterProtoTrackItr->pMax1);
652  if(segmentDistance<fShowerTrackClusterMergeCutoff)
653  {
654  toMerge.push_back(showerClusterProtoTrackItr-showerClusterI->clusterProtoTracks.begin());
655  mergeSlope.push_back(trackClusterProtoTrackItr->clusterSlope*xyScale);
656 
657 
658  // Sum up number of protoTracks at the vertex
659  //distance between two segments in the plane:
660  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
661  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
662  double x11 = showerClusterProtoTrackItr->pMin0;
663  double y11 = showerClusterProtoTrackItr->pMin1;
664  double x12 = showerClusterProtoTrackItr->pMax0;
665  double y12 = showerClusterProtoTrackItr->pMax1;
666  double x21 = trackClusterProtoTrackItr->pMin0;
667  double y21 = trackClusterProtoTrackItr->pMin1;
668  double x22 = trackClusterProtoTrackItr->pMax0;
669  double y22 = trackClusterProtoTrackItr->pMax1;
670 
671  // Compare toMergerItr min with clusIndexStart max
672  double mergeRightClusIndexStartDist = ::norm(x11-x22, y11-y22);
673  // Compare toMergerItr max with clusIndexStart min
674  double mergeLeftClusIndexStartDist = ::norm(x12-x21, y12-y21);
675 
676  // Are we inside the vertex distance? This is smaller than the merge cutoff
677  if(segmentDistance < fVertexLinesCutoff){
678  if( mergeRightClusIndexStartDist > mergeLeftClusIndexStartDist )
679  ++nInDistanceTrackClusterLeft;
680  else
681  ++nInDistanceTrackClusterRight;
682  }
683 
684 
685  }
686 
687  }// End of loop over trackClustersToMergeItr->clusterProtoTracks.begin()
688 
689 
690  mergeTheta.resize(toMerge.size());
691 
692  // Find the angle between the slopes
693  for(auto mergeThetaItr = mergeTheta.begin(); mergeThetaItr != mergeTheta.end(); ++mergeThetaItr){
694  double toMergeSlope = showerClusterI->clusterProtoTracks[toMerge[mergeThetaItr-mergeTheta.begin()]].clusterSlope*xyScale;
695  mergeTheta[mergeThetaItr-mergeTheta.begin()] = std::atan(std::abs(( toMergeSlope - mergeSlope[mergeThetaItr-mergeTheta.begin()])/(1 + toMergeSlope*mergeSlope[mergeThetaItr-mergeTheta.begin()] )))*(180/TMath::Pi());
696  }
697 
698 
699  // Perform the merge
700  for(auto toMergeItr = toMerge.begin(); toMergeItr != toMerge.end(); toMergeItr++){
701 
702  // Apply the angle cut
703  if(mergeTheta[toMergeItr-toMerge.begin()] > fShowerTrackClusterMergeAngle)
704  continue;
705 
706  // First check averages of charge and sigma charge for hits in lines closest to each other
707  //int closestShower=-1;
708  //int closestTrack=-1;
709  double closestDistance=999999;
710  for (auto showerClusterProtoTrackHitItr = showerClusterI->clusterProtoTracks[*toMergeItr].hits.begin(); showerClusterProtoTrackHitItr != showerClusterI->clusterProtoTracks[*toMergeItr].hits.end(); ++showerClusterProtoTrackHitItr) {
711  for (auto trackClusterProtoTrackHitItr = trackClusterProtoTrackItr->hits.begin(); trackClusterProtoTrackHitItr != trackClusterProtoTrackItr->hits.end(); trackClusterProtoTrackHitItr++) {
712  //double distance = ::norm(clusIndStHitItr->first-(*toMergeHitItr).first,
713  // clusIndStHitItr->second-toMergeHitItr->second);
714 
715  double distance = DistanceBetweenHits(*trackClusterProtoTrackHitItr,
716  *showerClusterProtoTrackHitItr,
717  wire_dist,
718  tickToDist);
719  if(distance < closestDistance){
720  closestDistance = distance;
721  //closestShower=showerClusterProtoTrackHitItr-showerClusterI->clusterProtoTracks[*toMergeItr].hits.begin();
722  //closestTrack=trackClusterProtoTrackHitItr-trackClusterProtoTrackItr->hits.begin();
723  }
724  }
725  }
726 
727 
728  // Veto the merge if the lines are not colinear
729 
730  //distance between two segments in the plane:
731  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
732  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
733  x11 = showerClusterI->clusterProtoTracks[*toMergeItr].pMin0;
734  y11 = showerClusterI->clusterProtoTracks[*toMergeItr].pMin1;
735  x12 = showerClusterI->clusterProtoTracks[*toMergeItr].pMax0;
736  y12 = showerClusterI->clusterProtoTracks[*toMergeItr].pMax1;
737  x21 = trackClusterProtoTrackItr->pMin0;
738  y21 = trackClusterProtoTrackItr->pMin1;
739  x22 = trackClusterProtoTrackItr->pMax0;
740  y22 = trackClusterProtoTrackItr->pMax1;
741  // BUG the double brace syntax is required to work around clang bug 21629
742  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
743  std::array<double, 4> distances = {{
744  // Compare toMergerItr min with clusIndexStart min, if this is the min distance, lines are not colinear, merge is vetoed
745  ::norm(x11-x21, y11-y21),
746  ::norm(x11-x22, y11-y22), // Compare toMergerItr min with clusIndexStart max
747  ::norm(x12-x21, y12-y21), // Compare toMergerItr max with clusIndexStart min
748  // Compare toMergerItr max with clusIndexStart max, if this is the min distance, lines are not colinear, merge is vetoed
749  ::norm(x12-x22, y12-y22)
750  }}; // distances
751 
752  double minDistance = 999999;
753  int minDistanceIndex = -1;
754  for(unsigned int j = 0; j < distances.size(); j++){
755  if (distances[j] < minDistance){
756  minDistance = distances[j];
757  minDistanceIndex = j;
758  }
759  }
760 
761  if(minDistanceIndex == 0 || minDistanceIndex == 3)
762  continue;
763 
764  // How many lines do we have at the merging point? If too many, veto the merge
765  //std::cout << nInDistanceTrackClusterLeft << " " << nInDistanceTrackClusterRight << std::endl;
766 
767  if(nInDistanceTrackClusterLeft > fMaxVertexLines) {
768  trackClusterProtoTrackItr->mergedLeft = true;
769  showerClusterI->clusterProtoTracks[*toMergeItr].mergedRight = true;
770  }
771  if(nInDistanceTrackClusterRight > fMaxVertexLines) {
772  trackClusterProtoTrackItr->mergedRight = true;
773  showerClusterI->clusterProtoTracks[*toMergeItr].mergedLeft = true;
774  }
775 
776 
777  // Check if we merged left or right already for clusIndexStart, we only do it once for each side
778  //if(trackClusterProtoTrackItr->mergedLeft == true && minDistanceIndex == 2)
779  //continue;
780  //if(trackClusterProtoTrackItr->mergedRight == true && minDistanceIndex == 1)
781  //continue;
782  //if(showerClusterI->clusterProtoTracks[*toMergeItr].mergedLeft == true && minDistanceIndex == 1)
783  //continue;
784  //if(showerClusterI->clusterProtoTracks[*toMergeItr].mergedRight == true && minDistanceIndex == 2)
785  //continue;
786 
787  //std::cout << "Potential merge" << std::endl;
788  //std::cout << "main trackClustersItr slope: " << trackClusters->at(*toMergeItr).clusterSlope << " clusIndexStart slope: " << trackClusters->at(clusIndexStart).clusterSlope << std::endl;
789  potentialBestMerge=true;
790 
791 
792  if(minDistance < bestToMergeTrackClusterProtoTrackDistance){
793  bestShowerClusterProtoTrack=*toMergeItr;
794  bestTrackClusterProtoTrack=trackClusterProtoTrackItr-trackClusterJ->clusterProtoTracks.begin();
795 
796  bestToMergeTrackClusterProtoTrackDistance=minDistance;
797 
798  // Did we merge left (0) or right (1)?
799  if(minDistanceIndex == 1){
800  bestShowerRightLeft = 0;
801  //bestClusIndexStartRightLeft = 1;
802  }
803  if(minDistanceIndex == 2){
804  bestShowerRightLeft = 1;
805  //bestClusIndexStartRightLeft = 0;
806  }
807 
808  }
809 
810  }// End of loop over toMerge
811  //}// End of loop over trackClusters->begin()+clusIndexStart+1
812  }//End of loop over trackClusters->at(clusIndexStart).clusterProtoTracks
813 
814  if(potentialBestMerge){
815  showerClusterI->clusterProtoTracks[bestShowerClusterProtoTrack].merged=true;
816  trackClusterJ->clusterProtoTracks[bestTrackClusterProtoTrack].merged=true;
817  if(bestShowerRightLeft == 0){
818  showerClusterI->clusterProtoTracks[bestShowerClusterProtoTrack].mergedLeft = true;
819  trackClusterJ->clusterProtoTracks[bestTrackClusterProtoTrack].mergedRight = true;
820  performedBestMerge=true;
821  }
822  if(bestShowerRightLeft == 1){
823  showerClusterI->clusterProtoTracks[bestShowerClusterProtoTrack].mergedRight = true;
824  trackClusterJ->clusterProtoTracks[bestTrackClusterProtoTrack].mergedLeft = true;
825  performedBestMerge=true;
826  }
827 
828  if(performedBestMerge){
829  showerClusterI->addProtoTracks(trackClusterJ->clusterProtoTracks);
830  trackClusterJ->clearProtoTracks();
831  //std::cout << "Merged shower-track" << std::endl;
832  }
833 
834  }
835 
836 
837 
838  return performedBestMerge;
839 
840 }
int fMaxVertexLines
Max number of line end points allowed in a Hough line merge region for a merge to happen...
double fShowerTrackClusterMergeAngle
Max angle between slopes before two lines are merged, for lines in shower line regions.
double HoughLineDistance(double p0MinLine1, double p1MinLine1, double p0MaxLine1, double p1MaxLine1, double p0MinLine2, double p1MinLine2, double p0MaxLine2, double p1MaxLine2)
Float_t norm
double fShowerTrackClusterMergeCutoff
Max distance between Hough lines before two lines are merged (electron showers),. ...
double fVertexLinesCutoff
Size of the vertex region to count up lines for fMaxVertexLines.
double DistanceBetweenHits(art::Ptr< recob::Hit > hit0, art::Ptr< recob::Hit > hit1, double wire_dist, double tickToDist)
bool cluster::fuzzyClusterAlg::mergeTrackClusters ( unsigned int  k,
std::vector< trackCluster > *  trackClusters,
double  xyScale,
double  wire_dist,
double  tickToDist 
)
private

Definition at line 845 of file fuzzyClusterAlg.cxx.

References DistanceBetweenHits(), fChargeAsymAngleCut, fMaxVertexLines, fSigmaChargeAsymAngleCut, fTrackClusterMergeCutoff, fVertexLinesCutoff, HoughLineDistance(), norm, and geo::sqr().

Referenced by run_fuzzy_cluster().

850 {
851 
852 
853 
854  // If we have zero or one Hough lines, move on
855  if(trackClusters->size() == 0 || trackClusters->size() == 1)
856  return false;
857 
858  // If we reach the last Hough line, move on
859  if(trackClusters->size() == clusIndexStart+1)
860  return false;
861 
862  std::vector<unsigned int> toMerge;
863  std::vector<double> mergeSlope;
864  std::vector<double> mergeTheta;
865 
866  // toMerge trackCluster index, toMerge trackCluster proto track index
867  bool potentialBestMerge=false;
868  bool performedBestMerge=false;
869  unsigned int bestToMergeTrackCluster;
870  unsigned int bestTrackClustersClusIndexStartProtoTrack;
871  unsigned int bestToMergeTrackClusterProtoTrack;
872  // Did we merge left (0) or right (1)?
873  int bestToMergeRightLeft = -1;
874  //int bestClusIndexStartRightLeft = -1;
875  double bestToMergeTrackClusterProtoTrackDistance=999999;
876 
877  for(auto trackClustersClusIndexStartProtoTrackItr = trackClusters->at(clusIndexStart).clusterProtoTracks.begin();
878  trackClustersClusIndexStartProtoTrackItr != trackClusters->at(clusIndexStart).clusterProtoTracks.end();
879  ++trackClustersClusIndexStartProtoTrackItr){
880 
881  //Count up how many lines are in merging distance to clusIndexStartProtoTrackItr
882  int nInDistanceClusIndexStartLeft = 1;
883  int nInDistanceClusIndexStartRight = 1;
884 
885 
886  for(auto trackClustersToMergeItr = trackClusters->begin()+clusIndexStart+1; trackClustersToMergeItr != trackClusters->end(); trackClustersToMergeItr++){
887  if(trackClusters->at(clusIndexStart).clusterNumber == trackClustersToMergeItr->clusterNumber)
888  continue;
889  //std::cout << "Made it here" << std::endl;
890 
891  toMerge.clear();
892  mergeSlope.clear();
893  mergeTheta.clear();
894 
895  for(auto trackClustersToMergeProtoTrackItr = trackClustersToMergeItr->clusterProtoTracks.begin();
896  trackClustersToMergeProtoTrackItr != trackClustersToMergeItr->clusterProtoTracks.end();
897  ++trackClustersToMergeProtoTrackItr){
898 
899  double segmentDistance = HoughLineDistance(trackClustersClusIndexStartProtoTrackItr->pMin0,trackClustersClusIndexStartProtoTrackItr->pMin1,
900  trackClustersClusIndexStartProtoTrackItr->pMax0,trackClustersClusIndexStartProtoTrackItr->pMax1,
901  trackClustersToMergeProtoTrackItr->pMin0,trackClustersToMergeProtoTrackItr->pMin1,
902  trackClustersToMergeProtoTrackItr->pMax0,trackClustersToMergeProtoTrackItr->pMax1);
903  if(segmentDistance<fTrackClusterMergeCutoff)
904  {
905  toMerge.push_back(trackClustersToMergeProtoTrackItr-trackClustersToMergeItr->clusterProtoTracks.begin());
906  mergeSlope.push_back(trackClustersClusIndexStartProtoTrackItr->clusterSlope*xyScale);
907 
908 
909  // Sum up number of protoTracks at the vertex
910  //distance between two segments in the plane:
911  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
912  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
913  double x11 = trackClustersToMergeProtoTrackItr->pMin0;
914  double y11 = trackClustersToMergeProtoTrackItr->pMin1;
915  double x12 = trackClustersToMergeProtoTrackItr->pMax0;
916  double y12 = trackClustersToMergeProtoTrackItr->pMax1;
917  double x21 = trackClustersClusIndexStartProtoTrackItr->pMin0;
918  double y21 = trackClustersClusIndexStartProtoTrackItr->pMin1;
919  double x22 = trackClustersClusIndexStartProtoTrackItr->pMax0;
920  double y22 = trackClustersClusIndexStartProtoTrackItr->pMax1;
921 
922  // Compare toMergerItr min with clusIndexStart max
923  double mergeRightClusIndexStartDist = std::sqrt(sqr(x11-x22) + sqr(y11-y22));
924  // Compare toMergerItr max with clusIndexStart min
925  double mergeLeftClusIndexStartDist = std::sqrt(sqr(x12-x21) + sqr(y12-y21));
926 
927  // Are we inside the vertex distance? This is smaller than the merge cutoff
928  if(segmentDistance < fVertexLinesCutoff){
929  if( mergeRightClusIndexStartDist > mergeLeftClusIndexStartDist )
930  nInDistanceClusIndexStartLeft++;
931  else
932  nInDistanceClusIndexStartRight++;
933  }
934  }
935 
936  }// End of loop over trackClustersToMergeItr->clusterProtoTracks.begin()
937 
938 
939  mergeTheta.resize(toMerge.size());
940 
941  // Find the angle between the slopes
942  for(auto mergeThetaItr = mergeTheta.begin(); mergeThetaItr != mergeTheta.end(); ++mergeThetaItr){
943  double toMergeSlope = trackClustersToMergeItr->clusterProtoTracks[toMerge[mergeThetaItr-mergeTheta.begin()]].clusterSlope*xyScale;
944  mergeTheta[mergeThetaItr-mergeTheta.begin()] = std::atan(std::abs(( toMergeSlope - mergeSlope[mergeThetaItr-mergeTheta.begin()])/(1 + toMergeSlope*mergeSlope[mergeThetaItr-mergeTheta.begin()] )))*(180/TMath::Pi());
945  }
946 
947 
948  // Perform the merge
949  for(auto toMergeItr = toMerge.begin(); toMergeItr != toMerge.end(); toMergeItr++){
950 
951  // First check averages of charge and sigma charge for hits in lines closest to each other
952  int closestToMerge=-1;
953  int closestClusIndexStart=-1;
954  double closestDistance=999999;
955  for (auto toMergeHitItr = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin(); toMergeHitItr != trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.end(); toMergeHitItr++) {
956  for (auto clusIndStHitItr = trackClustersClusIndexStartProtoTrackItr->hits.begin(); clusIndStHitItr != trackClustersClusIndexStartProtoTrackItr->hits.end(); clusIndStHitItr++) {
957  //double distance = std::sqrt(sqr(clusIndStHitItr->first-(*toMergeHitItr).first)+
958  //sqr(clusIndStHitItr->second-toMergeHitItr->second));
959 
960  double distance = DistanceBetweenHits(*clusIndStHitItr,
961  *toMergeHitItr,
962  wire_dist,
963  tickToDist);
964  if(distance < closestDistance){
965  closestDistance = distance;
966  closestToMerge=toMergeHitItr-trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin();
967  closestClusIndexStart=clusIndStHitItr-trackClustersClusIndexStartProtoTrackItr->hits.begin();
968  }
969  }
970  }
971 
972  // Find up to 9 more points closest to closestToMerge on the toMerge[i] line
973  // check if it's closer, insert, delete
974  using Pair_I_D = std::pair<int,double>;
975  std::vector<Pair_I_D> closestToMergeDist;
976  for (auto toMergeHitItr = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin(); toMergeHitItr != trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.end(); ++toMergeHitItr) {
977  if(closestToMerge==toMergeHitItr-trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin())
978  continue;
979  double distance = DistanceBetweenHits(trackClustersClusIndexStartProtoTrackItr->hits[closestClusIndexStart],
980  *toMergeHitItr,
981  wire_dist,
982  tickToDist);
983 
984  bool foundCloser = false;
985  for(auto closestToMergeDistItr = closestToMergeDist.begin(); closestToMergeDistItr != closestToMergeDist.end(); closestToMergeDistItr++) {
986  if(closestToMergeDistItr->second > distance){
987  foundCloser = true;
988  break;
989  }
990  }
991  if(foundCloser
992  || closestToMergeDist.size() < trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.size()-1
993  || closestToMergeDist.size() < 9){
994  closestToMergeDist.emplace_back(toMergeHitItr-trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.begin(),distance);
995  std::sort(closestToMergeDist.begin(), closestToMergeDist.end(),
996  [](const Pair_I_D& a, const Pair_I_D& b){ return a.second < b.second; }
997  );
998  // std::sort(closestToMergeDist.begin(), closestToMergeDist.end(), boost::bind(&std::pair<int,double>::second,_1) < boost::bind(&std::pair<int,double>::second,_2));
999  }
1000  if(closestToMergeDist.size() > trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits.size()-1 ||
1001  closestToMergeDist.size() > 9)
1002  closestToMergeDist.erase(closestToMergeDist.end());
1003  }
1004  //for(auto closestToMergeDistItr = closestToMergeDist.begin(); closestToMergeDistItr != closestToMergeDist.end();
1005  //closestToMergeDistItr++)
1006  //std::cout << closestToMergeDistItr->first << " " << closestToMergeDistItr->second << std::endl;
1007 
1008 
1009 
1010  // Find up to 9 more points closest to closestToMerge on the clusIndexStart line
1011  std::vector<Pair_I_D> closestClusIndexStartDist;
1012  for (auto clusIndexStartHitItr = trackClustersClusIndexStartProtoTrackItr->hits.begin(); clusIndexStartHitItr != trackClustersClusIndexStartProtoTrackItr->hits.end(); ++clusIndexStartHitItr) {
1013  if(closestClusIndexStart==clusIndexStartHitItr-trackClustersClusIndexStartProtoTrackItr->hits.begin())
1014  continue;
1015 
1016  double distance = DistanceBetweenHits(*clusIndexStartHitItr,
1017  trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits[closestToMerge],
1018  wire_dist,
1019  tickToDist);
1020 
1021  bool foundCloser = false;
1022  for(auto closestClusIndexStartDistItr = closestClusIndexStartDist.begin(); closestClusIndexStartDistItr != closestClusIndexStartDist.end(); ++closestClusIndexStartDistItr) {
1023  if(closestClusIndexStartDistItr->second > distance){
1024  foundCloser = true;
1025  break;
1026  }
1027  }
1028  if(foundCloser
1029  || closestClusIndexStartDist.size() < trackClustersClusIndexStartProtoTrackItr->hits.size()-1
1030  || closestClusIndexStartDist.size() < 9){
1031  closestClusIndexStartDist.emplace_back(clusIndexStartHitItr-trackClustersClusIndexStartProtoTrackItr->hits.begin(),distance);
1032  std::sort(closestClusIndexStartDist.begin(), closestClusIndexStartDist.end(),
1033  [](const Pair_I_D& a, const Pair_I_D& b){ return a.second < b.second; }
1034  );
1035  }
1036  if(closestClusIndexStartDist.size() > trackClustersClusIndexStartProtoTrackItr->hits.size()-1 ||
1037  closestClusIndexStartDist.size() > 9)
1038  closestClusIndexStartDist.erase(closestClusIndexStartDist.end());
1039  }
1040 
1041 
1042 
1043  double toMergeAveCharge = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits[closestToMerge]->Integral();
1044  double toMergeAveSigmaCharge = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits[closestToMerge]->SigmaIntegral();
1045  for(auto closestToMergeDistItr = closestToMergeDist.begin(); closestToMergeDistItr != closestToMergeDist.end(); ++closestToMergeDistItr) {
1046  toMergeAveCharge+= trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits[closestToMergeDistItr->first]->Integral();
1047  toMergeAveSigmaCharge+= trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].hits[closestToMergeDistItr->first]->SigmaIntegral();
1048  }
1049  double clusIndexStartAveCharge = trackClustersClusIndexStartProtoTrackItr->hits[closestClusIndexStart]->Integral();
1050  double clusIndexStartAveSigmaCharge = trackClustersClusIndexStartProtoTrackItr->hits[closestClusIndexStart]->SigmaIntegral();
1051  for(auto closestClusIndexStartDistItr = closestClusIndexStartDist.begin(); closestClusIndexStartDistItr != closestClusIndexStartDist.end(); ++closestClusIndexStartDistItr) {
1052  clusIndexStartAveCharge+= trackClustersClusIndexStartProtoTrackItr->hits[closestClusIndexStartDistItr->first]->Integral();
1053  clusIndexStartAveSigmaCharge+=trackClustersClusIndexStartProtoTrackItr->hits[closestClusIndexStartDistItr->first]->SigmaIntegral();
1054  }
1055 
1056 
1057 
1058  double chargeAsymmetry = std::abs(toMergeAveCharge-clusIndexStartAveCharge)/(toMergeAveCharge+clusIndexStartAveCharge);
1059  double sigmaChargeAsymmetry = std::abs(toMergeAveSigmaCharge-clusIndexStartAveSigmaCharge)/(toMergeAveSigmaCharge+clusIndexStartAveSigmaCharge);
1060  double chargeAsymmetrySinAngle = chargeAsymmetry*std::abs(sin(mergeTheta[toMergeItr-toMerge.begin()]*TMath::Pi()/180));
1061  double sigmaChargeAsymmetrySinAngle = sigmaChargeAsymmetry*std::fabs(sin(mergeTheta[toMergeItr-toMerge.begin()]*TMath::Pi()/180));
1062 
1063  //std::cout << std::endl;
1064  //std::cout << chargeAsymmetry*std::fabs(sin(mergeTheta[toMergeItr-toMerge.begin()]*TMath::Pi()/180)) << std::endl;
1065  //std::cout << sigmaChargeAsymmetry*std::fabs(sin(mergeTheta[toMergeItr-toMerge.begin()]*TMath::Pi()/180)) << std::endl;
1066 
1067 
1068  if(chargeAsymmetrySinAngle > fChargeAsymAngleCut)
1069  continue;
1070 
1071  if(sigmaChargeAsymmetrySinAngle > fSigmaChargeAsymAngleCut)
1072  continue;
1073 
1074 
1075  // Veto the merge if the lines are not colinear
1076 
1077  //distance between two segments in the plane:
1078  // one segment is (x11, y11) to (x12, y12) or (p0MinLine1, p1MinLine1) to (p0MaxLine1, p1MaxLine1)
1079  // the other is (x21, y21) to (x22, y22) or (p0MinLine2, p1MinLine2) to (p0MaxLine2, p1MaxLine2)
1080  double x11 = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMin0;
1081  double y11 = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMin1;
1082  double x12 = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMax0;
1083  double y12 = trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].pMax1;
1084  double x21 = trackClustersClusIndexStartProtoTrackItr->pMin0;
1085  double y21 = trackClustersClusIndexStartProtoTrackItr->pMin1;
1086  double x22 = trackClustersClusIndexStartProtoTrackItr->pMax0;
1087  double y22 = trackClustersClusIndexStartProtoTrackItr->pMax1;
1088  // BUG the double brace syntax is required to work around clang bug 21629
1089  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1090  std::array<double, 4> distances = {{
1091  // Compare toMergerItr min with clusIndexStart min, if this is the min distance, lines are not colinear, merge is vetoed
1092  ::norm(x11-x21, y11-y21),
1093  ::norm(x11-x22, y11-y22), // Compare toMergerItr min with clusIndexStart max
1094  ::norm(x12-x21, y12-y21), // Compare toMergerItr max with clusIndexStart min
1095  // Compare toMergerItr max with clusIndexStart max, if this is the min distance, lines are not colinear, merge is vetoed
1096  ::norm(x12-x22, y12-y22)
1097  }}; // distances
1098 
1099  double minDistance = 999999;
1100  int minDistanceIndex = -1;
1101  for(unsigned int j = 0; j < distances.size(); j++){
1102  if (distances[j] < minDistance){
1103  minDistance = distances[j];
1104  minDistanceIndex = j;
1105  }
1106  }
1107 
1108  if(minDistanceIndex == 0 || minDistanceIndex == 3)
1109  continue;
1110 
1111 
1112  // How many lines do we have at the merging point? If too many, veto the merge
1113  //std::cout << nInDistanceClusIndexStartLeft << " " << nInDistanceClusIndexStartRight << std::endl;
1114 
1115  if(nInDistanceClusIndexStartLeft > fMaxVertexLines) {
1116  trackClustersClusIndexStartProtoTrackItr->mergedLeft = true;
1117  trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedRight = true;
1118  }
1119  if(nInDistanceClusIndexStartRight > fMaxVertexLines) {
1120  trackClustersClusIndexStartProtoTrackItr->mergedRight = true;
1121  trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedLeft = true;
1122  }
1123 
1124 
1125 
1126 
1127  // Check if we merged left or right already for clusIndexStart, we only do it once for each side
1128  if(trackClustersClusIndexStartProtoTrackItr->mergedLeft == true && minDistanceIndex == 2)
1129  continue;
1130  if(trackClustersClusIndexStartProtoTrackItr->mergedRight == true && minDistanceIndex == 1)
1131  continue;
1132  if(trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedLeft == true && minDistanceIndex == 1)
1133  continue;
1134  if(trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].mergedRight == true && minDistanceIndex == 2)
1135  continue;
1136 
1137  //std::cout << "Potential merge" << std::endl;
1138  //std::cout << "main trackClustersItr slope: " << trackClusters->at(*toMergeItr).clusterSlope << " clusIndexStart slope: " << trackClusters->at(clusIndexStart).clusterSlope << std::endl;
1139  potentialBestMerge=true;
1140 
1141 
1142  if(minDistance < bestToMergeTrackClusterProtoTrackDistance){
1143  bestToMergeTrackCluster=trackClustersToMergeItr-trackClusters->begin();
1144  bestToMergeTrackClusterProtoTrack=*toMergeItr;
1145  bestTrackClustersClusIndexStartProtoTrack=trackClustersClusIndexStartProtoTrackItr-trackClusters->at(clusIndexStart).clusterProtoTracks.begin();
1146  bestToMergeTrackClusterProtoTrackDistance=minDistance;
1147 
1148  // Did we merge left (0) or right (1)?
1149  if(minDistanceIndex == 1){
1150  bestToMergeRightLeft = 0;
1151  //bestClusIndexStartRightLeft = 1;
1152  }
1153  if(minDistanceIndex == 2){
1154  bestToMergeRightLeft = 1;
1155  //bestClusIndexStartRightLeft = 0;
1156  }
1157 
1158  }
1159 
1160  }// End of loop over toMerge
1161  }// End of loop over trackClusters->begin()+clusIndexStart+1
1162  }//End of loop over trackClusters->at(clusIndexStart).clusterProtoTracks
1163 
1164  if(potentialBestMerge){
1165  trackClusters->at(bestToMergeTrackCluster).clusterProtoTracks[bestToMergeTrackClusterProtoTrack].merged=true;
1166  trackClusters->at(clusIndexStart).clusterProtoTracks[bestTrackClustersClusIndexStartProtoTrack].merged=true;
1167  if(bestToMergeRightLeft == 0){
1168  trackClusters->at(bestToMergeTrackCluster).clusterProtoTracks[bestToMergeTrackClusterProtoTrack].mergedLeft = true;
1169  trackClusters->at(clusIndexStart).clusterProtoTracks[bestTrackClustersClusIndexStartProtoTrack].mergedRight = true;
1170  performedBestMerge=true;
1171  }
1172  if(bestToMergeRightLeft == 1){
1173  trackClusters->at(bestToMergeTrackCluster).clusterProtoTracks[bestToMergeTrackClusterProtoTrack].mergedRight = true;
1174  trackClusters->at(clusIndexStart).clusterProtoTracks[bestTrackClustersClusIndexStartProtoTrack].mergedLeft = true;
1175  performedBestMerge=true;
1176  }
1177 
1178  if(performedBestMerge){
1179  trackClusters->at(clusIndexStart).addProtoTracks(trackClusters->at(bestToMergeTrackCluster).clusterProtoTracks);
1180  trackClusters->at(bestToMergeTrackCluster).clearProtoTracks();
1181  //std::cout << "Merged track-track" << std::endl;
1182  }
1183 
1184  }
1185 
1186  //lineMerged = true;
1187  //trackClustersClusIndexStartProtoTrackItr->merged = true;
1188  //trackClustersToMergeItr->clusterProtoTracks[*toMergeItr].merged = true;
1189 
1194  //for(auto trackClustersItr = trackClusters->begin(); trackClustersItr != trackClusters->end(); trackClustersItr++){
1195  //if((unsigned int)(*toMergeItr) == trackClustersItr-trackClusters->begin())
1196  //continue;
1197 
1198  //if(trackClustersItr->clusterNumber == trackClusters->at(*toMergeItr).clusterNumber){
1199  //trackClustersItr->clusterNumber = trackClusters->at(clusIndexStart).clusterNumber;
1200  //}
1201  //}
1202  //trackClusters->at(*toMergeItr).clusterNumber = trackClusters->at(clusIndexStart).clusterNumber;
1203 
1204 
1205  return performedBestMerge;
1206 
1207 }
double fSigmaChargeAsymAngleCut
Cut on product of charge asymmetry and sin of angle between slopes of lines.
double fTrackClusterMergeCutoff
Max distance between Hough lines before two lines are merged (muon tracks),.
int fMaxVertexLines
Max number of line end points allowed in a Hough line merge region for a merge to happen...
T sqr(T v)
double HoughLineDistance(double p0MinLine1, double p1MinLine1, double p0MaxLine1, double p1MaxLine1, double p0MinLine2, double p1MinLine2, double p0MaxLine2, double p1MaxLine2)
Float_t norm
double fVertexLinesCutoff
Size of the vertex region to count up lines for fMaxVertexLines.
double fChargeAsymAngleCut
Cut on product of charge asymmetry and sin of angle between slopes of lines.
double DistanceBetweenHits(art::Ptr< recob::Hit > hit0, art::Ptr< recob::Hit > hit1, double wire_dist, double tickToDist)
double cluster::fuzzyClusterAlg::PointSegmentDistance ( double  px,
double  py,
double  x1,
double  y1,
double  x2,
double  y2 
)
private

Definition at line 1504 of file fuzzyClusterAlg.cxx.

References norm, x1, x2, y1, and y2.

Referenced by HoughLineDistance(), and run_fuzzy_cluster().

1510 {
1511  double dx = x2 - x1;
1512  double dy = y2 - y1;
1513  if ( dx == 0 && dy == 0 ) // the segment's just a point
1514  return ::norm( px - x1, py - y1 );
1515 
1516  // Calculate the t that minimizes the distance.
1517  double t = ((px - x1)*dx + (py - y1)*dy) / ::sumsq(dx, dy);
1518 
1519  // See if this represents one of the segment's
1520  // end points or a point in the middle.
1521  if(t < 0){
1522  dx = px - x1;
1523  dy = py - y1;
1524  }
1525  else if(t > 1) {
1526  dx = px - x2;
1527  dy = py - y2;
1528  }
1529  else if(0 <= t && t <= 1) {
1530  double near_x = x1 + t * dx;
1531  double near_y = y1 + t * dy;
1532  dx = px - near_x;
1533  dy = py - near_y;
1534  }
1535 
1536  return ::norm(dx, dy);
1537 
1538 }
Float_t y1[n_points_granero]
Definition: compare.C:5
Float_t x1[n_points_granero]
Definition: compare.C:5
Float_t y2[n_points_geant4]
Definition: compare.C:26
Float_t norm
Float_t x2[n_points_geant4]
Definition: compare.C:26
void cluster::fuzzyClusterAlg::reconfigure ( fhicl::ParameterSet const &  p)

Definition at line 126 of file fuzzyClusterAlg.cxx.

References fChargeAsymAngleCut, fDBScan, fDoFuzzyRemnantMerge, fDoShowerClusterMerge, fDoShowerTrackClusterMerge, fDoTrackClusterMerge, fFuzzyRemnantMergeCutoff, fGenerateHoughLinesOnly, fHBAlg, fMaxVertexLines, fNumberTimeBoundaries, fNumberWireBoundaries, fRunHough, fShowerClusterMergeAngle, fShowerClusterMergeCutoff, fShowerLikenessCut, fShowerTrackClusterMergeAngle, fShowerTrackClusterMergeCutoff, fSigmaChargeAsymAngleCut, fTrackClusterMergeCutoff, fVertexLinesCutoff, fhicl::ParameterSet::get(), cluster::DBScanAlg::reconfigure(), and cluster::HoughBaseAlg::reconfigure().

Referenced by fuzzyClusterAlg(), and cluster::fuzzyCluster::reconfigure().

127 {
128 
129  fNumberTimeBoundaries = p.get< double >("NumberTimeBoundaries" );
130  fNumberWireBoundaries = p.get< double >("NumberWireBoundaries" );
131  fDoFuzzyRemnantMerge = p.get< bool >("DoFuzzyRemnantMerge" );
132  fFuzzyRemnantMergeCutoff = p.get< double >("FuzzyRemnantMergeCutoff" );
133  fDoTrackClusterMerge = p.get< bool >("DoTrackClusterMerge" );
134  fTrackClusterMergeCutoff = p.get< double >("TrackClusterMergeCutoff" );
135  fChargeAsymAngleCut = p.get< double >("ChargeAsymAngleCut" );
136  fSigmaChargeAsymAngleCut = p.get< double >("SigmaChargeAsymAngleCut" );
137  fDoShowerClusterMerge = p.get< bool >("DoShowerClusterMerge" );
138  fDoShowerTrackClusterMerge = p.get< bool >("DoShowerTrackClusterMerge" );
139  fShowerClusterMergeCutoff = p.get< double >("ShowerClusterMergeCutoff" );
140  fShowerClusterMergeAngle = p.get< double >("ShowerClusterMergeAngle" );
141  fShowerTrackClusterMergeCutoff = p.get< double >("ShowerTrackClusterMergeCutoff" );
142  fShowerTrackClusterMergeAngle = p.get< double >("ShowerTrackClusterMergeAngle" );
143  fShowerLikenessCut = p.get< double >("ShowerLikenessCut" );
144  fMaxVertexLines = p.get< int >("MaxVertexLines" );
145  fVertexLinesCutoff = p.get< double >("VertexLinesCutoff" );
146  fRunHough = p.get< bool >("RunHough" );
147  fGenerateHoughLinesOnly = p.get< bool >("GenerateHoughLinesOnly" );
148  fHBAlg.reconfigure(p.get< fhicl::ParameterSet >("HoughBaseAlg"));
149  fDBScan.reconfigure(p.get< fhicl::ParameterSet >("DBScanAlg"));
150 }
virtual void reconfigure(fhicl::ParameterSet const &pset)
double fFuzzyRemnantMergeCutoff
cut off on merging the fuzzy cluster remnants into the nearest shower or track
double fSigmaChargeAsymAngleCut
Cut on product of charge asymmetry and sin of angle between slopes of lines.
double fTrackClusterMergeCutoff
Max distance between Hough lines before two lines are merged (muon tracks),.
int fMaxVertexLines
Max number of line end points allowed in a Hough line merge region for a merge to happen...
double fNumberWireBoundaries
Number of boundaries in wires for the drift window to be divided up to make the Hough line finder eas...
bool fDoFuzzyRemnantMerge
Tell the algorithm to merge fuzzy cluster remnants into showers or tracks (0-off, 1-on) ...
double fShowerTrackClusterMergeAngle
Max angle between slopes before two lines are merged, for lines in shower line regions.
bool fDoTrackClusterMerge
Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.
bool fDoShowerTrackClusterMerge
Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.
bool fDoShowerClusterMerge
Turns on shower Hough line merging (0-off, 1-on)
bool fGenerateHoughLinesOnly
Show only the results of the Hough line finder, hits not in a line will not be clustered.
double fShowerClusterMergeAngle
Max angle between slopes before two lines are merged, for lines in shower line regions.
double fNumberTimeBoundaries
Number of boundaries in ticks for the drift window to be divided up to make the Hough line finder eas...
void reconfigure(fhicl::ParameterSet const &p)
Definition: DBScanAlg.cxx:271
double fShowerTrackClusterMergeCutoff
Max distance between Hough lines before two lines are merged (electron showers),. ...
double fShowerLikenessCut
Cut on shower likeness (larger the more shower like, smaller the less shower like) ...
double fVertexLinesCutoff
Size of the vertex region to count up lines for fMaxVertexLines.
double fShowerClusterMergeCutoff
Max distance between Hough lines before two lines are merged (electron showers),. ...
double fChargeAsymAngleCut
Cut on product of charge asymmetry and sin of angle between slopes of lines.
void cluster::fuzzyClusterAlg::run_fuzzy_cluster ( const std::vector< art::Ptr< recob::Hit > > &  allhits)
Todo:
: the collection plane's characteristic hit width's are,
Todo:
: on average, about 5 time samples wider than the induction plane's.
Todo:
: this is hard-coded for now.

Veto the hit if it already belongs to a line, proto tracks (Hough lines) are added after the fuzzy clusters

Sum up background hits, use smart distance

end loop over hits

end loop over lines found

Definition at line 217 of file fuzzyClusterAlg.cxx.

References d, detinfo::DetectorProperties::DriftVelocity(), detinfo::DetectorProperties::Efield(), fclusters, fDoFuzzyRemnantMerge, fDoShowerClusterMerge, fDoShowerTrackClusterMerge, fDoTrackClusterMerge, fFuzzyRemnantMergeCutoff, fGenerateHoughLinesOnly, fHBAlg, fnoise, fNumberTimeBoundaries, fNumberWireBoundaries, fpointId_to_clusterId, fps, fRunHough, fShowerLikenessCut, fvisited, fWirePitch, geo::kInduction, cluster::kNO_CLUSTER, cluster::kNOISE_CLUSTER, LOG_DEBUG, mergeShowerClusters(), mergeShowerTrackClusters(), mergeTrackClusters(), noise(), norm, geo::GeometryCore::Nwires(), PointSegmentDistance(), detinfo::DetectorProperties::ReadOutWindowSize(), detinfo::DetectorProperties::SamplingRate(), geo::GeometryCore::SignalType(), geo::sqr(), detinfo::DetectorProperties::Temperature(), cluster::HoughBaseAlg::Transform(), and y.

Referenced by cluster::fuzzyCluster::produce().

217  {
218 
219  // Don't attempt to run the algorithm if we have 1 or fewer hits
220  if(allhits.size() <= 1)
221  return;
222 
223  mf::LogInfo("fuzzyClusterAlg") << "Clustering " << allhits.size() << " hits";
224 
225 
226  fpointId_to_clusterId.resize(fps.size(), kNO_CLUSTER); // Not zero as before!
227  fnoise.resize(fps.size(), false);
228  fvisited.resize(fps.size(), false);
229 
231  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
232 
233 
234  //factor to make x and y scale the same units
235 // uint32_t channel = allhits[0]->Channel();
236 // double wirePitch = geom->WirePitch(geom->View(channel));
237  uint32_t channel = allhits[0]->WireID().Wire;
238 // double wirePitch[2];
239 // wirePitch[0] = geom->WirePitch(0);
240 // wirePitch[1] = geom->WirePitch(1);
241 // wirePitch[2] = geom->WirePitch(2);
242 
243 // saw this one
244 
245  double xyScale = .001*detprop->DriftVelocity(detprop->Efield(),detprop->Temperature());
246  xyScale*=detprop->SamplingRate();
247  // double wire_dist = wirePitch;
248 
249  double tickToDist = detprop->DriftVelocity(detprop->Efield(),detprop->Temperature());
250  tickToDist *= 1.e-3 * detprop->SamplingRate(); // 1e-3 is conversion of 1/us to 1/ns
251 
252 
253  double indcolscaling = 0.; //a parameter to account for the different
254  //characteristic hit width of induction and collection plane
258  geo::SigType_t sigt = geom->SignalType(channel);
259  if(sigt == geo::kInduction)
260  indcolscaling = 0.;
261  else
262  indcolscaling = 1.;
263 
264 
265  unsigned int nClusters = 1;
266  unsigned int nClustersTemp = 1;
267 
268  // Divide up readout window into 9 sections that the Hough transform will be run over individually
271  unsigned int nWires = geom->Nwires(allhits[0]->WireID().Plane);
272  unsigned int nTicks = detprop->ReadOutWindowSize();
273  std::vector<unsigned int> wireBoundaries;
274  std::vector<unsigned int> timeBoundaries;
275  for(size_t i = 0; i < fNumberWireBoundaries+1; i++){
276  wireBoundaries.push_back(i*nWires/fNumberWireBoundaries);
277  }
278  for(size_t i = 0; i < fNumberTimeBoundaries + 1; i++){
279  timeBoundaries.push_back(i*nTicks/fNumberTimeBoundaries);
280  }
281  for(auto hitsItr = allhits.cbegin(); hitsItr != allhits.cend(); ++hitsItr){
282  for(size_t i = 0; i < fNumberWireBoundaries; i++){
283  if(( *hitsItr)->WireID().Wire >= wireBoundaries[i] && (*hitsItr)->WireID().Wire < wireBoundaries[i+1]){
284  for(size_t j = 0; j < fNumberTimeBoundaries; j++){
285  if((*hitsItr)->PeakTime() >= timeBoundaries[j] && (*hitsItr)->PeakTime() < timeBoundaries[j+1]){
286  fpointId_to_clusterId[hitsItr-allhits.cbegin()] = j*fNumberTimeBoundaries+i;
287  }
288  }
289  }
290  }
291  }
292 
293 
294 
295 
296 
297 
298  // Loop over clusters with the Hough line finder to break the clusters up further
299  // list of lines
300  std::vector<protoTrack> protoTracksFound;
301  if(nClustersTemp > 0 && fRunHough)
302  for (unsigned int i = 0; i <= (unsigned int)nClustersTemp-1; ++i){
303  LOG_DEBUG("fuzzyClusterAlg")
304  << "Running Hough transform on protocluster " << i;
305  fHBAlg.Transform(allhits, &fpointId_to_clusterId, i, &nClusters, &protoTracksFound);
306  }
307 
308  // Determine the shower likeness of lines
309  std::vector<showerCluster> showerClusters;
310  std::vector<trackCluster> trackClusters;
311  double totalBkgDistCharge;
312  double fMaxDistance;
313  double distance;
314  double peakTimePerpMin;
315  double peakTimePerpMax;
316  for(auto protoTracksFoundItr = protoTracksFound.begin(); protoTracksFoundItr < protoTracksFound.end(); ++protoTracksFoundItr){
317  totalBkgDistCharge = 0;
318  fMaxDistance = 0.1;
319  for(auto hitsItr = allhits.cbegin(); hitsItr != allhits.cend(); ++hitsItr){
321  //if(fpointId_to_clusterId.at(hitsItr-allhits.cbegin()) < nClustersTemp)
322  //continue;
323  distance = (std::abs((*hitsItr)->PeakTime()-protoTracksFoundItr->clusterSlope*(double)((*hitsItr)->WireID().Wire)-protoTracksFoundItr->clusterIntercept)/(std::sqrt(sqr(xyScale/fWirePitch[(*hitsItr)->WireID().Plane]*protoTracksFoundItr->clusterSlope)+1)));
325  peakTimePerpMin=-(1/protoTracksFoundItr->clusterSlope)*(double)((*hitsItr)->WireID().Wire)+allhits[protoTracksFoundItr->iMinWire]->PeakTime()+(1/protoTracksFoundItr->clusterSlope)*(allhits[protoTracksFoundItr->iMinWire]->WireID().Wire);
326  peakTimePerpMax=-(1/protoTracksFoundItr->clusterSlope)*(double)((*hitsItr)->WireID().Wire)+allhits[protoTracksFoundItr->iMaxWire]->PeakTime()+(1/protoTracksFoundItr->clusterSlope)*(allhits[protoTracksFoundItr->iMaxWire]->WireID().Wire);
327  if(distance > 1*(fMaxDistance+(*hitsItr)->RMS()+indcolscaling)
328  && distance < 25*(fMaxDistance+(*hitsItr)->RMS()+indcolscaling)){
329  if((protoTracksFoundItr->clusterSlope < 0 && (*hitsItr)->PeakTime() < peakTimePerpMin && (*hitsItr)->PeakTime() > peakTimePerpMax)
330  || (protoTracksFoundItr->clusterSlope > 0 && (*hitsItr)->PeakTime() > peakTimePerpMin && (*hitsItr)->PeakTime() < peakTimePerpMax)){
331  if((*hitsItr)->Integral() > 0.1){
332  totalBkgDistCharge+=distance/(*hitsItr)->Integral();
333  }
334  }
335  }
336  }
337  protoTracksFoundItr->showerLikeness = totalBkgDistCharge/(double)protoTracksFoundItr->hits.size();
338  //std::cout << "showerLikeness: " << totalBkgDistCharge/(double)protoTracksFoundItr->hits.size() << std::endl;
339 
340  if(protoTracksFoundItr->showerLikeness > fShowerLikenessCut)
341  showerClusters.push_back(showerCluster(*protoTracksFoundItr));
342  else
343  trackClusters.push_back(trackCluster(*protoTracksFoundItr));
344 
345  }
346 
347 
348 
349  // Merge Hough lines
350  bool trackMerged;
351  bool showerMerged;
352  bool showerTrackMerged;
353 
354  if(fDoTrackClusterMerge && trackClusters.size() > 1){
355  unsigned int i = 0;
356  while(i < trackClusters.size()-1){
357  int ip = trackClusters[i].clusterProtoTracks[0].planeNumber;
358  trackMerged = mergeTrackClusters(i,&trackClusters,xyScale/fWirePitch[ip],
359  fWirePitch[ip],tickToDist);
360  if(trackMerged)
361  continue;
362  else
363  i++;
364  }
365  }
366 
367  if(fDoShowerClusterMerge && showerClusters.size() > 1){
368  unsigned int i = 0;
369  while(i < showerClusters.size()-1){
370  int ip = showerClusters[i].clusterProtoTracks[0].planeNumber;
371  showerMerged = mergeShowerClusters(i,&showerClusters,xyScale/fWirePitch[ip],
372  fWirePitch[ip],tickToDist);
373  if(showerMerged)
374  continue;
375  else
376  i++;
377  }
378  }
379 
380  if(fDoShowerTrackClusterMerge && showerClusters.size() > 0 && trackClusters.size() >0){
381  unsigned int i = 0;
382  while(i < showerClusters.size()){
383  int ip = showerClusters[i].clusterProtoTracks[0].planeNumber;
384  unsigned int j = 0;
385  while(j < trackClusters.size()){
386  // int ipt = trackClusters[j].clusterProtoTracks[0].planeNumber;
387  showerTrackMerged = mergeShowerTrackClusters(&showerClusters[i],&trackClusters[j],
388  xyScale/fWirePitch[ip],
389  fWirePitch[ip],tickToDist);
390  if(showerTrackMerged)
391  continue;
392  else
393  j++;
394  }
395  i++;
396  }
397  }
398 
399  if(fDoShowerClusterMerge && showerClusters.size() > 1){
400  unsigned int i = 0;
401  while(i < showerClusters.size()-1){
402  int ip = showerClusters[i].clusterProtoTracks[0].planeNumber;
403  showerMerged = mergeShowerClusters(i,&showerClusters,xyScale/fWirePitch[ip],
404  fWirePitch[ip],tickToDist);
405  if(showerMerged)
406  continue;
407  else
408  i++;
409  }
410  }
411 
412 
413  // Reassign the merged lines
414  for(auto fpointId_to_clusterIdItr = fpointId_to_clusterId.begin(); fpointId_to_clusterIdItr != fpointId_to_clusterId.end(); ++fpointId_to_clusterIdItr){
415  for(auto trackClustersItr = trackClusters.begin(); trackClustersItr != trackClusters.end(); ++trackClustersItr){
416  for(auto protoTracksFoundItr = trackClustersItr->clusterProtoTracks.begin(); protoTracksFoundItr < trackClustersItr->clusterProtoTracks.end(); ++protoTracksFoundItr){
417  if(*fpointId_to_clusterIdItr == (unsigned int)protoTracksFoundItr->oldClusterNumber)
418  *fpointId_to_clusterIdItr = protoTracksFoundItr->clusterNumber;
419  }
420  }
421  for(auto showerClustersItr = showerClusters.begin(); showerClustersItr != showerClusters.end(); ++showerClustersItr){
422  for(auto protoTracksFoundItr = showerClustersItr->clusterProtoTracks.begin(); protoTracksFoundItr < showerClustersItr->clusterProtoTracks.end(); ++protoTracksFoundItr){
423  if(*fpointId_to_clusterIdItr == (unsigned int)protoTracksFoundItr->oldClusterNumber){
424  *fpointId_to_clusterIdItr = protoTracksFoundItr->clusterNumber;
425  }
426  }
427  }
428  }
429 
430 
431  // Find sizes of all merged lines combined
432  // For protoTracksFoundSizes, key is cluster number and size is the mapped value
433  std::map<int,double> protoTracksFoundSizes;
434  for(auto protoTracksFoundItr = protoTracksFound.begin(); protoTracksFoundItr < protoTracksFound.end(); ++protoTracksFoundItr){
435  double d = ::norm(protoTracksFoundItr->pMin0-protoTracksFoundItr->pMax0, protoTracksFoundItr->pMin1-protoTracksFoundItr->pMax1);
436  if(!protoTracksFoundSizes.count(protoTracksFoundItr->clusterNumber))
437  protoTracksFoundSizes[protoTracksFoundItr->clusterNumber] = d;
438  else
439  protoTracksFoundSizes[protoTracksFoundItr->clusterNumber]+= d;
440  }
441 
442 
443 
444  // If only showing Hough lines, set the fuzzy cluster remnants to have no cluster
446  for(auto allhitsItr = allhits.cbegin(); allhitsItr != allhits.cend(); ++allhitsItr){
447  if(fpointId_to_clusterId.at(allhitsItr-allhits.begin()) < (unsigned int) nClustersTemp )
448  fpointId_to_clusterId.at(allhitsItr-allhits.begin()) = kNO_CLUSTER;
449  }
450  }
451 
452  std::vector< art::Ptr<recob::Hit> > unclusteredhits;
453  std::vector<unsigned int> unclusteredhitsToAllhits;
454  int nDBClusters = 0;
455  bool unclustered;
456  double p0;
457  double p1;
458  double minDistanceShower;
459  // double minDistanceTrack;
461  for(auto allhitsItr = allhits.cbegin(); allhitsItr != allhits.cend(); ++allhitsItr){
462  unclustered = true;
463  // nClusters is the number of fuzzy clusters we found, we only assign hits to lines here
464  // if they are not already part of hough lines
465  if(fpointId_to_clusterId.at(allhitsItr-allhits.begin()) >= (unsigned int) nClustersTemp
466  && fpointId_to_clusterId.at(allhitsItr-allhits.begin()) < nClusters ){
467  unclustered = false;
468  continue;
469  }
470  int ip = (*allhitsItr)->WireID().Plane;
471  p0 = ((*allhitsItr)->WireID().Wire)*fWirePitch[ip];
472  p1 = (*allhitsItr)->PeakTime()*tickToDist;
473 
474  // First try to group it with a shower-like cluster
475  minDistanceShower = 999999;
476  for(auto showerClustersItr = showerClusters.begin(); showerClustersItr != showerClusters.end(); ++showerClustersItr){
477  for(auto protoTracksItr = showerClustersItr->clusterProtoTracks.begin(); protoTracksItr < showerClustersItr->clusterProtoTracks.end(); ++protoTracksItr){
478 
479  distance = PointSegmentDistance( p0, p1, protoTracksItr->pMin0, protoTracksItr->pMin1, protoTracksItr->pMax0, protoTracksItr->pMax1);
480 
481  if(distance > fFuzzyRemnantMergeCutoff)
482  continue;
483 
484  // This line used to have 1/4 instead of 0.25; wthat made it uneffective
485  // (1/4 = 0); but replacing 0.25 sensibly changes performances;
486  // commenting out the line for now [GP]
487  // distance /= std::pow(protoTracksFoundSizes[protoTracksItr->clusterNumber], 0.25);
488  if(distance < minDistanceShower){
489  fpointId_to_clusterId.at(allhitsItr-allhits.begin()) = protoTracksItr->clusterNumber;
490  minDistanceShower = distance;
491  unclustered = false;
492  }
493  }
494  }
495 
496  if(!unclustered)
497  continue;
498 
499  // Failing to group it with a shower-like cluster, try with a track-like cluster
500  // minDistanceTrack = 999999;
501  // for(auto trackClustersItr = trackClusters.begin(); trackClustersItr != trackClusters.end(); ++trackClustersItr){
502  // for(auto protoTracksItr = trackClustersItr->clusterProtoTracks.begin(); protoTracksItr < trackClustersItr->clusterProtoTracks.end(); ++protoTracksItr){
503 
504  // distance = PointSegmentDistance( p0, p1, protoTracksItr->pMin0, protoTracksItr->pMin1, protoTracksItr->pMax0, protoTracksItr->pMax1);
505 
506  // if(distance > fFuzzyRemnantMergeCutoff)
507  // continue;
508 
509  // // commenting out the line for now (see above) [GP]
510  // // distance /= std::pow(protoTracksFoundSizes[protoTracksItr->clusterNumber], 0.25);
511  // if(distance < minDistanceTrack){
512  // fpointId_to_clusterId.at(allhitsItr-allhits.begin()) = protoTracksItr->clusterNumber;
513  // minDistanceTrack = distance;
514  // unclustered = false;
515  // }
516  // }
517  // }
518 
519 
520  if(unclustered){
521  unclusteredhitsToAllhits.push_back(allhitsItr-allhits.begin());
522  unclusteredhits.push_back(*allhitsItr);
523  fpointId_to_clusterId.at(allhitsItr-allhits.begin()) = kNOISE_CLUSTER;
524  }
525 
526  }
527 
528  // Setup DBSCAN for noise and extra hits
529  // Start by getting the ChannelFilter
530  // filter::ChannelFilter chanFilt;
531  // fDBScan.InitScan(unclusteredhits, chanFilt.SetOfBadChannels());
532  // fDBScan.run_cluster();
533 
534  // nDBClusters = fDBScan.fclusters.size();
535  // for(size_t j = 0; j < fDBScan.fpointId_to_clusterId.size(); ++j){
536  // if (fDBScan.fpointId_to_clusterId[j]== kNO_CLUSTER || fDBScan.fpointId_to_clusterId[j]==kNOISE_CLUSTER) {
537  // fpointId_to_clusterId.at(unclusteredhitsToAllhits[j]) = kNOISE_CLUSTER;
538  // }
539  // else {
540  // fpointId_to_clusterId.at(unclusteredhitsToAllhits[j]) = fDBScan.fpointId_to_clusterId[j] + nClusters;
541  // }
542  // }
543  }
544 
545  size_t cid = nClusters + nDBClusters;
546 
547  //mf::LogInfo("fuzzyCluster") << "cid: " << cid ;
548 
549  //for(size_t j = 0; j < fpointId_to_clusterId.size(); ++j)
550  //mf::LogInfo("fuzzyCluster") << "fpointId_to_clusterId[j]: " << fpointId_to_clusterId[j] << " j: " << j ;
551 
552 
553  // Construct clusters, count noise, etc..
554  int noise = 0;
555  unsigned int c;
556  fclusters.resize(cid);
557  for(size_t y = 0; y < fpointId_to_clusterId.size(); ++y){
559  // This shouldn't happen...all points should be clasified by now!
560  mf::LogWarning("fuzzyCluster") << "Unclassified point!";
561  }
563  ++noise;
564  }
565  else {
567  if (c >= cid) {
568  mf::LogWarning("fuzzyCluster") << "Point in cluster " << c
569  << " when only " << cid
570  << " clusters were found [0-" << cid-1
571  << "]";
572  }
573  fclusters[c].push_back(y);
574  }
575  }
576  mf::LogInfo("fuzzyCluster") << "DWM (R*-tree): Found "
577  << cid << " clusters...";
578  for (unsigned int c = 0; c < cid; ++c){
579  mf::LogVerbatim("fuzzyCluster") << "\t" << "Cluster " << c << ":\t"
580  << fclusters[c].size();
581  }
582  mf::LogVerbatim("fuzzyCluster") << "\t" << "...and " << noise << " noise points.";
583 }
bool mergeShowerClusters(unsigned int k, std::vector< showerCluster > *showerClusters, double xyScale, double wire_dist, double tickToDist)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
const unsigned int kNO_CLUSTER
Definition: DBScanAlg.cxx:253
virtual unsigned int ReadOutWindowSize() const =0
std::vector< bool > fnoise
double fFuzzyRemnantMergeCutoff
cut off on merging the fuzzy cluster remnants into the nearest shower or track
std::vector< bool > fvisited
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Float_t y
Definition: compare.C:6
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
double fNumberWireBoundaries
Number of boundaries in wires for the drift window to be divided up to make the Hough line finder eas...
bool fDoFuzzyRemnantMerge
Tell the algorithm to merge fuzzy cluster remnants into showers or tracks (0-off, 1-on) ...
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
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 noise()
Definition: chem4.cc:265
T sqr(T v)
size_t Transform(std::vector< art::Ptr< recob::Hit > > const &hits, std::vector< unsigned int > *fpointId_to_clusterId, unsigned int clusterId, unsigned int *nClusters, std::vector< protoTrack > *protoTracks)
const unsigned int kNOISE_CLUSTER
Definition: DBScanAlg.cxx:254
bool fDoTrackClusterMerge
Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.
bool fDoShowerTrackClusterMerge
Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.
bool fDoShowerClusterMerge
Turns on shower Hough line merging (0-off, 1-on)
Signal from induction planes.
Definition: geo_types.h:92
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
virtual double Temperature() const =0
Float_t d
Definition: plot.C:237
bool mergeTrackClusters(unsigned int k, std::vector< trackCluster > *trackClusters, double xyScale, double wire_dist, double tickToDist)
std::vector< std::vector< double > > fps
the collection of points we are working on
bool fGenerateHoughLinesOnly
Show only the results of the Hough line finder, hits not in a line will not be clustered.
std::vector< unsigned int > fpointId_to_clusterId
mapping point_id -> clusterId
Float_t norm
std::vector< double > fWirePitch
the pitch of the wires in each plane
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
double fNumberTimeBoundaries
Number of boundaries in ticks for the drift window to be divided up to make the Hough line finder eas...
bool mergeShowerTrackClusters(showerCluster *showerClusterI, trackCluster *trackClusterJ, double xyScale, double wire_dist, double tickToDist)
double PointSegmentDistance(double px, double py, double x1, double y1, double x2, double y2)
std::vector< std::vector< unsigned int > > fclusters
collection of something
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
#define LOG_DEBUG(id)
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
double fShowerLikenessCut
Cut on shower likeness (larger the more shower like, smaller the less shower like) ...
recob::tracking::Plane Plane
Definition: TrackState.h:17

Member Data Documentation

std::vector<std::vector<double> > cluster::fuzzyClusterAlg::data

Definition at line 53 of file fuzzyClusterAlg.h.

std::set<uint32_t> cluster::fuzzyClusterAlg::fBadChannels
private

set of bad channels in this detector

Definition at line 159 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

std::vector<uint32_t> cluster::fuzzyClusterAlg::fBadWireSum
private

running total of bad channels. Used for fast intervening dead wire counting ala fBadChannelSum[m]-fBadChannelSum[n].

Definition at line 160 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

double cluster::fuzzyClusterAlg::fChargeAsymAngleCut
private

Cut on product of charge asymmetry and sin of angle between slopes of lines.

Definition at line 78 of file fuzzyClusterAlg.h.

Referenced by mergeTrackClusters(), and reconfigure().

std::vector<std::vector<unsigned int> > cluster::fuzzyClusterAlg::fclusters

collection of something

Definition at line 39 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), cluster::fuzzyCluster::produce(), and run_fuzzy_cluster().

DBScanAlg cluster::fuzzyClusterAlg::fDBScan
private

Definition at line 173 of file fuzzyClusterAlg.h.

Referenced by reconfigure().

bool cluster::fuzzyClusterAlg::fDoFuzzyRemnantMerge
private

Tell the algorithm to merge fuzzy cluster remnants into showers or tracks (0-off, 1-on)

Definition at line 73 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

bool cluster::fuzzyClusterAlg::fDoShowerClusterMerge
private

Turns on shower Hough line merging (0-off, 1-on)

Definition at line 81 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

bool cluster::fuzzyClusterAlg::fDoShowerTrackClusterMerge
private

Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.

Definition at line 85 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

bool cluster::fuzzyClusterAlg::fDoTrackClusterMerge
private

Turn on cut on product of charge asymmetry and sin of angle between slopes of lines.

Definition at line 76 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

double cluster::fuzzyClusterAlg::fFuzzyRemnantMergeCutoff
private

cut off on merging the fuzzy cluster remnants into the nearest shower or track

Definition at line 74 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

bool cluster::fuzzyClusterAlg::fGenerateHoughLinesOnly
private

Show only the results of the Hough line finder, hits not in a line will not be clustered.

Definition at line 71 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

art::ServiceHandle<geo::Geometry> cluster::fuzzyClusterAlg::fGeom
private

handle to geometry service

Definition at line 175 of file fuzzyClusterAlg.h.

HoughBaseAlg cluster::fuzzyClusterAlg::fHBAlg
private

Definition at line 170 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

int cluster::fuzzyClusterAlg::fMaxVertexLines
private

Max number of line end points allowed in a Hough line merge region for a merge to happen.

Definition at line 91 of file fuzzyClusterAlg.h.

Referenced by mergeShowerTrackClusters(), mergeTrackClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fMaxWidth

Definition at line 45 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

std::vector<bool> cluster::fuzzyClusterAlg::fnoise
private

Definition at line 156 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), and run_fuzzy_cluster().

double cluster::fuzzyClusterAlg::fNumberTimeBoundaries
private

Number of boundaries in ticks for the drift window to be divided up to make the Hough line finder easier on memory.

Definition at line 63 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

double cluster::fuzzyClusterAlg::fNumberWireBoundaries
private

Number of boundaries in wires for the drift window to be divided up to make the Hough line finder easier on memory.

Definition at line 67 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

std::vector<unsigned int> cluster::fuzzyClusterAlg::fpointId_to_clusterId

mapping point_id -> clusterId

Definition at line 41 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), cluster::fuzzyCluster::produce(), and run_fuzzy_cluster().

std::vector<std::vector<double> > cluster::fuzzyClusterAlg::fps

the collection of points we are working on

Definition at line 40 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), cluster::fuzzyCluster::produce(), and run_fuzzy_cluster().

bool cluster::fuzzyClusterAlg::fRunHough
private

Definition at line 70 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

double cluster::fuzzyClusterAlg::fShowerClusterMergeAngle
private

Max angle between slopes before two lines are merged, for lines in shower line regions.

Definition at line 82 of file fuzzyClusterAlg.h.

Referenced by mergeShowerClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fShowerClusterMergeCutoff
private

Max distance between Hough lines before two lines are merged (electron showers),.

Definition at line 83 of file fuzzyClusterAlg.h.

Referenced by mergeShowerClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fShowerLikenessCut
private

Cut on shower likeness (larger the more shower like, smaller the less shower like)

Definition at line 89 of file fuzzyClusterAlg.h.

Referenced by reconfigure(), and run_fuzzy_cluster().

double cluster::fuzzyClusterAlg::fShowerTrackClusterMergeAngle
private

Max angle between slopes before two lines are merged, for lines in shower line regions.

Definition at line 87 of file fuzzyClusterAlg.h.

Referenced by mergeShowerTrackClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fShowerTrackClusterMergeCutoff
private

Max distance between Hough lines before two lines are merged (electron showers),.

Definition at line 86 of file fuzzyClusterAlg.h.

Referenced by mergeShowerTrackClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fSigmaChargeAsymAngleCut
private

Cut on product of charge asymmetry and sin of angle between slopes of lines.

Definition at line 79 of file fuzzyClusterAlg.h.

Referenced by mergeTrackClusters(), and reconfigure().

std::vector<std::vector<double> > cluster::fuzzyClusterAlg::fsim

Definition at line 42 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

std::vector<std::vector<double> > cluster::fuzzyClusterAlg::fsim2

Definition at line 43 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

std::vector<std::vector<double> > cluster::fuzzyClusterAlg::fsim3

Definition at line 44 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy().

double cluster::fuzzyClusterAlg::fTrackClusterMergeCutoff
private

Max distance between Hough lines before two lines are merged (muon tracks),.

Definition at line 77 of file fuzzyClusterAlg.h.

Referenced by mergeTrackClusters(), and reconfigure().

double cluster::fuzzyClusterAlg::fVertexLinesCutoff
private

Size of the vertex region to count up lines for fMaxVertexLines.

Definition at line 92 of file fuzzyClusterAlg.h.

Referenced by mergeShowerTrackClusters(), mergeTrackClusters(), and reconfigure().

std::vector<bool> cluster::fuzzyClusterAlg::fvisited
private

Definition at line 157 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), and run_fuzzy_cluster().

std::vector<double> cluster::fuzzyClusterAlg::fWirePitch
private

the pitch of the wires in each plane

Definition at line 158 of file fuzzyClusterAlg.h.

Referenced by InitFuzzy(), and run_fuzzy_cluster().


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