213 std::unique_ptr< std::vector<gar::rec::Track> > trkCol(
new std::vector<gar::rec::Track>);
214 std::unique_ptr< art::Assns<gar::rec::Hit,gar::rec::Track> > hitTrkAssns(new ::art::Assns<gar::rec::Hit,gar::rec::Track>);
217 auto const& hits = *hitHandle;
223 G4ThreeVector zerovec(0,0,0);
224 G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
227 double xtpccent = geo->TPCXCent();
228 double ytpccent = geo->TPCYCent();
229 double ztpccent = geo->TPCZCent();
230 TVector3 tpccent(xtpccent,ytpccent,ztpccent);
231 TVector3 xhat(1,0,0);
234 std::vector<float> hitx;
235 for (
size_t i=0; i<hits.size(); ++i)
237 hitx.push_back(hits[i].Position()[0]);
239 std::vector<int> hsi(hitx.size());
240 TMath::Sort((
int) hitx.size(),hitx.data(),hsi.data());
247 std::vector< std::vector<int> > hitlist;
259 std::vector< std::vector<int> > hitlistf;
260 std::vector<int> trackf(hits.size());
261 for (
size_t ihit=0; ihit<hits.size(); ++ihit)
263 const float *hpos = hits[hsi[ihit]].Position();
264 TVector3 hpvec(hpos);
265 if ( ((hpos - tpccent).Cross(xhat)).Mag() >
fHitRCut )
continue;
268 float bestsignifs = -1;
270 for (
size_t itcand = 0; itcand < hitlistf.size(); ++itcand)
273 size_t hlsiz = hitlistf[itcand].size();
276 TVector3 pt1( hits[hsi[hitlistf[itcand][hlsiz-
fPatRecLookBack1]]].Position() );
277 TVector3 pt2( hits[hsi[hitlistf[itcand][hlsiz-
fPatRecLookBack2]]].Position() );
278 TVector3 uv = pt1-pt2;
280 signifs = ((hpvec-pt1).Cross(uv)).Mag2()/resolSq;
284 const float *cpos = hits[hsi[hitlistf[itcand].back()]].Position();
285 signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
286 TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
288 if (bestsignifs < 0 || signifs < bestsignifs)
290 bestsignifs = signifs;
294 if (ibest == -1 || bestsignifs > roadsq)
296 ibest = hitlistf.size();
297 std::vector<int> vtmp;
298 hitlistf.push_back(vtmp);
300 hitlistf[ibest].push_back(ihit);
301 trackf[ihit] = ibest;
304 std::vector< std::vector<int> > hitlistb;
305 std::vector<int> trackb(hits.size());
306 for (
int ihit=hits.size()-1; ihit >= 0; --ihit)
308 const float *hpos = hits[hsi[ihit]].Position();
309 TVector3 hpvec(hpos);
310 if ( ((hpos - tpccent).Cross(xhat)).Mag() >
fHitRCut )
continue;
313 float bestsignifs = -1;
315 for (
size_t itcand = 0; itcand < hitlistb.size(); ++itcand)
318 size_t hlsiz = hitlistb[itcand].size();
321 TVector3 pt1( hits[hsi[hitlistb[itcand][hlsiz-
fPatRecLookBack1]]].Position() );
322 TVector3 pt2( hits[hsi[hitlistb[itcand][hlsiz-
fPatRecLookBack2]]].Position() );
323 TVector3 uv = pt1-pt2;
325 signifs = ((hpvec-pt1).Cross(uv)).Mag2()/resolSq;
329 const float *cpos = hits[hsi[hitlistb[itcand].back()]].Position();
330 signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
331 TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
334 if (bestsignifs < 0 || signifs < bestsignifs)
336 bestsignifs = signifs;
340 if (ibest == -1 || bestsignifs > roadsq)
342 ibest = hitlistb.size();
343 std::vector<int> vtmp;
344 hitlistb.push_back(vtmp);
346 hitlistb[ibest].push_back(ihit);
347 trackb[ihit] = ibest;
352 for (
size_t itrack=0; itrack<hitlistf.size(); ++itrack)
355 for (
size_t ihit=0; ihit<hitlistf[itrack].size(); ++ihit)
357 int ihif = hitlistf[itrack][ihit];
358 if (ihit == 0 || (trackb[ihif] != itrackl))
360 std::vector<int> vtmp;
361 hitlist.push_back(vtmp);
362 itrackl = trackb[ihif];
364 hitlist.back().push_back(ihif);
376 std::vector<vechit_t> vechits;
377 std::vector<vechit_t> vhtmp;
379 for (
size_t ihit=0; ihit<hits.size(); ++ihit)
381 const float *hpos = hits[hsi[ihit]].Position();
382 TVector3 hpvec(hpos);
383 if ( ((hpos - tpccent).Cross(xhat)).Mag() >
fHitRCut )
continue;
387 for (
size_t ivh=0; ivh<vhtmp.size(); ++ivh)
390 if (
vh_hitmatch(hpvec, ihit, vhtmp[ivh], hits, hsi ))
399 vh.pos.SetXYZ(hpos[0],hpos[1],hpos[2]);
400 vh.dir.SetXYZ(0,0,0);
401 vh.hitindex.push_back(ihit);
409 for (
size_t ivh=0; ivh<vhtmp.size(); ++ivh)
413 vechits.push_back(vhtmp[ivh]);
422 std::vector< std::vector< vechit_t > > vhclusters;
424 for (
size_t ivh = 0; ivh< vechits.size(); ++ ivh)
429 std::vector<size_t> clusmatchlist;
430 for (
size_t iclus=0; iclus<vhclusters.size(); ++iclus)
434 clusmatchlist.push_back(iclus);
437 if (clusmatchlist.size() == 0)
439 std::vector<vechit_t> newclus;
440 newclus.push_back(vechits[ivh]);
441 vhclusters.push_back(newclus);
443 else if (clusmatchlist.size() == 1)
445 vhclusters[clusmatchlist[0]].push_back(vechits[ivh]);
449 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
451 for (
size_t ivh=0; ivh<vhclusters[clusmatchlist[icm]].size(); ++ivh)
453 vhclusters[clusmatchlist[0]].push_back(vhclusters[clusmatchlist[icm]][ivh]);
457 for (
size_t icm=1; icm<clusmatchlist.size(); ++icm)
459 vhclusters.erase(vhclusters.begin() + (clusmatchlist[icm]-icm+1));
467 for (
size_t iclus=0; iclus < vhclusters.size(); ++iclus)
469 std::vector<int> vtmp;
470 hitlist.push_back(vtmp);
471 for (
size_t ivh=0; ivh < vhclusters[iclus].size(); ++ ivh)
473 for (
size_t ihit=0; ihit < vhclusters[iclus][ivh].hitindex.size(); ++ihit)
475 hitlist.back().push_back(vhclusters[iclus][ivh].hitindex[ihit]);
481 std::sort(hitlist[iclus].
begin(), hitlist[iclus].
end(),
482 [&hsi](
int a,
int b ) {
return (hsi[a] > hsi[b]);});
491 size_t ntracks = hitlist.size();
495 std::vector<TrackPar> firstpass_tracks;
496 std::vector<int> firstpass_tid;
497 std::vector<TrackPar> secondpass_tracks;
498 std::vector<int> secondpass_tid;
503 for (
size_t itrack=0;itrack<
ntracks;++itrack)
507 std::cout <<
"Trkdump: " << ntracktmp <<
std::endl;
510 std::vector<int> whichtrack(hits.size(),-1);
512 for (
size_t itrack=0; itrack<
ntracks; ++itrack)
514 size_t nhits = hitlist[itrack].size();
517 for (
size_t ihit=0; ihit<nhits; ++ihit)
519 whichtrack[hitlist[itrack][ihit]] = itrack;
524 std::cout <<
"Starting a new Pass1 track: " << itrack <<
" Number of hits: " << nhits <<
std::endl;
527 TrackPar trackparams;
528 std::set<int> unused_hits;
533 retcode =
FitHelix(hitHandle,hitlist,hsi,itrack,
true,unused_hits,trackparams);
537 retcode =
KalmanFitBothWays(hitHandle,hitlist,hsi,itrack,unused_hits,trackparams);
543 if (retcode != 0)
continue;
545 firstpass_tracks.push_back(trackparams);
546 firstpass_tid.push_back(itrack);
550 std::cout <<
"Trkdump: " << itrack <<
std::endl;
551 std::cout <<
"Trkdump: " << trackparams.getTrackParametersBegin()[5] <<
std::endl;
552 for (
int i=0; i<5;++i) std::cout <<
"Trkdump: " << trackparams.getTrackParametersBegin()[i] <<
std::endl;
553 std::cout <<
"Trkdump: " << trackparams.getTrackParametersEnd()[5] <<
std::endl;
554 for (
int i=0; i<5;++i) std::cout <<
"Trkdump: " << trackparams.getTrackParametersEnd()[i] <<
std::endl;
555 std::cout <<
"Trkdump: " << nhits <<
std::endl;
556 for (
size_t ihit=0;ihit<nhits;++ihit)
558 std::cout <<
"Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[0] <<
std::endl;
559 std::cout <<
"Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[1] <<
std::endl;
560 std::cout <<
"Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[2] <<
std::endl;
570 std::vector< std::vector<int> > hitlist2(firstpass_tracks.size());
571 if (firstpass_tracks.size() > 0 &&
fTrackPass > 1)
573 for (
size_t ihit=0; ihit< hits.size(); ++ihit)
575 if (whichtrack[ihit] < 0)
continue;
576 const float *hpos = hits[hsi[ihit]].Position();
579 for (
size_t itrack=0; itrack<firstpass_tracks.size(); ++itrack)
581 float dist = firstpass_tracks[itrack].DistXYZ(hpos);
582 if (itrack == 0 || dist < mindist)
588 hitlist2[ibest].push_back(ihit);
591 size_t ntracks2 = hitlist2.size();
592 for (
size_t itrack=0; itrack<ntracks2; ++itrack)
594 size_t nhits = hitlist2[itrack].size();
599 std::cout <<
"Starting a new Pass2 track: " << itrack <<
" Number of hits: " << nhits <<
std::endl;
602 TrackPar trackparams;
603 std::set<int> unused_hits;
608 retcode =
FitHelix(hitHandle,hitlist2,hsi,itrack,
true,unused_hits,trackparams);
612 retcode =
KalmanFitBothWays(hitHandle,hitlist2,hsi,itrack,unused_hits,trackparams);
618 if (retcode != 0)
continue;
620 secondpass_tracks.push_back(trackparams);
621 secondpass_tid.push_back(itrack);
632 for (
size_t itrack=0; itrack<firstpass_tracks.size(); ++itrack)
634 trkCol->push_back(firstpass_tracks[itrack].CreateTrack());
635 auto const trackpointer = trackPtrMaker(itrack);
636 for (
size_t ihit=0; ihit<hitlist[firstpass_tid[itrack]].size(); ++ ihit)
638 auto const hitpointer = hitPtrMaker(hsi[hitlist[firstpass_tid[itrack]][ihit]]);
639 hitTrkAssns->addSingle(hitpointer,trackpointer);
645 for (
size_t itrack=0; itrack<secondpass_tracks.size(); ++itrack)
647 trkCol->push_back(secondpass_tracks[itrack].CreateTrack());
648 auto const trackpointer = trackPtrMaker(itrack);
649 for (
size_t ihit=0; ihit<hitlist2[secondpass_tid[itrack]].size(); ++ ihit)
651 auto const hitpointer = hitPtrMaker(hsi[hitlist2[secondpass_tid[itrack]][ihit]]);
652 hitTrkAssns->addSingle(hitpointer,trackpointer);
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
size_t fPatRecLookBack1
n hits to look backwards to make a linear extrapolation
bool vh_hitmatch(TVector3 &hpvec, int ihit, vechit_t &vechit, const std::vector< gar::rec::Hit > &hits, std::vector< int > &hsi)
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
unsigned int fMinNumHits
minimum number of hits to define a track
std::string fFirstPassFitType
helix or Kalman – which fitter to call for first-pass tracks
float fHitRCut
only take hits within rcut of the center of the detector
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
int fTrackPass
which pass of the tracking to save as the tracks in the event
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool vhclusmatch(std::vector< vechit_t > &cluster, vechit_t &vh)
unsigned int fVecHitMinHits
minimum number of hits on a vector hit for it to be considered
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
int fDumpTracks
0: do not print out tracks, 1: print out tracks
float fSigmaRoad
how many sigma away from a track a hit can be and still add it during patrec
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
int FitHelix(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::set< int > &unused_hits, TrackPar &trackpar)
int KalmanFitBothWays(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, std::set< int > &unused_hits, TrackPar &trackpar)
size_t fPatRecAlg
1: x-sorted patrec. 2: vector-hit patrec
LArSoft geometry interface.
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
std::string fHitLabel
label of module creating hits
size_t fPatRecLookBack2
extrapolate from lookback1 to lookback2 and see how close the new hit is to the line ...
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)