21 #include "messagefacility/MessageLogger/MessageLogger.h"
22 #include "fhiclcpp/ParameterSet.h"
23 #include "art/Framework/Principal/Event.h"
24 #include "canvas/Persistency/Common/Ptr.h"
25 #include "canvas/Persistency/Common/PtrVector.h"
40 fCosAngTol = pset.get<
double >(
"CosAngTolerance", 0.95);
41 fSepTol = pset.get<
double >(
"SpptSepTolerance", 10.0);
49 fTrackComposite.clear();
52 EvtArg.getByLabel(trackModuleLabelArg,ftListHandle);
58 int ntrack = ftListHandle->size();
60 for(
int ii = 0; ii < ntrack; ++ii) {
61 art::Ptr<recob::Track> ptrack1(ftListHandle, ii);
63 const TVector3 start1(track1.
Vertex<TVector3>());
64 const TVector3 end1(track1.
End<TVector3>());
68 std::vector< std::tuple< std::string, int, int, double, double> > headvv;
69 std::vector< std::tuple< std::string, int, int, double, double> > tailvv;
72 std::vector< std::vector<std::pair< double, double>> > matchhead;
73 std::vector< std::vector<std::pair< double, double>> > matchtail;
78 for(
int jj = ii+1; jj < ntrack; ++jj) {
79 art::Ptr<recob::Track> ptrack2(ftListHandle, jj);
81 const TVector3& start2(track2.
Vertex<TVector3>());
82 const TVector3& end2(track2.
End<TVector3>());
84 const TVector3& end2Dir(track2.
EndDirection<TVector3>());
85 std::string sHT2(
"NA");
88 bool c12((
std::abs(start1Dir.Dot(end2Dir))>fCosAngTol) && ((start1-end2).Mag()<fSepTol));
89 bool c21((
std::abs(end1Dir.Dot(start2Dir))>fCosAngTol) && ((start2-end1).Mag()<fSepTol));
90 bool c11((
std::abs(start1Dir.Dot(start2Dir))>fCosAngTol) && ((start1-start2).Mag()<fSepTol));
91 bool c22((
std::abs(end1Dir.Dot(end2Dir))>fCosAngTol) && ((end1-end2).Mag()<fSepTol));
93 if ( c12 || c21 || c11 || c22 )
97 if (c12||c11) { head=
true; }
98 if (c11) { sHT2 =
"H"; }
else if (c12) { sHT2 =
"T"; }
99 if (c21||c22) { tail=
true; }
100 if (c21) { sHT2 =
"H"; }
else if (c22) { sHT2 =
"T"; }
104 head =
false; tail =
false;
105 if ( ((start1-end2).Mag() < (start2-end1).Mag()) || ((start1-end2).Mag() < (start2-end2).Mag()) || ((start1-start2).Mag() < (start2-end1).Mag()) || ((start1-start2).Mag() < (start2-end2).Mag()) )
106 { head =
true; tail =
false; }
108 { head =
false; tail =
true; }
114 std::vector< std::pair <double,double> > headv;
115 headv.push_back(std::pair<double,double>(
abs(start1Dir.Dot(start2Dir)), (start1-start2).Mag()) );
116 headv.push_back(std::pair<double,double>(
abs(start1Dir.Dot(end2Dir)), (start1-end2).Mag()) );
118 matchhead.push_back( headv );
120 if ( ((matchhead.size() > 1) && ( (matchhead.back().at(0).second < matchhead.front().at(0).second) || (matchhead.back().at(1).second < matchhead.front().at(1).second ) ) ) || matchhead.size()==1 )
122 if (matchhead.size()>1) matchhead.erase(matchhead.begin());
123 if (headvv.size()>1) headvv.erase(headvv.begin());
124 if (!sHT2.compare(
"H"))
126 auto tupTmp =std::make_tuple(sHT2,ii,jj,matchhead.back().at(0).first,matchhead.back().at(0).second);
127 headvv.push_back (tupTmp);
131 auto tupTmp = std::make_tuple(sHT2,ii,jj,matchhead.back().at(1).first,matchhead.back().at(1).second);
132 headvv.push_back (tupTmp);
136 matchhead.pop_back();
147 std::vector< std::pair <double,double> > tailv;
148 tailv.push_back(std::pair<double,double>(
abs(end1Dir.Dot(start2Dir)),(start2-end1).Mag() ) );
149 tailv.push_back(std::pair<double,double>(
abs(end1Dir.Dot(end2Dir)),(end1-end2).Mag() ) );
150 matchtail.push_back( tailv );
152 if ( ((matchtail.size() > 1) && ( (matchtail.back().at(0).second < matchtail.front().at(0).second) || (matchtail.back().at(1).second < matchtail.front().at(1).second ) ) ) || matchtail.size()==1 )
154 if (matchtail.size()>1) matchtail.erase(matchtail.begin());
155 if (tailvv.size()>1) tailvv.erase(tailvv.begin());
156 if (!sHT2.compare(
"T"))
158 auto tupTmp = std::make_tuple(sHT2,ii,jj,matchtail.back().at(0).first,matchtail.back().at(0).second);
159 tailvv.push_back(tupTmp);
163 auto tupTmp = std::make_tuple(sHT2,ii,jj,matchtail.back().at(1).first,matchtail.back().at(1).second);
164 tailvv.push_back(tupTmp);
168 matchtail.pop_back();
185 int otrk = std::get<2>(headvv.back());
187 std::string sotrkht(std::get<0>(headvv.back()));
188 for (
int kk=0;kk<ii;++kk)
190 if (std::get<2>(fh.at(kk)) == otrk && !sotrkht.compare(std::get<0>(fh.at(kk)) ) )
195 if (std::get<4>(headvv.back()) < std::get<4>(fh.at(kk)) && std::get<4>(headvv.back())!=0.0)
197 auto tupTmp2 = std::make_tuple(std::string(
"NA"),kk,-12,0.0,0.0);
200 else if (std::get<4>(headvv.back())!=0.0)
210 int otrk = std::get<2>(tailvv.back());
212 std::string sotrkht(std::get<0>(tailvv.back()));
213 for (
int kk=0;kk<ii;++kk)
215 if (std::get<2>(ft.at(kk)) == otrk && !sotrkht.compare(std::get<0>(ft.at(kk)) ) )
219 if (std::get<4>(tailvv.back()) < std::get<4>(ft.at(kk)) && std::get<4>(tailvv.back())!=0.0)
221 auto tupTmp2 = std::make_tuple(std::string(
"NA"),kk,-12,0.0,0.0);
224 else if (std::get<4>(tailvv.back())!=0.0)
237 auto tupTmp2 = std::make_tuple(std::string(
"NA"),ii,-12,0.0,0.0);
239 if (!headvv.size()) headvv.push_back(tupTmp2);
240 if (!tailvv.size()) tailvv.push_back(tupTmp2);
242 fh.push_back(headvv.back());
243 ft.push_back(tailvv.back());
256 std::vector<recob::tracking::Point_t> xyz;
257 std::vector<recob::tracking::Vector_t> dxdydz;
258 std::vector<recob::tracking::SMatrixSym55> cov;
259 std::vector<recob::TrackTrajectory::PointFlags_t> flgs;
262 bool hasMomentum =
true;
263 for (
auto it = (*itvvArg).begin(); it!=(*itvvArg).end(); ++it)
265 if ((*it).get()->HasMomentum()==
false) {
272 for (
auto it = (*itvvArg).begin(); it!=(*itvvArg).end(); ++it)
277 for (
size_t pt = 0; pt!=(*it).get()->NumberTrajectoryPoints(); pt++)
285 auto itvfHT = fHT.begin() + size_t (itvArg - fTrackVec.begin());
286 if ( (*itvfHT).size() &&
289 (cnt==1 && !(*itvfHT).at(cnt-1).compare(0,1,
"H")) ||
290 (cnt>1 && !(*itvfHT).at(cnt-2).compare(1,1,
"T"))
293 ptHere = (*it).get()->NumberTrajectoryPoints() - pt - 1;
297 xyz.push_back((*it).get()->LocationAtPoint(ptHere));
299 dxdydz.push_back( (hasMomentum ? (*it).get()->MomentumVectorAtPoint(ptHere) : (*it).get()->DirectionAtPoint(ptHere)) );
300 flgs.push_back((*it).get()->FlagsAtPoint(ptHere));
301 cov.push_back( (ptHere==0 ? (*it).get()->VertexCovariance() : (*it).get()->EndCovariance()));
303 catch (cet::exception &
e)
305 mf::LogVerbatim(
"TrackStitcher bailing. ") <<
" One or more of xyz, dxdydz, cov, mom, dQdx elements from original Track is out of range..." << e.what() << __LINE__;
317 0, -1., 0, cov.front(), cov.back(), ftNo++);
319 fTrackVec.insert(itvArg,t);
326 art::PtrVector<recob::Track> compTrack;
327 std::vector <std::string> trackStatus (fh.size(),
"NotDone");
328 std::vector <std::string> HT2 ;
331 for (
unsigned int ii=0; ii<fh.size(); ++ii)
334 if (!trackStatus.at(ii).compare(
"Done"))
continue;
336 const art::Ptr<recob::Track> th(ftListHandle, ii);
337 compTrack.push_back(th);
345 std::string sh(std::get<0>(fh.at(walk)));
346 std::string st(
"NA");
353 sh = std::get<0>(fh.at(walk));
354 st = std::get<0>(ft.at(walk));
358 if (!sh.compare(
"H") || !sh.compare(
"T"))
361 hInd = std::get<2>(fh.at(walk));
364 const art::Ptr<recob::Track> th2( ftListHandle, hInd );
365 compTrack.push_back(th2);
366 HT2.push_back(
"H"+sh);
369 if ((!st.compare(
"H") || !st.compare(
"T")))
371 tInd = std::get<2>(ft.at(walk));
373 const art::Ptr<recob::Track> th2( ftListHandle, tInd );
374 compTrack.push_back(th2);
375 HT2.push_back(
"T"+st);
377 if (hInd!=-12) walk = hInd;
378 if (tInd!=-12) walk = tInd;
379 if (!sh.compare(
"NA") && !st.compare(
"NA"))
382 trackStatus.at(walk) =
"Done";
390 st = std::get<0>(ft.at(walk));
397 sh = std::get<0>(fh.at(walk));
398 st = std::get<0>(ft.at(walk));
402 if (!sh.compare(
"H") || !sh.compare(
"T"))
405 hInd = std::get<2>(fh.at(walk));
408 const art::Ptr<recob::Track> th2( ftListHandle, hInd );
409 compTrack.insert(compTrack.begin(),th2);
410 HT2.insert(HT2.begin(),sh+
"H");
413 if ((!st.compare(
"H") || !st.compare(
"T")))
415 tInd = std::get<2>(ft.at(walk));
417 const art::Ptr<recob::Track> th2( ftListHandle, tInd );
418 compTrack.insert(compTrack.begin(),th2);
419 HT2.insert(HT2.begin(),st+
"T");
421 if (hInd!=-12) walk = hInd;
422 if (tInd!=-12) walk = tInd;
423 if (!sh.compare(
"NA") && !st.compare(
"NA"))
426 trackStatus.at(walk) =
"Done";
431 if (compTrack.size())
435 for (
auto iit = compTrack.begin(); iit!=compTrack.end();++iit)
438 for (
auto jit = iit+1; jit!=compTrack.end();++jit)
444 compTrack.erase(jit);
445 HT2.erase(HT2.begin()+cjit);
451 fTrackComposite.push_back(compTrack);
464 FirstStitch(fTrackComposite.end()-1, fTrackVec.end());
481 int osciit(-12), oscjit(-12);
482 std::vector < art::PtrVector<recob::Track> >::iterator osiComposite, osjComposite;
483 art::PtrVector < recob::Track >::iterator osiAgg, osjAgg;
488 for (
auto iit = fTrackComposite.begin(); iit!=fTrackComposite.end()&&!match; ++iit)
492 for (
auto jit = iit+1; jit!=fTrackComposite.end()&&!match; ++jit)
495 for (
auto iiit = iit->begin(); iiit!=iit->end()&&!match; ++iiit)
497 for (
auto jjit = jit->begin(); jjit!=jit->end()&&!match; ++jjit)
518 if (!match)
return match;
525 (*osiComposite).erase(osiAgg);
535 std::vector< std::vector<std::string> >::iterator siit(fHT.begin()+osciit-1);
536 std::vector< std::vector<std::string> >::iterator sjit(fHT.begin()+oscjit-1);
537 size_t itdiff(osiComposite->end()-osiComposite->begin());
538 if (osjAgg == osjComposite->begin())
545 (*osjComposite).insert(osjComposite->begin(),osiComposite->begin(),osiComposite->begin()+itdiff);
548 (*sjit).insert(sjit->begin(),siit->begin(),siit->begin()+itdiff);
551 else if (osjAgg == (osjComposite->end()-1))
554 (*osjComposite).insert(osjComposite->end(),osiComposite->begin(),osiComposite->begin()+itdiff);
555 (*sjit).insert(sjit->end(),siit->begin(),siit->begin()+itdiff);
560 fTrackVec.erase(fTrackVec.begin()+oscjit-1);
563 FirstStitch(osjComposite,fTrackVec.begin()+oscjit-1);
566 fTrackVec.erase(fTrackVec.begin()+osciit-1);
568 fTrackComposite.erase(osiComposite);
570 fHT.erase(fHT.begin()+osciit-1);
StitchAlg(fhicl::ParameterSet const &pset)
art::Handle< std::vector< recob::Track > > ftListHandle
void FindHeadsAndTails(const art::Event &e, const std::string &t)
bool CommonComponentStitch()
Vector_t VertexDirection() const
void FirstStitch(const std::vector< art::PtrVector< recob::Track >>::iterator itvvArg, const std::vector< recob::Track >::iterator itvArg)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
A trajectory in space reconstructed from hits.
Point_t const & Vertex() const
void reconfigure(fhicl::ParameterSet const &pset)
Vector_t EndDirection() const
Point_t const & End() const
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track: