20 #include "cetlib_except/exception.h" 29 #include "Fit/Fitter.h" 30 #include "Math/Functor.h" 33 #include "Geant4/G4ThreeVector.hh" 36 #include "nutools/MagneticField/MagneticField.h" 103 std::vector<int> &hsi,
106 float &curvature_init,
116 std::vector<int> &hsi,
119 std::vector<float> &trackparatend,
123 std::set<int> &unused_hits);
127 std::vector<int> &hsi,
129 std::set<int> &unused_hits,
135 std::vector<int> &hsi,
138 std::set<int> &unused_hits,
142 size_t ifob(
size_t ihit,
size_t nhits,
bool isForwards);
147 float &xc,
float &yc);
149 float capprox2(
float y0,
float z0,
float y1,
float z1,
float y2,
float z2);
157 bool vh_hitmatch(TVector3 &hpvec,
int ihit,
vechit_t &vechit,
const std::vector<gar::rec::Hit> &hits, std::vector<int> &hsi);
159 void fitline(std::vector<double> &
x, std::vector<double> &
y,
double &lambda,
double &intercept);
173 if (fPatRecLookBack1 == fPatRecLookBack2)
175 throw cet::exception(
"tracker1_module: PatRecLookBack1 and PatRecLookBack2 are the same");
206 consumes< std::vector<gar::rec::Hit> >(itag);
207 produces< std::vector<gar::rec::Track> >();
208 produces< art::Assns<gar::rec::Hit, gar::rec::Track> >();
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);
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;
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;
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;
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);
669 float &xc,
float &yc)
680 float det = x3*y2-x2*y3;
681 if (TMath::Abs(det)<1
e-10){
685 float u = 0.5* (x2*(x2-
x3)+y2*(y2-y3))/det;
686 float x0 = x3*0.5-y3*u;
687 float y0 = y3*0.5+x3*u;
688 float c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
700 float A = y1*(z2 - z0) - z1*(y2 - y0) + (y2*z0 - z2*y0);
702 float B = -( (y1*y1 + z1*z1)*(z2 - z0)
703 -z1*( (y2*y2 + z2*z2) - (y0*y0 + z0*z0) )
704 + ( (y2*y2 + z2*z2)*z0 - z2*(y0*y0 + z0*z0) ) );
706 float C = (y1*y1 + z1*z1)*(y2 - y0)
707 -y1*( (y2*y2 + z2*z2) - (y0*y0 + z0*z0))
708 + ( (y2*y2 + z2*z2)*y0 - y2*(y0*y0 + z0*z0) );
710 float D = - ( (y1*y1 + z1*z1)*(y2*z0 - z2*y0)
711 - y1*( (y2*y2 + z2*z2)*z0 - z2*(y0*y0 + z0*z0) )
712 + z1*( (y2*y2 + z2*z2)*y0 - y2*(y0*y0 + z0*z0) ));
714 if (TMath::Abs(A) < 1
E-10)
717 float yc = -B/(2.0*
A);
718 float zc = -C/(2.0*
A);
719 float rs = yc*yc + zc*zc -D/
A;
723 std::cout <<
" In capprox2, A, B, C, D, rs: " << A <<
" " << B <<
" " << C <<
" " << D <<
" " << rs <<
std::endl;
726 {
throw cet::exception(
"tracker1capprox2: negative input to sqrt"); }
727 float curv = 1.0/TMath::Sqrt(rs);
734 std::vector<int> &hsi,
736 std::set<int> &unused_hits,
755 std::vector<std::vector<int> > hlf;
756 std::vector<std::vector<int> > hlb;
764 auto const& hits = *hitHandle;
770 for (
size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
772 for (
int i=0; i<3; ++i)
774 float c = hits[hsi[hitlist[itrack][ihit]]].Position()[i];
801 for (
size_t i=0; i<6; ++i)
804 TVector3 poshc(hits[hsi[hitlist[itrack][ihex[i]]]].Position());
805 for (
size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
807 TVector3 hp(hits[hsi[hitlist[itrack][ihit]]].Position());
808 sumd += (poshc - hp).Mag();
822 std::vector<int> hls;
823 hls.push_back(hitlist[itrack][ihex[imax]]);
824 TVector3 lpos(hits[hsi[hls[0]]].Position());
825 for (
size_t inh=1;inh<hitlist[itrack].size();++inh)
829 for (
size_t jh=0;jh<hitlist[itrack].size();++jh)
832 for (
size_t kh=0;kh<hls.size();++kh)
834 if (hls[kh] == hitlist[itrack][jh])
841 TVector3 hpos(hits[hsi[hitlist[itrack][jh]]].Position());
842 float d=(hpos-lpos).Mag();
858 hls.push_back(hitlist[itrack][jmin]);
864 std::cout <<
"Itrack: " << itrack <<
std::endl;
865 for (
size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
867 printf(
"Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
868 hitlist[itrack][ihit],
869 hits[hsi[hitlist[itrack][ihit]]].Position()[0],
870 hits[hsi[hitlist[itrack][ihit]]].Position()[1],
871 hits[hsi[hitlist[itrack][ihit]]].Position()[2],
873 hits[hsi[hls[ihit]]].Position()[0],
874 hits[hsi[hls[ihit]]].Position()[1],
875 hits[hsi[hls[ihit]]].Position()[2]);
883 hls.push_back(hlf[itrack].back());
884 TVector3 lpos2(hits[hsi[hls[0]]].Position());
885 for (
size_t inh=1;inh<hitlist[itrack].size();++inh)
889 for (
size_t jh=0;jh<hitlist[itrack].size();++jh)
892 for (
size_t kh=0;kh<hls.size();++kh)
894 if (hls[kh] == hitlist[itrack][jh])
901 TVector3 hpos(hits[hsi[hitlist[itrack][jh]]].Position());
902 float d=(hpos-lpos2).Mag();
918 hls.push_back(hitlist[itrack][jmin]);
924 std::cout <<
"Itrack: " << itrack <<
std::endl;
925 for (
size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
927 printf(
"Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
928 hitlist[itrack][ihit],
929 hits[hsi[hitlist[itrack][ihit]]].Position()[0],
930 hits[hsi[hitlist[itrack][ihit]]].Position()[1],
931 hits[hsi[hitlist[itrack][ihit]]].Position()[2],
933 hits[hsi[hls[ihit]]].Position()[0],
934 hits[hsi[hls[ihit]]].Position()[1],
935 hits[hsi[hls[ihit]]].Position()[2]);
944 std::sort(hlf[itrack].
begin(), hlf[itrack].
end(),
945 [&hsi](
int a,
int b ) {
return (hsi[a] > hsi[b]);});
947 std::sort(hlb[itrack].
begin(), hlb[itrack].
end(),
948 [&hsi](
int a,
int b ) {
return (hsi[a] < hsi[b]);});
951 std::vector<float> tparend(6);
953 float chisqforwards = 0;
954 float lengthforwards = 0;
955 int retcode =
KalmanFit(hitHandle,hlf,hsi,itrack,
true,tparend,chisqforwards,lengthforwards,covmatend,unused_hits);
956 if (retcode != 0)
return 1;
960 std::vector<float> tparbeg(6);
962 float chisqbackwards = 0;
963 float lengthbackwards = 0;
965 retcode =
KalmanFit(hitHandle,hlb,hsi,itrack,
false,tparbeg,chisqbackwards,lengthbackwards,covmatbeg,unused_hits);
966 if (retcode != 0)
return 1;
969 if (hitlist[itrack].
size()>unused_hits.size())
970 { nhits = hitlist[itrack].size()-unused_hits.size(); }
971 trackpar.setNHits(nhits);
1000 std::vector<int> &hsi,
1003 std::vector<float> &trackparatend,
1007 std::set<int> &unused_hits)
1012 auto const& hits = *hitHandle;
1013 size_t nhits = hitlist[itrack].size();
1016 for (
size_t i=0; i<5; ++i) trackparatend[i] = 0;
1017 for (
size_t i=0; i<25; ++i) covmat[i] = 0;
1022 float curvature_init=0.1;
1024 float lambda_init = 0;
1028 float x_other_end = 0;
1048 float xpos = xpos_init;
1053 P[0][0] = TMath::Sq(1);
1054 P[1][1] = TMath::Sq(1);
1055 P[2][2] = TMath::Sq(.5);
1056 P[3][3] = TMath::Sq(.5);
1057 P[4][4] = TMath::Sq(.5);
1059 TMatrixF PPred(5,5);
1081 parvec[0] = ypos_init;
1082 parvec[1] = zpos_init;
1083 parvec[2] = curvature_init;
1084 parvec[3] = phi_init;
1085 parvec[4] = lambda_init;
1086 TVectorF predstep(5);
1102 for (
int i=0;i<5;++i) I[i][i] = 1;
1104 for (
size_t ihit=1; ihit<nhits; ++ihit)
1107 size_t ihf =
ifob(ihit,nhits,isForwards);
1108 float xh = hits[hsi[hitlist[itrack][ihf]]].Position()[0];
1109 float yh = hits[hsi[hitlist[itrack][ihf]]].Position()[1];
1110 float zh = hits[hsi[hitlist[itrack][ihf]]].Position()[2];
1115 std::cout <<
"Adding a new hit: " << xh <<
" " << yh <<
" " << zh <<
std::endl;
1120 float curvature = parvec[2];
1121 float phi = parvec[3];
1122 float lambda = parvec[4];
1131 float slope = TMath::Tan(lambda);
1144 float dx = xh -
xpos;
1147 float dxnum = (slope/(
fHitResolYZ*
fHitResolYZ))*( (yh - parvec[0])*TMath::Sin(phi) + (zh - parvec[1])*TMath::Cos(phi) )
1150 if (dx == 0) dx = 1
E-3;
1161 F[0][3] = dx*slope*TMath::Cos(phi);
1162 F[0][4] = dx*TMath::Sin(phi)*(-1.0-slope*slope);
1166 F[1][3] = -dx*slope*TMath::Sin(phi);
1167 F[1][4] = dx*TMath::Cos(phi)*(-1.0-slope*slope);
1176 F[3][4] = dx*curvature*(-1.0-slope*slope);
1192 std::cout <<
"x: " << xpos <<
" dx: " << dx <<
std::endl;
1193 std::cout <<
" Parvec: y " << parvec[0] <<
" z " << parvec[1] <<
" c " << parvec[2] <<
" phi " << parvec[3] <<
" lambda " << parvec[4] <<
std::endl;
1197 predstep[0] += slope*dx*TMath::Sin(phi);
1198 predstep[1] += slope*dx*TMath::Cos(phi);
1199 predstep[3] += slope*dx*curvature;
1203 std::cout <<
" Predstep: y " << predstep[0] <<
" z " << predstep[1] <<
" c " << predstep[2] <<
" phi " << predstep[3] <<
" lambda " << predstep[4] <<
std::endl;
1210 std::cout <<
"PPred Matrix: " <<
std::endl;
1214 ytilde[0] = yh - predstep[0];
1215 ytilde[1] = zh - predstep[1];
1216 float ydistsq = ytilde.Norm2Sqr();
1217 if (ydistsq > roadsq)
1219 unused_hits.insert(ihf);
1222 chisquared += ytilde.Norm2Sqr()/TMath::Sq(
fHitResolYZ);
1225 std::cout <<
"ytilde (residuals): " <<
std::endl;
1245 std::cout <<
"Inverted S Matrix: " <<
std::endl;
1256 float yprev = parvec[0];
1257 float zprev = parvec[1];
1258 parvec = predstep + K*ytilde;
1263 length += TMath::Sqrt( dx*dx + TMath::Sq(parvec[0]-yprev) + TMath::Sq(parvec[1]-zprev) );
1266 for (
size_t i=0; i<5; ++i)
1268 trackparatend[i] = parvec[i];
1270 trackparatend[5] =
xpos;
1273 std::cout <<
"Track params at end (y, z, curv, phi, lambda) " << trackparatend[0] <<
" " << trackparatend[1] <<
" " <<
1274 trackparatend[2] <<
" " << trackparatend[3] <<
" " << trackparatend[4] <<
std::endl;
1289 for (
size_t i=0; i<5; ++i)
1291 for (
size_t j=0; j<5; ++j)
1293 covmat[icov] = P[i][j];
1327 std::vector<int> &hsi,
1330 float &curvature_init,
1340 auto const& hits = *hitHandle;
1341 size_t nhits = hitlist[itrack].size();
1344 size_t inthit_index = farhit_index/2;
1346 size_t firsthit =
ifob(0,nhits,isForwards);
1349 size_t inthit =
ifob(inthit_index,nhits,isForwards);
1350 size_t farhit =
ifob(farhit_index,nhits,isForwards);
1351 size_t lasthit =
ifob(nhits-1,nhits,isForwards);
1353 float trackbeg[3] = {hits[hsi[hitlist[itrack][firsthit]]].Position()[0],
1354 hits[hsi[hitlist[itrack][firsthit]]].Position()[1],
1355 hits[hsi[hitlist[itrack][firsthit]]].Position()[2]};
1357 float tp1[3] = {hits[hsi[hitlist[itrack][inthit]]].Position()[0],
1358 hits[hsi[hitlist[itrack][inthit]]].Position()[1],
1359 hits[hsi[hitlist[itrack][inthit]]].Position()[2]};
1361 float tp2[3] = {hits[hsi[hitlist[itrack][farhit]]].Position()[0],
1362 hits[hsi[hitlist[itrack][farhit]]].Position()[1],
1363 hits[hsi[hitlist[itrack][farhit]]].Position()[2]};
1367 std::cout <<
"Hit Dump in initial_trackpar_estimate: " <<
std::endl;
1368 for (
size_t i=0;i<nhits;++i)
1370 size_t ihf =
ifob(i,nhits,isForwards);
1371 std::cout << i <<
" : " <<
1372 hits[hsi[hitlist[itrack][ihf]]].Position()[0] <<
" " <<
1373 hits[hsi[hitlist[itrack][ihf]]].Position()[1] <<
" " <<
1374 hits[hsi[hitlist[itrack][ihf]]].Position()[2] <<
std::endl;
1379 std::cout <<
"isForwards: " << isForwards <<
std::endl;
1380 std::cout <<
"first hit: " << firsthit <<
", inter hit: " << inthit <<
" " <<
" far hit: " << farhit <<
std::endl;
1381 std::cout <<
"in the hit list: " << hsi[hitlist[itrack][firsthit]] <<
" " << hsi[hitlist[itrack][inthit]] <<
" " << hsi[hitlist[itrack][farhit]] <<
std::endl;
1382 std::cout <<
"First hit x, y, z: " << trackbeg[0] <<
" " << trackbeg[1] <<
" " << trackbeg[2] <<
std::endl;
1383 std::cout <<
"Inter hit x, y, z: " << tp1[0] <<
" " << tp1[1] <<
" " << tp1[2] <<
std::endl;
1384 std::cout <<
"Far hit x, y, z: " << tp2[0] <<
" " << tp2[1] <<
" " << tp2[2] <<
std::endl;
1390 x_other_end = hits[hsi[hitlist[itrack][lasthit]]].Position()[0];
1395 curvature_init =
capprox(trackbeg[1],trackbeg[2],tp1[1],tp1[2],tp2[1],tp2[2],ycc,zcc);
1400 phi_init = TMath::ATan2( trackbeg[2] - zcc, ycc - trackbeg[1] );
1401 float phi2 = phi_init;
1402 if (curvature_init<0) phi_init += TMath::Pi();
1403 float radius_init = 10000;
1404 if (curvature_init != 0) radius_init = 1.0/curvature_init;
1406 float dx1 = tp2[0] -
xpos;
1409 float dphi2 = TMath::ATan2(tp2[2]-zcc,ycc-tp2[1])-phi2;
1410 if (dphi2 > TMath::Pi()) dphi2 -= 2.0*TMath::Pi();
1411 if (dphi2 < -TMath::Pi()) dphi2 += 2.0*TMath::Pi();
1412 lambda_init = TMath::ATan(1.0/((radius_init/dx1)*dphi2));
1423 std::cout <<
"phi calc: dz, dy " << tp2[2]-trackbeg[2] <<
" " << tp2[1]-trackbeg[1] <<
std::endl;
1424 std::cout <<
"initial curvature, phi, lambda: " << curvature_init <<
" " << phi_init <<
" " << lambda_init <<
std::endl;
1436 std::vector<int> &hsi,
1439 std::set<int> &unused_hits,
1443 auto const& hits = *hitHandle;
1444 size_t nhits = hitlist[itrack].size();
1448 float curvature_init=0.1;
1450 float lambda_init = 0;
1454 float x_other_end=0;
1471 float tpi[5] = {ypos_init, zpos_init, curvature_init, phi_init, lambda_init};
1472 float covmat[25] = {0};
1476 auto chi2Function = [&](
const Double_t *par) {
1480 float tpl[5] = { (
float) par[0], (
float) par[1], (
float) par[2], (
float) par[3], (
float) par[4] };
1485 TrackPar tpar(0,0,nhits,xpos_init,tpl,covmat,0,xpos_init,tpl,covmat,0,0);
1488 for (
size_t ihit=0; ihit<nhits; ++ihit)
1490 TVector3 hitpos(hits[hsi[hitlist[itrack][ihit]]].Position()[0],
1491 hits[hsi[hitlist[itrack][ihit]]].Position()[1],
1492 hits[hsi[hitlist[itrack][ihit]]].Position()[2]);
1493 TVector3 helixpos = tpar.getPosAtX(hitpos.X(),isForwards);
1495 c2sum += (hitpos-helixpos).Mag2();
1497 double dc2sum = c2sum;
1503 ROOT::Math::Functor fcn(chi2Function,5);
1504 ROOT::Fit::Fitter fitter;
1507 for (
size_t i=0; i<5; ++i) pStart[i] = tpi[i];
1508 fitter.SetFCN(fcn, pStart);
1509 fitter.Config().ParSettings(0).SetName(
"y0");
1510 fitter.Config().ParSettings(1).SetName(
"z0");
1511 fitter.Config().ParSettings(2).SetName(
"curvature");
1512 fitter.Config().ParSettings(3).SetName(
"phi0");
1513 fitter.Config().ParSettings(4).SetName(
"lambda");
1516 bool ok = fitter.FitFCN();
1518 LOG_WARNING(
"gar::rec::tracker1") <<
"Helix Fit failed";
1522 const ROOT::Fit::FitResult &
result = fitter.Result();
1524 float fity0 = result.Value(0);
1525 float fitz0 = result.Value(1);
1526 float fitcurvature = result.Value(2);
1527 float fitphi0 = result.Value(3);
1528 float fitlambda = result.Value(4);
1529 float tpfit[5] = {fity0,fitz0,fitcurvature,fitphi0,fitlambda};
1530 float chisqmin = result.MinFcnValue();
1532 float stmp = TMath::Tan(fitlambda);
1543 float tracklength = TMath::Abs(xpos_init - x_other_end) * TMath::Sqrt( 1.0 + stmp*stmp );
1544 float covmatfit[25];
1545 for (
size_t i=0; i<5; ++i)
1547 for (
size_t j=0; j<5; ++j)
1549 covmatfit[5*i + j] = result.CovMatrix(i,j);
1553 trackpar.setNHits(nhits);
1565 trackpar.
setXEnd(x_other_end);
1566 TVector3 xyzend = trackpar.getPosAtX(x_other_end,
true);
1567 float yend = xyzend[1];
1568 float zend = xyzend[2];
1569 float tp_other_end[5] = {yend,zend,fitcurvature,fitphi0,fitlambda};
1576 trackpar.
setXBeg(x_other_end);
1577 TVector3 xyzend = trackpar.getPosAtX(x_other_end,
true);
1578 float yend = xyzend[1];
1579 float zend = xyzend[2];
1580 float tp_other_end[5] = {yend,zend,fitcurvature,fitphi0,fitlambda};
1592 bool retval =
false;
1595 for (
size_t iht=0; iht<vechit.
hitindex.size(); ++iht)
1597 TVector3 ht(hits[hsi[vechit.
hitindex[iht]]].Position());
1598 float d = (hpvec - ht).Mag();
1600 dist = TMath::Min(dist,d);
1605 dist = ((hpvec - vechit.
pos).Cross(vechit.
dir)).Mag();
1612 std::vector<TVector3> hplist;
1613 for (
size_t i=0; i< vechit.
hitindex.size(); ++i)
1615 hplist.emplace_back(hits[hsi[vechit.
hitindex[i]]].Position());
1617 hplist.push_back(hpvec);
1630 std::vector<double>
x;
1631 std::vector<double>
y;
1632 std::vector<double>
z;
1633 for (
size_t i=0; i<hlist.size();++i)
1635 x.push_back(hlist[i].
X());
1636 y.push_back(hlist[i].
Y());
1637 z.push_back(hlist[i].
Z());
1641 double intercept_yx=0;
1642 double intercept_zx=0;
1646 double intercept_yz=0;
1647 double intercept_xz=0;
1651 double intercept_xy=0;
1652 double intercept_zy=0;
1654 fitline(x,y,slope_xy,intercept_xy);
1655 fitline(x,z,slope_xz,intercept_xz);
1657 fitline(y,z,slope_yz,intercept_yz);
1658 fitline(y,x,slope_yx,intercept_yx);
1660 fitline(z,y,slope_zy,intercept_zy);
1661 fitline(z,x,slope_zx,intercept_zx);
1666 double slopesumx = TMath::Abs(slope_xy) + TMath::Abs(slope_xz);
1667 double slopesumy = TMath::Abs(slope_yz) + TMath::Abs(slope_yx);
1668 double slopesumz = TMath::Abs(slope_zx) + TMath::Abs(slope_zy);
1670 if (slopesumx < slopesumy && slopesumx < slopesumz)
1672 dir.SetXYZ(1.0,slope_xy,slope_xz);
1674 for (
size_t i=0; i<x.size(); ++i)
1679 pos.SetXYZ(avgx, avgx*slope_xy + intercept_xy, avgx*slope_xz + intercept_xz);
1681 else if (slopesumy < slopesumx && slopesumy < slopesumz)
1683 dir.SetXYZ(slope_yx,1.0,slope_yz);
1685 for (
size_t i=0; i<y.size(); ++i)
1690 pos.SetXYZ(avgy*slope_yx + intercept_yx, avgy, avgy*slope_yz + intercept_yz);
1694 dir.SetXYZ(slope_zx,slope_zy,1.0);
1696 for (
size_t i=0; i<z.size(); ++i)
1701 pos.SetXYZ(avgz*slope_zx + intercept_zx, avgz*slope_zy + intercept_zy, avgz);
1703 dir *= 1.0/dir.Mag();
1712 size_t n = x.size();
1715 throw cet::exception(
"tracker1: too few hits to fit a line in linefit");
1722 for (
size_t i=0; i<
n; ++i)
1726 sumxx += TMath::Sq(x[i]);
1729 double denom = (n*sumxx) - TMath::Sq(sumx);
1737 slope = (n*sumxy - sumx*sumy)/denom;
1738 intercept = (sumxx*sumy - sumx*sumxy)/denom;
1744 for (
size_t ivh=0; ivh<cluster.size(); ++ivh)
1784 TVector3 vhdp(vh.
dir);
1786 float norm = vhdp.Mag();
1787 if (norm > 0) vhdp *= (1.0/
norm);
1791 TVector3 vhcp(cluster[ivh].dir);
1794 if (norm > 0) vhcp *= (1.0/
norm);
1796 float relsign = 1.0;
1797 if (vhdp.Dot(vhcp) < 0) relsign = -1;
1799 TVector3 dcent = vh.
pos-cluster[ivh].pos;
1802 TVector3 avgdir1 = 0.5*(vhdp + relsign*vhcp);
1803 float amag = avgdir1.Mag();
1804 if (amag != 0) avgdir1 *= 1.0/amag;
1805 float eta = (dcent.Cross(avgdir1)).Mag();
1816 float vhpd = TMath::Sqrt( TMath::Sq(vh.
dir.Y()) + TMath::Sq(vh.
dir.Z()) );
1817 float vhxd = TMath::Abs( vh.
dir.X() );
1818 float vhlambda = TMath::Pi()/2.0;
1819 if (vhpd >0) vhlambda = TMath::ATan(vhxd/vhpd);
1821 float cvhpd = TMath::Sqrt( TMath::Sq(cluster[ivh].dir.Y()) + TMath::Sq(cluster[ivh].dir.Z()) );
1822 float cvhxd = TMath::Abs( cluster[ivh].dir.X() );
1823 float cvhlambda = TMath::Pi()/2.0;
1824 if (cvhpd >0) cvhlambda = TMath::ATan(cvhxd/cvhpd);
1832 if ( vh.
dir.Dot(cluster[ivh].dir) * vh.
dir.X() * cluster[ivh].dir.X() < 0 &&
1833 TMath::Abs(vh.
dir.X()) > 0.01 && TMath::Abs(cluster[ivh].dir.X()) > 0.01)
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void setLengthForwards(const float lengthforwards)
float fKalLambdaStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for lambda
size_t fPatRecLookBack1
n hits to look backwards to make a linear extrapolation
float fVecHitMatchPos
matching condition for pairs of vector hits – 3D distance (cm)
void fitlinesdir(std::vector< TVector3 > &hlist, TVector3 &pos, TVector3 &dir)
void setCovMatBeg(const float *covmatbeg)
std::string fSecondPassFitType
helix or Kalman – which fitter to call for second-pass tracks
float fKalCurvStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for curvature ...
const float * getTrackParametersEnd() const
bool vh_hitmatch(TVector3 &hpvec, int ihit, vechit_t &vechit, const std::vector< gar::rec::Hit > &hits, std::vector< int > &hsi)
float fVecHitMatchPEX
matching condition for pairs of vector hits – miss distance (cm)
std::pair< float, std::string > P
void setLengthBackwards(const float lengthbackwards)
Cluster finding and building.
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 capprox2(float y0, float z0, float y1, float z1, float y2, float z2)
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.
std::string fSortOrder
switch to tell what way to sort hits before presenting them to the fitter
void setTrackParametersBegin(const float *tparbeg)
int fTrackPass
which pass of the tracking to save as the tracks in the event
std::vector< size_t > hitindex
#define DEFINE_ART_MODULE(klass)
tracker1(fhicl::ParameterSet const &p)
T get(std::string const &key) const
void setXEnd(const float xend)
void setTrackParametersEnd(const float *tparend)
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool vhclusmatch(std::vector< vechit_t > &cluster, vechit_t &vh)
void setChisqBackwards(const float chisqbackwards)
unsigned int fVecHitMinHits
minimum number of hits on a vector hit for it to be considered
float fVecHitRoad
max dist from a vector hit to a hit to assign it. for patrec alg 2. in cm.
float fVecHitMatchCos
matching condition for pairs of vector hits cos angle between directions
int KalmanFit(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::vector< float > &trackparatend, float &chisquared, float &length, float *covmat, std::set< int > &unused_hits)
float fRoadYZinFit
cut in cm for dropping hits from tracks in fit
float capprox(float x1, float y1, float x2, float y2, float x3, float y3, float &xc, float &yc)
initial guess of curvature calculator – from ALICE. Also returns circle center
auto norm(Vector const &v)
Return norm of the specified vector.
float fHitResolX
resolution in cm of a hit in X (drift direction)
int initial_trackpar_estimate(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end)
General GArSoft Utilities.
float fVecHitMatchLambda
matching condition for pairs of vector hits – dLambda (radians)
void setCovMatEnd(const float *covmatend)
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
void setXBeg(const float xbeg)
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
unsigned int fInitialTPNHits
number of hits to use for initial trackpar estimate, if present
void produce(art::Event &e) override
float fMaxVecHitLen
maximum vector hit length in patrec alg 2, in cm
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
const float * getTrackParametersBegin() const
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)
void setChisqForwards(const float chisqforwards)
float fHitResolYZinFit
Hit resolution parameter to use in fit.
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)
tracker1 & operator=(tracker1 const &)=delete
size_t fPatRecAlg
1: x-sorted patrec. 2: vector-hit patrec
float fVecHitMatchEta
matching condition for pairs of vector hits – eta match (cm)
LArSoft geometry interface.
art framework interface to geometry description
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
void setTime(const double time)
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 ...
void fitline(std::vector< double > &x, std::vector< double > &y, double &lambda, double &intercept)
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
size_t ifob(size_t ihit, size_t nhits, bool isForwards)
float fKalPhiStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for phi