20 #include "canvas/Persistency/Common/FindManyP.h" 28 #include "Geant4/G4ThreeVector.hh" 29 #include "nutools/MagneticField/MagneticField.h" 83 bool vhclusmatch(
const std::vector<gar::rec::VecHit> &vechits, std::vector<size_t> &
cluster,
size_t vh);
95 std::vector<size_t> &splitclus1,
96 std::vector<size_t> &splitclus2);
120 if (fPatRecLookBack1 == fPatRecLookBack2)
122 throw cet::exception(
"tpcpatrec2_module: PatRecLookBack1 and PatRecLookBack2 are the same");
129 consumes< std::vector<gar::rec::VecHit> >(vechitTag);
130 consumes< art::Assns<gar::rec::TPCCluster, gar::rec::VecHit> >(vechitTag);
131 produces< std::vector<gar::rec::Track> >();
132 produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
133 produces< art::Assns<gar::rec::VecHit, gar::rec::Track> >();
138 std::unique_ptr< std::vector<gar::rec::Track> > trkCol(
new std::vector<gar::rec::Track>);
139 std::unique_ptr< art::Assns<gar::rec::VecHit,gar::rec::Track> > vhTrkAssns(new ::art::Assns<gar::rec::VecHit,gar::rec::Track>);
140 std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
143 auto const& vechits = *vechitHandle;
146 auto const& e_tpcclusters = *TPCClusterHandle;
152 const art::FindManyP<gar::rec::TPCCluster> TPCClustersFromVecHits(vechitHandle,e,
fVecHitLabel);
155 G4ThreeVector zerovec(0,0,0);
156 G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
158 std::set<gar::rec::IDNumber> TPCClusNumerosUsedInFirstPass;
165 std::vector< std::vector< size_t > > vhclusters;
167 for (
size_t ivh = 0; ivh< vechits.size(); ++ ivh)
171 std::cout <<
" vhprint " << vechits[ivh].Position()[0] <<
" " << vechits[ivh].Position()[1] <<
" " << vechits[ivh].Position()[2] <<
" " <<
172 vechits[ivh].Direction()[0] <<
" " << vechits[ivh].Direction()[1] <<
" " << vechits[ivh].Direction()[2] <<
" " <<
std::endl;
175 std::vector<size_t> clusmatchlist;
176 for (
size_t iclus=0; iclus<vhclusters.size(); ++iclus)
180 clusmatchlist.push_back(iclus);
183 if (clusmatchlist.size() == 0)
185 std::vector<size_t> newclus;
186 newclus.push_back(ivh);
187 vhclusters.push_back(newclus);
189 else if (clusmatchlist.size() == 1)
191 vhclusters[clusmatchlist[0]].push_back(ivh);
195 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
197 for (
size_t ivh2=0; ivh2<vhclusters[clusmatchlist[icm]].size(); ++ivh2)
199 vhclusters[clusmatchlist[0]].push_back(vhclusters[clusmatchlist[icm]][ivh2]);
203 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
205 vhclusters.erase(vhclusters.begin() + (clusmatchlist[icm]-icm+1));
225 std::vector<size_t> identified_conversions;
226 std::vector< std::vector< size_t > > splitclus1;
227 std::vector< std::vector< size_t > > splitclus2;
229 for (
size_t iclus=0; iclus<vhclusters.size(); ++iclus)
231 std::vector<size_t> scc1;
232 std::vector<size_t> scc2;
235 identified_conversions.push_back(iclus);
236 splitclus1.push_back(scc1);
237 splitclus2.push_back(scc2);
243 for (
size_t icc=0; icc<identified_conversions.size(); ++icc)
245 vhclusters.at(identified_conversions.at(icc)) = splitclus1.at(icc);
246 vhclusters.push_back(splitclus2.at(icc));
251 for (
size_t iclus=0; iclus < vhclusters.size(); ++iclus)
253 std::vector<gar::rec::TPCCluster> TPCClusters;
254 std::vector<art::Ptr<gar::rec::TPCCluster> > TPCClusterptrs;
255 for (
size_t ivh=0; ivh<vhclusters[iclus].size(); ++ivh)
257 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromVecHits.at(vhclusters[iclus][ivh]).size(); ++iTPCCluster)
259 TPCClusterptrs.push_back(TPCClustersFromVecHits.at(vhclusters[iclus][ivh]).at(iTPCCluster));
260 TPCClusters.push_back(*TPCClusterptrs.back());
270 auto const trackpointer = trackPtrMaker(trkCol->size()-1);
271 for (
size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
273 TPCClusNumerosUsedInFirstPass.insert(TPCClusters.at(iTPCCluster).getIDNumber());
274 TPCClusterTrkAssns->addSingle(TPCClusterptrs.at(iTPCCluster),trackpointer);
276 for (
size_t ivh=0; ivh<vhclusters[iclus].size(); ++ivh)
278 auto const vhpointer = vhPtrMaker(ivh);
279 vhTrkAssns->addSingle(vhpointer,trackpointer);
297 std::vector<gar::rec::TPCCluster> tcc2pass;
298 std::vector<float> clusx;
299 std::vector<size_t> tcc2passidx;
304 for (
size_t iclus=0; iclus < e_tpcclusters.size(); ++iclus)
306 if (TPCClusNumerosUsedInFirstPass.count(e_tpcclusters.at(iclus).getIDNumber()) == 0)
308 tcc2pass.push_back(e_tpcclusters.at(iclus));
309 tcc2passidx.push_back(iclus);
310 clusx.push_back(tcc2pass.back().Position()[0]);
314 if (tcc2pass.size()>0)
316 std::vector<int> csi(clusx.size());
317 TMath::Sort((
int) clusx.size(),clusx.data(),csi.data());
322 std::vector< std::vector<int> > cluslistf;
323 std::vector<int> trackf(tcc2pass.size());
324 for (
size_t iclus=0; iclus<tcc2pass.size(); ++iclus)
326 const float *cpos = tcc2pass[csi[iclus]].Position();
327 TVector3 hpvec(cpos);
329 float bestsignifs = -1;
331 for (
size_t itcand = 0; itcand < cluslistf.size(); ++itcand)
345 const float *hpos = tcc2pass[csi[cluslistf[itcand].back()]].Position();
346 signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
347 TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
349 if (bestsignifs < 0 || signifs < bestsignifs)
351 bestsignifs = signifs;
355 if (ibest == -1 || bestsignifs > roadsq)
357 ibest = cluslistf.size();
358 std::vector<int> vtmp;
359 cluslistf.push_back(vtmp);
361 cluslistf[ibest].push_back(iclus);
362 trackf[iclus] = ibest;
365 std::vector< std::vector<int> > cluslistb;
366 std::vector<int> trackb(tcc2pass.size());
367 for (
int iclus=tcc2pass.size()-1; iclus >= 0; --iclus)
369 const float *cpos = tcc2pass[csi[iclus]].Position();
370 TVector3 hpvec(cpos);
372 float bestsignifs = -1;
374 for (
size_t itcand = 0; itcand < cluslistb.size(); ++itcand)
388 const float *hpos = tcc2pass[csi[cluslistb[itcand].back()]].Position();
389 signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
390 TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
393 if (bestsignifs < 0 || signifs < bestsignifs)
395 bestsignifs = signifs;
399 if (ibest == -1 || bestsignifs > roadsq)
401 ibest = cluslistb.size();
402 std::vector<int> vtmp;
403 cluslistb.push_back(vtmp);
405 cluslistb[ibest].push_back(iclus);
406 trackb[iclus] = ibest;
411 std::vector< std::vector<int> > cluslist;
412 for (
size_t itrack=0; itrack<cluslistf.size(); ++itrack)
415 for (
size_t iclus=0; iclus<cluslistf[itrack].size(); ++iclus)
417 int ihif = cluslistf[itrack][iclus];
418 if (iclus == 0 || (trackb[ihif] != itrackl))
420 std::vector<int> vtmp;
421 cluslist.push_back(vtmp);
422 itrackl = trackb[ihif];
424 cluslist.back().push_back(ihif);
430 for (
size_t itrack=0; itrack<cluslist.size(); ++itrack)
433 std::vector<gar::rec::TPCCluster>
tcl;
434 for (
size_t iclus=0; iclus<cluslist.at(itrack).size(); ++iclus)
436 tcl.push_back(tcc2pass.at(csi[cluslist[itrack].at(iclus)]));
442 auto const trackptr = trackPtrMaker(trkCol->size()-1);
443 for (
size_t iclus=0; iclus<tcl.size(); ++iclus)
445 auto const clusptr = clusPtrMaker(tcc2passidx.at(csi[cluslist[itrack][iclus]]));
446 TPCClusterTrkAssns->addSingle(clusptr,trackptr);
449 std::cout <<
" second-pass track " << itrack <<
" clus: " << iclus <<
" : ";
450 TVector3 cp(tcc2pass[csi[cluslist[itrack][iclus]]].Position());
451 std::cout << cp.X() <<
" " << cp.Y() <<
" " << cp.Z() <<
std::endl;
473 bool foundmatch =
false;
474 for (
size_t ivh=0; ivh<cluster.size(); ++ivh)
478 TVector3 vhtestpos(vhtest.
Position());
482 std::cout <<
"Testing vh " << ivh <<
" in a cluster of size: " << cluster.size() <<
std::endl;
491 std::cout <<
" Dot failure: " << TMath::Abs((vhdir).Dot(vhtestdir)) <<
std::endl;
502 std::cout <<
" Pos failure: " << (vhpos-vhtestpos).Mag() <<
std::endl;
514 std::cout <<
"PEX failure: " << ((vhpos-vhtestpos).Cross(vhdir)).Mag() <<
std::endl;
522 std::cout <<
"PEX failure: " << ((vhpos-vhtestpos).Cross(vhtestdir)).Mag() <<
std::endl;
533 std::cout <<
"Eta failure: " << eta <<
std::endl;
542 float vhpd = TMath::Sqrt( TMath::Sq(vhdir.Y()) + TMath::Sq(vhdir.Z()) );
543 float vhxd = TMath::Abs( vhdir.X() );
544 float vhlambda = TMath::Pi()/2.0;
545 if (vhpd >0) vhlambda = TMath::ATan(vhxd/vhpd);
547 float cvhpd = TMath::Sqrt( TMath::Sq(vhtestdir.Y()) + TMath::Sq(vhtestdir.Z()) );
548 float cvhxd = TMath::Abs( vhtestdir.X() );
549 float cvhlambda = TMath::Pi()/2.0;
550 if (cvhpd >0) cvhlambda = TMath::ATan(cvhxd/cvhpd);
556 std::cout <<
"dlambda failure: " << vhlambda <<
" " << cvhlambda <<
std::endl;
561 if ( vhdir.Dot(vhtestdir) * vhdir.X() * vhtestdir.X() < 0 &&
562 TMath::Abs(vhdir.X()) > 0.01 && TMath::Abs(vhtestdir.X()) > 0.01)
566 std::cout <<
"lambda sign failure" <<
std::endl;
573 std::cout <<
" vh cluster match " <<
std::endl;
621 float lengthforwards = 0;
622 std::vector<int> hlf;
623 float lengthbackwards = 0;
624 std::vector<int> hlb;
628 std::vector<float> tparbeg(6,0);
636 std::vector<float> tparend(6,0);
646 for (
size_t i=0; i<25; ++i)
677 TVector3 vhtestpos(vhtest.
Position());
681 TVector3 vhdp(vhdir);
683 float norm = vhdp.Mag();
684 if (norm > 0) vhdp *= (1.0/
norm);
688 TVector3 vhcp(vhtestdir);
691 if (norm > 0) vhcp *= (1.0/
norm);
694 if (vhdp.Dot(vhcp) < 0) relsign = -1;
696 TVector3 dcent = vhpos-vhtestpos;
699 TVector3 avgdir1 = 0.5*(vhdp + relsign*vhcp);
700 float amag = avgdir1.Mag();
701 if (amag != 0) avgdir1 *= 1.0/amag;
702 float eta = (dcent.Cross(avgdir1)).Mag();
712 std::vector<size_t> &splitclus1,
713 std::vector<size_t> &splitclus2)
724 for (
size_t ivh=0; ivh<cluster.size(); ++ivh)
726 TVector3 vhpos(vechits.at(cluster.at(ivh)).Position());
728 for (
size_t jvh=0; jvh<cluster.size(); ++jvh)
730 if (ivh == jvh)
continue;
731 TVector3 vhpos2(vechits.at(cluster.at(jvh)).Position());
735 dsum += (vhpos-vhpos2).Mag();
745 if (dsummax == 0)
return(
false);
750 std::vector<size_t> already;
751 std::set<size_t> yet;
755 for(
size_t ivh=0; ivh<cluster.size(); ++ivh)
759 ivhlast = cluster.at(ivh);
760 already.push_back(ivhlast);
765 yet.insert(cluster.at(ivh));
769 TVector3 lastpdir(0,0,0);
772 TVector3 lastpos(vechits.at(ivhlast).Position());
775 while(yet.size() > 0)
782 bool foundmin =
false;
784 for (
auto iyet : yet)
786 TVector3 testpos(vechits.at(iyet).Position());
787 TVector3 testdir(vechits.at(iyet).Direction());
789 float dtest = (lastpos - testpos).Mag() +
calceta2d(lastvhdp,testvhdp);
790 if (dtest < dmin || !foundmin)
797 if (!foundmin)
return(
false);
798 TVector3 nextpos(vechits.at(inext).Position());
799 TVector3 nextdir(vechits.at(inext).Direction());
800 if (lastpdir.Mag() > 1
E-3)
802 TVector3 testpdir = nextpos - lastpos;
803 if (testpdir.Angle(lastpdir) > 3)
806 splitclus1 = already;
807 for (
auto iyet : yet)
809 splitclus2.push_back(iyet);
815 lastpdir = nextpos - lastpos;
816 already.push_back(inext);
820 lastvhdp = vechits.at(inext);
void setNTPCClusters(const size_t nTPCClusters)
size_t fMinNumTPCClusters
minimum number of hits for a patrec track
void setLengthForwards(const float lengthforwards)
int fPrintLevel
debug printout: 0: none, 1: selected, 2: all
const float * Position() const
void setCovMatBeg(const float *covmatbeg)
EDProducer(fhicl::ParameterSet const &pset)
tpcpatrec2(fhicl::ParameterSet const &p)
void setLengthBackwards(const float lengthbackwards)
Cluster finding and building.
const float * Direction() const
std::string fVecHitLabel
label of module to get the vector hits and associations with hits
size_t fPatRecLookBack2
extrapolate from lookback1 to lookback2 and see how close the new hit is to the line ...
void setTrackParametersBegin(const float *tparbeg)
#define DEFINE_ART_MODULE(klass)
bool vhclusmatch(const std::vector< gar::rec::VecHit > &vechits, std::vector< size_t > &cluster, size_t vh)
void setXEnd(const float xend)
void setTrackParametersEnd(const float *tparend)
float calceta2d(gar::rec::VecHit &vhtest, gar::rec::VecHit &vh)
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
float fVecHitMatchEta
matching condition for pairs of vector hits – eta match (cm)
unsigned int fInitialTPNTPCClusters
number of hits to use for initial trackpar estimate, if present
void setChisqBackwards(const float chisqbackwards)
std::string fTPCClusterLabel
label of module to get the TPC clusters
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
gar::rec::Track CreateTrack()
size_t fPatRecLookBack1
n hits to look backwards to make a linear extrapolation
auto norm(Vector const &v)
Return norm of the specified vector.
bool conversion_test_split(const std::vector< gar::rec::VecHit > &vechits, std::vector< size_t > &cluster, std::vector< size_t > &splitclus1, std::vector< size_t > &splitclus2)
float fHitResolX
resolution in cm of a hit in X (drift direction)
float fCloseEtaUnmatch
distance to look for vector hits that don't match in eta.
General GArSoft Utilities.
int makepatrectrack(std::vector< gar::rec::TPCCluster > &tpcclusters, gar::rec::TrackPar &trackpar)
void setCovMatEnd(const float *covmatend)
void sort_TPCClusters_along_track(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float sorttransweight, float sortdistback)
void setXBeg(const float xbeg)
float fVecHitMatchLambda
matching condition for pairs of vector hits – dLambda (radians)
int fXBasedMinTPCClusters
min number of TPC clusters to require on new tracks found with the second pass
float fSortTransWeight
for use in the hit sorting algorithm – transverse distance weight factor
tpcpatrec2 & operator=(tpcpatrec2 const &)=delete
void setChisqForwards(const float chisqforwards)
bool fXBasedSecondPass
switch to tell us to use the X-based second-pass of patrec
float fVecHitMatchPEX
matching condition for pairs of vector hits – miss distance (cm)
float fVecHitMatchCos
matching condition for pairs of vector hits cos angle between directions
float fSortDistBack
for use in the hit sorting algorithm – how far to go back before raising the distance figure of meri...
float fVecHitMatchPos
matching condition for pairs of vector hits – 3D distance (cm)
float fSigmaRoad
how many sigma away from a track a hit can be and still add it during patrec
void setTime(const double time)
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
void produce(art::Event &e) override
int initial_trackpar_estimate(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &TPCClusterlist, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end, unsigned int initialtpnTPCClusters, int printlevel)