20 #include "canvas/Persistency/Common/FindManyP.h" 28 #include "nug4/MagneticFieldServices/MagneticFieldService.h" 29 #include "Geant4/G4ThreeVector.hh" 38 #include "CoreUtils/ServiceUtil.h" 81 bool vhclusmatch(
const std::vector<gar::rec::VecHit> &vechits, std::vector<size_t> &
cluster,
size_t vh);
93 std::vector<size_t> &splitclus1,
94 std::vector<size_t> &splitclus2);
118 consumes< std::vector<gar::rec::VecHit> >(vechitTag);
119 consumes< art::Assns<gar::rec::TPCCluster, gar::rec::VecHit> >(vechitTag);
120 produces< std::vector<gar::rec::Track> >();
121 produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
122 produces< art::Assns<gar::rec::VecHit, gar::rec::Track> >();
127 std::unique_ptr< std::vector<gar::rec::Track> > trkCol(
new std::vector<gar::rec::Track>);
128 std::unique_ptr< art::Assns<gar::rec::VecHit,gar::rec::Track> > vhTrkAssns(new ::art::Assns<gar::rec::VecHit,gar::rec::Track>);
129 std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
132 auto const& vechits = *vechitHandle;
137 const art::FindManyP<gar::rec::TPCCluster> TPCClustersFromVecHits(vechitHandle,e,
fVecHitLabel);
139 auto const *magFieldService = gar::providerFrom<mag::MagneticFieldService>();
140 G4ThreeVector zerovec(0,0,0);
141 G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
149 std::vector< std::vector< size_t > > vhclusters;
151 for (
size_t ivh = 0; ivh< vechits.size(); ++ ivh)
155 std::cout <<
" vhprint " << vechits[ivh].Position()[0] <<
" " << vechits[ivh].Position()[1] <<
" " << vechits[ivh].Position()[2] <<
" " <<
156 vechits[ivh].Direction()[0] <<
" " << vechits[ivh].Direction()[1] <<
" " << vechits[ivh].Direction()[2] <<
" " <<
std::endl;
159 std::vector<size_t> clusmatchlist;
160 for (
size_t iclus=0; iclus<vhclusters.size(); ++iclus)
164 clusmatchlist.push_back(iclus);
167 if (clusmatchlist.size() == 0)
169 std::vector<size_t> newclus;
170 newclus.push_back(ivh);
171 vhclusters.push_back(newclus);
173 else if (clusmatchlist.size() == 1)
175 vhclusters[clusmatchlist[0]].push_back(ivh);
179 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
181 for (
size_t ivh2=0; ivh2<vhclusters[clusmatchlist[icm]].size(); ++ivh2)
183 vhclusters[clusmatchlist[0]].push_back(vhclusters[clusmatchlist[icm]][ivh2]);
187 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
189 vhclusters.erase(vhclusters.begin() + (clusmatchlist[icm]-icm+1));
209 std::vector<size_t> identified_conversions;
210 std::vector< std::vector< size_t > > splitclus1;
211 std::vector< std::vector< size_t > > splitclus2;
213 for (
size_t iclus=0; iclus<vhclusters.size(); ++iclus)
216 std::vector<size_t> scc1;
217 std::vector<size_t> scc2;
220 identified_conversions.push_back(iclus);
221 splitclus1.push_back(scc1);
222 splitclus2.push_back(scc2);
228 for (
size_t icc=0; icc<identified_conversions.size(); ++icc)
237 vhclusters.at(identified_conversions.at(icc)) = splitclus1.at(icc);
238 vhclusters.push_back(splitclus2.at(icc));
243 for (
size_t iclus=0; iclus < vhclusters.size(); ++iclus)
245 std::vector<gar::rec::TPCCluster> TPCClusters;
246 std::vector<art::Ptr<gar::rec::TPCCluster> > TPCClusterptrs;
247 for (
size_t ivh=0; ivh<vhclusters[iclus].size(); ++ivh)
249 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromVecHits.at(vhclusters[iclus][ivh]).size(); ++iTPCCluster)
251 TPCClusterptrs.push_back(TPCClustersFromVecHits.at(vhclusters[iclus][ivh]).at(iTPCCluster));
252 TPCClusters.push_back(*TPCClusterptrs.back());
262 auto const trackpointer = trackPtrMaker(trkCol->size()-1);
263 for (
size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
265 TPCClusterTrkAssns->addSingle(TPCClusterptrs.at(iTPCCluster),trackpointer);
267 for (
size_t ivh=0; ivh<vhclusters[iclus].size(); ++ivh)
269 auto const vhpointer = vhPtrMaker(ivh);
270 vhTrkAssns->addSingle(vhpointer,trackpointer);
289 bool foundmatch =
false;
290 for (
size_t ivh=0; ivh<cluster.size(); ++ivh)
294 TVector3 vhtestpos(vhtest.
Position());
298 std::cout <<
"Testing vh " << ivh <<
" in a cluster of size: " << cluster.size() <<
std::endl;
307 std::cout <<
" Dot failure: " << TMath::Abs((vhdir).Dot(vhtestdir)) <<
std::endl;
318 std::cout <<
" Pos failure: " << (vhpos-vhtestpos).Mag() <<
std::endl;
330 std::cout <<
"PEX failure: " << ((vhpos-vhtestpos).Cross(vhdir)).Mag() <<
std::endl;
338 std::cout <<
"PEX failure: " << ((vhpos-vhtestpos).Cross(vhtestdir)).Mag() <<
std::endl;
349 std::cout <<
"Eta failure: " << eta <<
std::endl;
358 float vhpd = TMath::Sqrt( TMath::Sq(vhdir.Y()) + TMath::Sq(vhdir.Z()) );
359 float vhxd = TMath::Abs( vhdir.X() );
360 float vhlambda = TMath::Pi()/2.0;
361 if (vhpd >0) vhlambda = TMath::ATan(vhxd/vhpd);
363 float cvhpd = TMath::Sqrt( TMath::Sq(vhtestdir.Y()) + TMath::Sq(vhtestdir.Z()) );
364 float cvhxd = TMath::Abs( vhtestdir.X() );
365 float cvhlambda = TMath::Pi()/2.0;
366 if (cvhpd >0) cvhlambda = TMath::ATan(cvhxd/cvhpd);
372 std::cout <<
"dlambda failure: " << vhlambda <<
" " << cvhlambda <<
std::endl;
377 if ( vhdir.Dot(vhtestdir) * vhdir.X() * vhtestdir.X() < 0 &&
378 TMath::Abs(vhdir.X()) > 0.01 && TMath::Abs(vhtestdir.X()) > 0.01)
382 std::cout <<
"lambda sign failure" <<
std::endl;
389 std::cout <<
" vh cluster match " <<
std::endl;
437 float lengthforwards = 0;
438 std::vector<int> hlf;
439 float lengthbackwards = 0;
440 std::vector<int> hlb;
457 std::vector<float> tparbeg(6,0);
465 std::vector<float> tparend(6,0);
475 for (
size_t i=0; i<25; ++i)
506 TVector3 vhtestpos(vhtest.
Position());
510 TVector3 vhdp(vhdir);
512 float norm = vhdp.Mag();
513 if (norm > 0) vhdp *= (1.0/
norm);
517 TVector3 vhcp(vhtestdir);
520 if (norm > 0) vhcp *= (1.0/
norm);
523 if (vhdp.Dot(vhcp) < 0) relsign = -1;
525 TVector3 dcent = vhpos-vhtestpos;
528 TVector3 avgdir1 = 0.5*(vhdp + relsign*vhcp);
529 float amag = avgdir1.Mag();
530 if (amag != 0) avgdir1 *= 1.0/amag;
531 float eta = (dcent.Cross(avgdir1)).Mag();
540 std::vector<size_t> &cluster,
541 std::vector<size_t> &splitclus1,
542 std::vector<size_t> &splitclus2)
554 for (
size_t ivh=0; ivh<cluster.size(); ++ivh)
556 TVector3 vhpos(vechits.at(cluster.at(ivh)).Position());
558 for (
size_t jvh=0; jvh<cluster.size(); ++jvh)
560 if (ivh == jvh)
continue;
561 TVector3 vhpos2(vechits.at(cluster.at(jvh)).Position());
565 dsum += (vhpos-vhpos2).Mag();
575 if (dsummax == 0)
return(
false);
580 std::vector<size_t> already;
581 std::set<size_t> yet;
585 for(
size_t ivh=0; ivh<cluster.size(); ++ivh)
589 ivhlast = cluster.at(ivh);
590 already.push_back(ivhlast);
595 yet.insert(cluster.at(ivh));
599 TVector3 lastpdir(0,0,0);
602 TVector3 lastpos(vechits.at(ivhlast).Position());
605 while(yet.size() > 0)
612 bool foundmin =
false;
614 for (
auto iyet : yet)
616 TVector3 testpos(vechits.at(iyet).Position());
617 TVector3 testdir(vechits.at(iyet).Direction());
619 float dtest = (lastpos - testpos).Mag() +
calceta2d(lastvhdp,testvhdp);
620 if (dtest < dmin || !foundmin)
627 if (!foundmin)
return(
false);
628 TVector3 nextpos(vechits.at(inext).Position());
629 TVector3 nextdir(vechits.at(inext).Direction());
630 if (lastpdir.Mag() > 1
E-3)
632 TVector3 testpdir = nextpos - lastpos;
637 splitclus1 = already;
638 for (
auto iyet : yet)
640 splitclus2.push_back(iyet);
646 lastpdir = nextpos - lastpos;
647 already.push_back(inext);
651 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.
float fSortDistCut
distance cut to pass to hit sorting algorithm #2
const float * Direction() const
std::string fVecHitLabel
label of module to get the vector hits and associations with hits
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)
gar::rec::Track CreateTrack()
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 fConvAngleCut
cut on angle diff for the conversion finder to split a cluster of VH's into two tracks ...
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 sort_TPCClusters_along_track2(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float dcut)
void setXBeg(const float xbeg)
float fVecHitMatchLambda
matching condition for pairs of vector hits – dLambda (radians)
int fSortAlg
which hit sorting alg to use. 1: old, 2: greedy distance sort
float fSortTransWeight
for use in the hit sorting algorithm – transverse distance weight factor
tpcpatrec2 & operator=(tpcpatrec2 const &)=delete
void setChisqForwards(const float chisqforwards)
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)
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)