tpcvechitfinder2_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: tpcvechitfinder2
3 // Plugin Type: producer (art v3_00_00)
4 // File: tpcvechitfinder2_module.cc
5 //
6 // Generated at Tue Feb 12 15:44:27 2019 by Thomas Junk using cetskelgen
7 // A first step in GArSoft tracking pattern recognition
8 // finds short track segments from TPCClusters
9 // from cetlib version v3_04_00.
10 ////////////////////////////////////////////////////////////////////////
11 
20 #include "fhiclcpp/ParameterSet.h"
23 
24 #include <memory>
25 // GArSoft Includes
28 
29 #include "Geometry/GeometryGAr.h"
30 #include "TMath.h"
31 #include "TVector3.h"
32 #include "TVectorD.h"
33 #include "TMatrixD.h"
34 #include "TMatrixDSym.h"
35 
36 namespace gar {
37  namespace rec {
38 
40  public:
41  explicit tpcvechitfinder2(fhicl::ParameterSet const& p);
42  // The compiler-generated destructor is fine for non-base
43  // classes without bare pointers or other resource use.
44 
45  // Plugins should not be copied or assigned.
46  tpcvechitfinder2(tpcvechitfinder2 const&) = delete;
50 
51  // Required functions.
52  void produce(art::Event& e) override;
53 
54  private:
55 
56  // a struct used for convenience before making data products
57  // not meant to be stored, but used by producers
58 
59  typedef struct{
60  TVector3 pos;
61  TVector3 dir;
62  std::vector<size_t> TPCClusterindex;
63  float length;
64  float c2ndf;
65  } vechit_t;
66 
67  std::string fTPCClusterLabel; ///< label of module to get the TPCClusters from
68  int fPrintLevel; ///< debug printout: 0: none, 1: selected, 2: all
69  size_t fNPasses; ///< number of passes to reassign TPCClusters from vector hits with poor chisquareds
70 
71  std::vector<float> fMaxVecHitLen; ///< maximum vector hit length in patrec alg 2, in cm
72  std::vector<float> fVecHitRoad; ///< max dist from a vector hit to a TPCCluster to assign it. for patrec alg 2. in cm.
73  std::vector<unsigned int> fVecHitMinTPCClusters; ///< minimum number of TPCClusters on a vector hit for it to be considered
74  std::vector<float> fTPCClusterRCut; ///< only take TPCClusters within rcut of the center of the detector
75  std::vector<float> fTPCClusterGapCut; ///< in cm -- skip TPC clusters within this distance of a gap
76  std::vector<float> fC2Cut; ///< "chisquared" per ndof cut to reassign TPCClusters
77 
78  int fLineFitAlg; ///< Line Fit switch. 0: six least-squares, 1: PCA
79 
80  bool vh_TPCClusmatch(int iTPCCluster, vechit_t &vechit, const std::vector<gar::rec::TPCCluster> &TPCClusters, vechit_t &proposedvh, size_t ipass);
81  void fitlinesdir(std::vector<TVector3> &hlist, TVector3 &pos, TVector3 &dir, float &chi2ndf);
82  void fitlines6ls(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z,TVector3 &pos, TVector3 &dir, float &chi2ndf);
83  void fitlinesPCA(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z,TVector3 &pos, TVector3 &dir, float &chi2ndf);
84  void fitline(std::vector<double> &x, std::vector<double> &y, double &lambda, double &intercept, double &chi2ndf);
85 
86  };
87 
88 
90  {
91  fTPCClusterLabel = p.get<std::string>("TPCClusterLabel","tpccluster");
92  fPrintLevel = p.get<int>("PrintLevel",0);
93  fNPasses = p.get<unsigned int>("NPasses",2);
94  fMaxVecHitLen = p.get<std::vector<float>>("MaxVecHitLen",{20.0,20.0});
95  fVecHitRoad = p.get<std::vector<float>>("VecHitRoad",{2.0,2.0});
96  fVecHitMinTPCClusters = p.get<std::vector<unsigned int>>("VecHitMinTPCClusters",{10,5});
97  fTPCClusterRCut = p.get<std::vector<float>>("TPCClusterRCut",{280.0,280.0});
98  fTPCClusterGapCut = p.get<std::vector<float>>("TPCClusterGapCut",{5.0,5.0});
99  fC2Cut = p.get<std::vector<float>>("C2Cut",{0.5,0.5});
100  fLineFitAlg = p.get<int>("LineFitAlg",0);
101 
102  art::InputTag TPCClusterTag(fTPCClusterLabel);
103  consumes< std::vector<gar::rec::TPCCluster> >(TPCClusterTag);
104  produces< std::vector<gar::rec::VecHit> >();
105  produces< art::Assns<gar::rec::TPCCluster, gar::rec::VecHit> >();
106 
107  }
108 
110  {
111  std::unique_ptr< std::vector<gar::rec::VecHit> > vhCol(new std::vector<gar::rec::VecHit>);
112  std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::VecHit> > TPCClusterVHAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::VecHit>);
113 
114  auto TPCClusterHandle = e.getValidHandle< std::vector<TPCCluster> >(fTPCClusterLabel);
115  auto const& TPCClusters = *TPCClusterHandle;
116 
117  auto const vhPtrMaker = art::PtrMaker<gar::rec::VecHit>(e);
118  auto const TPCClusterPtrMaker = art::PtrMaker<gar::rec::TPCCluster>(e, TPCClusterHandle.id());
119 
121  double xtpccent = geo->TPCXCent();
122  double ytpccent = geo->TPCYCent();
123  double ztpccent = geo->TPCZCent();
124  TVector3 tpccent(xtpccent,ytpccent,ztpccent);
125  TVector3 xhat(1,0,0);
126 
127  // make an array of TPCCluster indices sorted by TPCCluster X position
128  std::vector<float> TPCClusterx;
129  for (size_t i=0; i<TPCClusters.size(); ++i)
130  {
131  TPCClusterx.push_back(TPCClusters[i].Position()[0]);
132  }
133  std::vector<int> hsi(TPCClusterx.size());
134  TMath::Sort((int) TPCClusterx.size(),TPCClusterx.data(),hsi.data());
135 
136  std::vector<vechit_t> vechits;
137  std::vector<vechit_t> vhtmp;
138 
139  // iterate this, breaking up vechits with bad chisquareds and reassigning their TPCClusters
140 
141  for (size_t ipass=0; ipass<fNPasses; ++ipass)
142  {
143  for (size_t iTPCClusterxs=0; iTPCClusterxs<hsi.size(); ++iTPCClusterxs)
144  {
145  int iTPCCluster = hsi[iTPCClusterxs]; // access TPCClusters sorted in X but keep original indices
146  const float *hpos = TPCClusters[iTPCCluster].Position();
147  TVector3 hpvec(hpos);
148  TVector3 cprel = hpvec - tpccent;
149  float rclus = (cprel.Cross(xhat)).Mag();
150 
151  // skip TPCClusters if they are too far away from center as the
152  // last few pad rows may have distorted TPCClusters
153 
154  if ( rclus > fTPCClusterRCut.at(ipass) ) continue;
155 
156  // logic to see if a hit is close to a gap and skip if it is
157  if ( rclus > geo->GetIROCInnerRadius())
158  {
159  float phi = TMath::ATan2(cprel.Z(),cprel.Y());
160  if (phi<0) phi += 2.0*TMath::Pi();
161  float phisc = phi/( TMath::Pi()/9.0 );
162  UInt_t isector = TMath::Floor(phisc); // assumes the sector boundary is at phi=0 // goes from 0 to 17
163  // rotate this back down to a single sector
164  float rotang = ( isector*TMath::Pi()/9.0 );
165  float crot = TMath::Cos(rotang);
166  float srot = TMath::Sin(rotang);
167  //float zrot = cprel.Z()*crot + cprel.Y()*srot;
168  float yrot = - cprel.Z()*srot + cprel.Y()*crot;
169  if (TMath::Abs(yrot) < fTPCClusterGapCut.at(ipass)) continue;
170  }
171 
172  bool matched=false;
173  vechit_t proposedvh;
174  vechit_t bestproposedvh;
175  size_t ibestmatch = 0;
176 
177  for (size_t ivh=0; ivh<vhtmp.size(); ++ivh)
178  {
179  //std::cout << "testing TPCCluster: " << iTPCCluster << " with vector hit " << ivh << std::endl;
180  if (vh_TPCClusmatch(iTPCCluster, vhtmp[ivh], TPCClusters, proposedvh, ipass )) // updates vechit with this TPCCluster if matched
181  {
182  if (!matched || proposedvh.c2ndf < bestproposedvh.c2ndf )
183  {
184  matched = true;
185  ibestmatch = ivh;
186  bestproposedvh = proposedvh;
187  }
188  }
189  }
190  if (!matched) // make a new vechit if we haven't found one yet
191  {
192  vechit_t vh;
193  vh.pos.SetXYZ(hpos[0],hpos[1],hpos[2]);
194  vh.dir.SetXYZ(0,0,0); // new vechit with just one TPCCluster; don't know the direction yet
195  vh.length = 0; // no length with just one TPCCluster
196  vh.c2ndf = 0;
197  vh.TPCClusterindex.push_back(iTPCCluster);
198  vhtmp.push_back(vh);
199  //std::cout << "Created a new vector hit with one TPCCluster: " << hpos[0] << " " << hpos[1] << " " << hpos[2] << std::endl;
200  }
201  else
202  {
203  vhtmp[ibestmatch] = bestproposedvh;
204  }
205  }
206 
207  // prepare for the next pass -- find vector hits with poor chisquareds and remove them from the list. Remove short VH's too. Make a new
208  // list instead of constantly removing from the existing list. Repurpose hsi to contain the list of TPCClusters we want to reassign
209  // on the next pass.
210 
211  if (fNPasses > 1 && ipass < fNPasses-1)
212  {
213  hsi.clear();
214  std::vector<vechit_t> vhtmp2;
215  for (size_t ivh=0; ivh<vhtmp.size(); ++ivh)
216  {
217  if (fPrintLevel > 1)
218  {
219  std::cout << "about to push vh: " << ivh << " " << vhtmp[ivh].c2ndf << " " << vhtmp[ivh].TPCClusterindex.size() << std::endl;
220  }
221  if (vhtmp[ivh].c2ndf < fC2Cut.at(ipass) && vhtmp[ivh].TPCClusterindex.size() >= (size_t) fVecHitMinTPCClusters.at(ipass))
222  {
223  vhtmp2.push_back(vhtmp[ivh]);
224  }
225  else
226  {
227  for (size_t iTPCCluster=0; iTPCCluster<vhtmp[ivh].TPCClusterindex.size(); ++iTPCCluster)
228  {
229  hsi.push_back(vhtmp[ivh].TPCClusterindex[iTPCCluster]);
230  }
231  }
232  }
233  vhtmp = vhtmp2;
234  if (fPrintLevel > 1)
235  {
236  std::cout << "left with " << vhtmp.size() << " vec hits and " << hsi.size() << " TPCClusters to reassociate " << std::endl;
237  }
238  }
239  }
240 
241  // prepare data products for writing to the event
242 
243  for (size_t ivh=0; ivh<vhtmp.size(); ++ivh)
244  {
245  vechits.push_back(vhtmp[ivh]);
246  vechit_t vh = vechits[ivh];
247  float pos[3] = {0,0,0};
248  float dir[3] = {0,0,0};
249  vh.pos.GetXYZ(pos);
250  vh.dir.GetXYZ(dir);
251  vhCol->emplace_back(pos,dir,vh.length);
252  auto const vhpointer = vhPtrMaker(ivh);
253  for (size_t iTPCCluster=0; iTPCCluster<vh.TPCClusterindex.size(); ++iTPCCluster)
254  {
255  auto const TPCClusterpointer = TPCClusterPtrMaker(vh.TPCClusterindex[iTPCCluster]);
256  TPCClusterVHAssns->addSingle(TPCClusterpointer,vhpointer);
257  }
258  }
259 
260 
261  e.put(std::move(vhCol));
262  e.put(std::move(TPCClusterVHAssns));
263  }
264 
265  // see if a TPCCluster is consistent with a vector hit and add it if it is.
266 
267  bool tpcvechitfinder2::vh_TPCClusmatch(int iTPCCluster, vechit_t &vechit, const std::vector<gar::rec::TPCCluster> &TPCClusters, vechit_t &proposedvh, size_t ipass)
268  {
269  bool retval = false;
270 
271  TVector3 hpvec(TPCClusters.at(iTPCCluster).Position());
272  float dist = 1E10;
273  float newlength = vechit.length;
274 
275  for (size_t iht=0; iht<vechit.TPCClusterindex.size(); ++iht)
276  {
277  TVector3 ht(TPCClusters.at(vechit.TPCClusterindex.at(iht)).Position());
278  float d = (hpvec - ht).Mag();
279  if (d>fMaxVecHitLen.at(ipass)) return retval;
280  dist = TMath::Min(dist,d);
281  newlength = TMath::Max(newlength,d);
282  }
283 
284  if (vechit.TPCClusterindex.size() > 1)
285  {
286  dist = ((hpvec - vechit.pos).Cross(vechit.dir)).Mag();
287  //std::cout << " Distance cross comparison: " << dist << std::endl;
288  }
289 
290  if (dist < fVecHitRoad.at(ipass)) // add TPCCluster to vector hit if we have a match
291  {
292  //std::cout << "matched a TPCCluster to a vh" << std::endl;
293  std::vector<TVector3> hplist;
294  for (size_t i=0; i< vechit.TPCClusterindex.size(); ++i)
295  {
296  hplist.emplace_back(TPCClusters[vechit.TPCClusterindex[i]].Position());
297  }
298  hplist.push_back(hpvec);
299 
300  proposedvh.TPCClusterindex = vechit.TPCClusterindex;
301  fitlinesdir(hplist,proposedvh.pos,proposedvh.dir,proposedvh.c2ndf);
302  proposedvh.TPCClusterindex.push_back(iTPCCluster);
303  proposedvh.length = newlength; // we already calculated this above
304 
305  //std::cout << "vechit now has " << hplist.size() << " TPCClusters" << std::endl;
306  //std::cout << proposedvh.pos.X() << " " << proposedvh.pos.Y() << " " << proposedvh.pos.Z() << std::endl;
307  //std::cout << proposedvh.dir.X() << " " << proposedvh.dir.Y() << " " << proposedvh.dir.Z() << std::endl;
308  retval = true;
309  }
310  return retval;
311  }
312 
313  void tpcvechitfinder2::fitlinesdir(std::vector<TVector3> &hlist, TVector3 &pos, TVector3 &dir, float &chi2ndf)
314  {
315  std::vector<double> x;
316  std::vector<double> y;
317  std::vector<double> z;
318  for (size_t i=0; i<hlist.size();++i)
319  {
320  x.push_back(hlist[i].X());
321  y.push_back(hlist[i].Y());
322  z.push_back(hlist[i].Z());
323  }
324  if (fLineFitAlg == 0)
325  {
326  fitlines6ls(x,y,z,pos,dir,chi2ndf);
327  }
328  else if (fLineFitAlg == 1)
329  {
330  fitlinesPCA(x,y,z,pos,dir,chi2ndf);
331  }
332  else
333  {
334  throw cet::exception("tpcvechitfinder2_module.cc: ununderstood LineFitAlg parameter: ") << fLineFitAlg;
335  }
336  }
337 
338  void tpcvechitfinder2::fitlines6ls(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z,
339  TVector3 &pos, TVector3 &dir, float &chi2ndf)
340  {
341  double slope_yx=0;
342  double slope_zx=0;
343  double intercept_yx=0;
344  double intercept_zx=0;
345 
346  double slope_yz=0;
347  double slope_xz=0;
348  double intercept_yz=0;
349  double intercept_xz=0;
350 
351  double slope_xy=0;
352  double slope_zy=0;
353  double intercept_xy=0;
354  double intercept_zy=0;
355 
356  double chi2ndf_xy=0;
357  double chi2ndf_xz=0;
358  double chi2ndf_yz=0;
359  double chi2ndf_yx=0;
360  double chi2ndf_zx=0;
361  double chi2ndf_zy=0;
362 
363  fitline(x,y,slope_xy,intercept_xy,chi2ndf_xy);
364  fitline(x,z,slope_xz,intercept_xz,chi2ndf_xz);
365 
366  fitline(y,z,slope_yz,intercept_yz,chi2ndf_yz);
367  fitline(y,x,slope_yx,intercept_yx,chi2ndf_yx);
368 
369  fitline(z,y,slope_zy,intercept_zy,chi2ndf_zy);
370  fitline(z,x,slope_zx,intercept_zx,chi2ndf_zx);
371 
372  // pick the direction with the smallest sum of the absolute values of slopes to use to determine the line direction
373  // in three-dimensional space
374 
375  double slopesumx = TMath::Abs(slope_xy) + TMath::Abs(slope_xz);
376  double slopesumy = TMath::Abs(slope_yz) + TMath::Abs(slope_yx);
377  double slopesumz = TMath::Abs(slope_zx) + TMath::Abs(slope_zy);
378 
379  if (slopesumx < slopesumy && slopesumx < slopesumz)
380  {
381  dir.SetXYZ(1.0,slope_xy,slope_xz);
382  double avgx = 0;
383  for (size_t i=0; i<x.size(); ++i)
384  {
385  avgx += x[i];
386  }
387  avgx /= x.size();
388  pos.SetXYZ(avgx, avgx*slope_xy + intercept_xy, avgx*slope_xz + intercept_xz);
389  chi2ndf = chi2ndf_xy + chi2ndf_xz; // not really a chisquared per ndf, but perhaps good enough to pick which VH to assign a TPCCluster to
390  }
391  else if (slopesumy < slopesumx && slopesumy < slopesumz)
392  {
393  dir.SetXYZ(slope_yx,1.0,slope_yz);
394  double avgy = 0;
395  for (size_t i=0; i<y.size(); ++i)
396  {
397  avgy += y[i];
398  }
399  avgy /= y.size();
400  pos.SetXYZ(avgy*slope_yx + intercept_yx, avgy, avgy*slope_yz + intercept_yz);
401  chi2ndf = chi2ndf_yx + chi2ndf_yz; // not really a chisquared per ndf, but perhaps good enough to pick which VH to assign a TPCCluster to
402  }
403  else
404  {
405  dir.SetXYZ(slope_zx,slope_zy,1.0);
406  double avgz = 0;
407  for (size_t i=0; i<z.size(); ++i)
408  {
409  avgz += z[i];
410  }
411  avgz /= z.size();
412  pos.SetXYZ(avgz*slope_zx + intercept_zx, avgz*slope_zy + intercept_zy, avgz);
413  chi2ndf = chi2ndf_zx + chi2ndf_zy; // not really a chisquared per ndf, but perhaps good enough to pick which VH to assign a TPCCluster to
414  }
415  dir *= 1.0/dir.Mag();
416 
417  // put in fit values for y and z
418  }
419 
420  // fit with same weights on all points -- to think about: what are the uncertainties?
421 
422  void tpcvechitfinder2::fitline(std::vector<double> &x, std::vector<double> &y, double &slope, double &intercept, double &chi2ndf)
423  {
424  chi2ndf = 0;
425  size_t n = x.size();
426  if (n < 2)
427  {
428  throw cet::exception("tpcvechitfinder2_module.cc: too few TPCClusters to fit a line in linefit");
429  }
430  double sumx = 0;
431  double sumy = 0;
432  double sumxx = 0;
433  double sumxy = 0;
434 
435  for (size_t i=0; i<n; ++i)
436  {
437  sumx += x[i];
438  sumy += y[i];
439  sumxx += TMath::Sq(x[i]);
440  sumxy += x[i]*y[i];
441  }
442  double denom = (n*sumxx) - TMath::Sq(sumx);
443  if (denom == 0)
444  {
445  slope = 1E6; // is this right?
446  intercept = 0;
447  }
448  else
449  {
450  slope = (n*sumxy - sumx*sumy)/denom;
451  intercept = (sumxx*sumy - sumx*sumxy)/denom;
452  }
453  if (n > 2)
454  {
455  for (size_t i=0; i<n; ++i)
456  {
457  chi2ndf += TMath::Sq( y[i] - slope*x[i] - intercept ); // no errors for now.
458  }
459  chi2ndf /= (n-2);
460  }
461  else
462  {
463  chi2ndf = 1.0; // a choice here -- if we can add the TPCCluster to an existing VH or make a "perfect-chisquare" 2-TPCCluster VH?
464  // define a 2-TPCCluster VH to be not perfect.
465  }
466  }
467 
468 
469  void tpcvechitfinder2::fitlinesPCA(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z,
470  TVector3 &pos, TVector3 &dir, float &chi2ndf)
471  {
472  double* xyz[3];
473  xyz[0] = x.data();
474  xyz[1] = y.data();
475  xyz[2] = z.data();
476  size_t npts = x.size();
477  if (npts < 2)
478  {
479  throw cet::exception("tpcvechitfinder2_module.cc: too few TPCClusters to fit a line in linefit");
480  }
481 
482  TMatrixDSym covmat(3); // covariance matrix (use symmetric version)
483 
484  // position is just the average of the coordinates
485 
486  double psum[3] = {0,0,0};
487  for (size_t ipoint=0; ipoint<npts; ++ipoint)
488  {
489  for (size_t j=0; j<3; j++)
490  {
491  psum[j] += xyz[j][ipoint];
492  }
493  }
494  for (size_t j=0; j<3; ++j)
495  {
496  psum[j] /= npts;
497  }
498  pos.SetXYZ(psum[0],psum[1],psum[2]);
499 
500  for (size_t i=0; i<3; ++i)
501  {
502  for (size_t j=0; j<= i; ++j)
503  {
504  double csum=0;
505  for (size_t ipoint=0; ipoint<npts; ++ipoint)
506  {
507  csum += (xyz[i][ipoint] - psum[i]) * (xyz[j][ipoint] - psum[j]);
508  }
509  csum /= (npts-1);
510  covmat[i][j] = csum;
511  covmat[j][i] = csum;
512  }
513  }
514  TVectorD eigenvalues(3);
515  TMatrixD eigenvectors = covmat.EigenVectors(eigenvalues);
516  double dirv[3] = {0,0,0};
517  for (size_t i=0; i<3; ++i)
518  {
519  dirv[i]=eigenvectors[i][0];
520  }
521  dir.SetXYZ(dirv[0],dirv[1],dirv[2]);
522  chi2ndf = 0;
523 
524  for (size_t i=0; i<npts; ++i)
525  {
526  TVector3 pt(x[i],y[i],z[i]);
527  double dist = ((pt - pos).Cross(dir)).Mag(); // no uncertainties for now -- set all to 1
528  chi2ndf += dist*dist;
529  }
530  if (npts == 2)
531  {
532  chi2ndf = 1; // a choice -- same as the choice in fitlines6ls
533  }
534  else
535  {
536  chi2ndf /= (npts-2);
537  }
538  }
539 
541 
542  } // namespace rec
543 } // namespace gar
rec
Definition: tracks.py:88
std::string string
Definition: nybbler.cc:12
void fitlinesdir(std::vector< TVector3 > &hlist, TVector3 &pos, TVector3 &dir, float &chi2ndf)
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
std::vector< float > fVecHitRoad
max dist from a vector hit to a TPCCluster to assign it. for patrec alg 2. in cm. ...
string dir
std::vector< float > fTPCClusterRCut
only take TPCClusters within rcut of the center of the detector
int fLineFitAlg
Line Fit switch. 0: six least-squares, 1: PCA.
std::string fTPCClusterLabel
label of module to get the TPCClusters from
tpcvechitfinder2 & operator=(tpcvechitfinder2 const &)=delete
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
std::void_t< T > n
tpcvechitfinder2(fhicl::ParameterSet const &p)
void fitlinesPCA(std::vector< double > &x, std::vector< double > &y, std::vector< double > &z, TVector3 &pos, TVector3 &dir, float &chi2ndf)
def move(depos, offset)
Definition: depos.py:107
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
std::vector< unsigned int > fVecHitMinTPCClusters
minimum number of TPCClusters on a vector hit for it to be considered
std::vector< float > fMaxVecHitLen
maximum vector hit length in patrec alg 2, in cm
bool vh_TPCClusmatch(int iTPCCluster, vechit_t &vechit, const std::vector< gar::rec::TPCCluster > &TPCClusters, vechit_t &proposedvh, size_t ipass)
General GArSoft Utilities.
std::vector< float > fTPCClusterGapCut
in cm – skip TPC clusters within this distance of a gap
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::vector< float > fC2Cut
"chisquared" per ndof cut to reassign TPCClusters
list x
Definition: train.py:276
void fitline(std::vector< double > &x, std::vector< double > &y, double &lambda, double &intercept, double &chi2ndf)
void fitlines6ls(std::vector< double > &x, std::vector< double > &y, std::vector< double > &z, TVector3 &pos, TVector3 &dir, float &chi2ndf)
size_t fNPasses
number of passes to reassign TPCClusters from vector hits with poor chisquareds
int fPrintLevel
debug printout: 0: none, 1: selected, 2: all
LArSoft geometry interface.
Definition: ChannelGeo.h:16
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
void produce(art::Event &e) override