34 #include "TMatrixDSym.h" 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);
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});
99 fC2Cut =
p.get<std::vector<float>>(
"C2Cut",{0.5,0.5});
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> >();
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>);
115 auto const& TPCClusters = *TPCClusterHandle;
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);
128 std::vector<float> TPCClusterx;
129 for (
size_t i=0; i<TPCClusters.size(); ++i)
131 TPCClusterx.push_back(TPCClusters[i].Position()[0]);
133 std::vector<int> hsi(TPCClusterx.size());
134 TMath::Sort((
int) TPCClusterx.size(),TPCClusterx.data(),hsi.data());
136 std::vector<vechit_t> vechits;
137 std::vector<vechit_t> vhtmp;
141 for (
size_t ipass=0; ipass<
fNPasses; ++ipass)
143 for (
size_t iTPCClusterxs=0; iTPCClusterxs<hsi.size(); ++iTPCClusterxs)
145 int iTPCCluster = hsi[iTPCClusterxs];
146 const float *hpos = TPCClusters[iTPCCluster].Position();
147 TVector3 hpvec(hpos);
148 TVector3 cprel = hpvec - tpccent;
149 float rclus = (cprel.Cross(xhat)).Mag();
157 if ( rclus > geo->GetIROCInnerRadius())
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);
164 float rotang = ( isector*TMath::Pi()/9.0 );
165 float crot = TMath::Cos(rotang);
166 float srot = TMath::Sin(rotang);
168 float yrot = - cprel.Z()*srot + cprel.Y()*crot;
175 size_t ibestmatch = 0;
177 for (
size_t ivh=0; ivh<vhtmp.size(); ++ivh)
180 if (
vh_TPCClusmatch(iTPCCluster, vhtmp[ivh], TPCClusters, proposedvh, ipass ))
182 if (!matched || proposedvh.
c2ndf < bestproposedvh.
c2ndf )
186 bestproposedvh = proposedvh;
193 vh.
pos.SetXYZ(hpos[0],hpos[1],hpos[2]);
194 vh.
dir.SetXYZ(0,0,0);
203 vhtmp[ibestmatch] = bestproposedvh;
211 if (fNPasses > 1 && ipass < fNPasses-1)
214 std::vector<vechit_t> vhtmp2;
215 for (
size_t ivh=0; ivh<vhtmp.size(); ++ivh)
219 std::cout <<
"about to push vh: " << ivh <<
" " << vhtmp[ivh].c2ndf <<
" " << vhtmp[ivh].TPCClusterindex.size() <<
std::endl;
223 vhtmp2.push_back(vhtmp[ivh]);
227 for (
size_t iTPCCluster=0; iTPCCluster<vhtmp[ivh].TPCClusterindex.size(); ++iTPCCluster)
229 hsi.push_back(vhtmp[ivh].TPCClusterindex[iTPCCluster]);
236 std::cout <<
"left with " << vhtmp.size() <<
" vec hits and " << hsi.size() <<
" TPCClusters to reassociate " <<
std::endl;
243 for (
size_t ivh=0; ivh<vhtmp.size(); ++ivh)
245 vechits.push_back(vhtmp[ivh]);
247 float pos[3] = {0,0,0};
248 float dir[3] = {0,0,0};
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)
255 auto const TPCClusterpointer = TPCClusterPtrMaker(vh.
TPCClusterindex[iTPCCluster]);
256 TPCClusterVHAssns->addSingle(TPCClusterpointer,vhpointer);
271 TVector3 hpvec(TPCClusters.at(iTPCCluster).Position());
273 float newlength = vechit.
length;
277 TVector3 ht(TPCClusters.at(vechit.
TPCClusterindex.at(iht)).Position());
278 float d = (hpvec - ht).Mag();
280 dist = TMath::Min(dist,d);
281 newlength = TMath::Max(newlength,d);
286 dist = ((hpvec - vechit.
pos).Cross(vechit.
dir)).Mag();
293 std::vector<TVector3> hplist;
296 hplist.emplace_back(TPCClusters[vechit.
TPCClusterindex[i]].Position());
298 hplist.push_back(hpvec);
303 proposedvh.
length = newlength;
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)
320 x.push_back(hlist[i].
X());
321 y.push_back(hlist[i].
Y());
322 z.push_back(hlist[i].
Z());
339 TVector3 &
pos, TVector3 &
dir,
float &chi2ndf)
343 double intercept_yx=0;
344 double intercept_zx=0;
348 double intercept_yz=0;
349 double intercept_xz=0;
353 double intercept_xy=0;
354 double intercept_zy=0;
363 fitline(x,y,slope_xy,intercept_xy,chi2ndf_xy);
364 fitline(x,z,slope_xz,intercept_xz,chi2ndf_xz);
366 fitline(y,z,slope_yz,intercept_yz,chi2ndf_yz);
367 fitline(y,x,slope_yx,intercept_yx,chi2ndf_yx);
369 fitline(z,y,slope_zy,intercept_zy,chi2ndf_zy);
370 fitline(z,x,slope_zx,intercept_zx,chi2ndf_zx);
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);
379 if (slopesumx < slopesumy && slopesumx < slopesumz)
381 dir.SetXYZ(1.0,slope_xy,slope_xz);
383 for (
size_t i=0; i<x.size(); ++i)
388 pos.SetXYZ(avgx, avgx*slope_xy + intercept_xy, avgx*slope_xz + intercept_xz);
389 chi2ndf = chi2ndf_xy + chi2ndf_xz;
391 else if (slopesumy < slopesumx && slopesumy < slopesumz)
393 dir.SetXYZ(slope_yx,1.0,slope_yz);
395 for (
size_t i=0; i<y.size(); ++i)
400 pos.SetXYZ(avgy*slope_yx + intercept_yx, avgy, avgy*slope_yz + intercept_yz);
401 chi2ndf = chi2ndf_yx + chi2ndf_yz;
405 dir.SetXYZ(slope_zx,slope_zy,1.0);
407 for (
size_t i=0; i<z.size(); ++i)
412 pos.SetXYZ(avgz*slope_zx + intercept_zx, avgz*slope_zy + intercept_zy, avgz);
413 chi2ndf = chi2ndf_zx + chi2ndf_zy;
415 dir *= 1.0/dir.Mag();
428 throw cet::exception(
"tpcvechitfinder2_module.cc: too few TPCClusters to fit a line in linefit");
435 for (
size_t i=0; i<
n; ++i)
439 sumxx += TMath::Sq(x[i]);
442 double denom = (n*sumxx) - TMath::Sq(sumx);
450 slope = (n*sumxy - sumx*sumy)/denom;
451 intercept = (sumxx*sumy - sumx*sumxy)/denom;
455 for (
size_t i=0; i<
n; ++i)
457 chi2ndf += TMath::Sq( y[i] - slope*x[i] - intercept );
470 TVector3 &
pos, TVector3 &
dir,
float &chi2ndf)
476 size_t npts = x.size();
479 throw cet::exception(
"tpcvechitfinder2_module.cc: too few TPCClusters to fit a line in linefit");
482 TMatrixDSym covmat(3);
486 double psum[3] = {0,0,0};
487 for (
size_t ipoint=0; ipoint<npts; ++ipoint)
489 for (
size_t j=0; j<3; j++)
491 psum[j] += xyz[j][ipoint];
494 for (
size_t j=0; j<3; ++j)
498 pos.SetXYZ(psum[0],psum[1],psum[2]);
500 for (
size_t i=0; i<3; ++i)
502 for (
size_t j=0; j<= i; ++j)
505 for (
size_t ipoint=0; ipoint<npts; ++ipoint)
507 csum += (xyz[i][ipoint] - psum[i]) * (xyz[j][ipoint] - psum[j]);
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)
519 dirv[i]=eigenvectors[i][0];
521 dir.SetXYZ(dirv[0],dirv[1],dirv[2]);
524 for (
size_t i=0; i<npts; ++i)
526 TVector3 pt(x[i],y[i],z[i]);
527 double dist = ((pt -
pos).Cross(dir)).Mag();
528 chi2ndf += dist*
dist;
void fitlinesdir(std::vector< TVector3 > &hlist, TVector3 &pos, TVector3 &dir, float &chi2ndf)
EDProducer(fhicl::ParameterSet const &pset)
std::vector< float > fVecHitRoad
max dist from a vector hit to a TPCCluster to assign it. for patrec alg 2. in cm. ...
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
std::vector< size_t > TPCClusterindex
#define DEFINE_ART_MODULE(klass)
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)
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
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
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.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
void produce(art::Event &e) override