51 if(tj.AlgMod[
kKilled])
continue;
62 std::vector<int> temp;
63 for(
auto& vx3 : tjs.
vtx3) {
64 if(vx3.ID == 0)
continue;
65 if(vx3.TPCID != tpcid)
continue;
68 temp.push_back(vx3.ID);
70 if(temp.empty())
return;
73 std::vector<int> masterlist;
74 for(
auto vx3id : temp) {
75 auto& vx3 = tjs.
vtx3[vx3id - 1];
78 for(
auto tjid : tjlist) {
80 auto& tj = tjs.
allTraj[tjid - 1];
81 if(tj.ParentID != 0) {
85 if(std::find(masterlist.begin(), masterlist.end(), tjid) == masterlist.end()) masterlist.push_back(tjid);
90 myprt<<
"DTP: masterlist Tjs";
91 for(
auto tjid : masterlist) myprt<<
" "<<tjid;
95 std::vector<SortEntry> sortVec(temp.size());
96 for(
unsigned short indx = 0; indx < temp.size(); ++indx) {
97 auto& vx3 = tjs.
vtx3[temp[indx] - 1];
98 sortVec[indx].index = indx;
99 sortVec[indx].val = vx3.Score;
101 if(sortVec.size() > 1) std::sort(sortVec.begin(), sortVec.end(),
valDecreasing);
104 for(
unsigned short indx = 0; indx < temp.size(); ++indx) vlist[indx] = temp[sortVec[indx].
index];
108 auto& vx3 = tjs.
vtx3[vlist[0] - 1];
110 auto neutrinoPFP =
CreatePFP(tjs, tpcid);
114 neutrinoPFP.XYZ[1][0] = vx3.X;
115 neutrinoPFP.XYZ[1][1] = vx3.Y;
116 neutrinoPFP.XYZ[1][2] = vx3.Z;
117 neutrinoPFP.XYZ[0] = neutrinoPFP.XYZ[1];
118 neutrinoPFP.Dir[1][2] = 1;
119 neutrinoPFP.Dir[0][2] = 1;
121 neutrinoPFP.PDGCode = 14;
122 neutrinoPFP.Vx3ID[1] = vx3.ID;
123 neutrinoPFP.Vx3ID[0] = vx3.ID;
124 neutrinoPFP.NeedsUpdate =
false;
126 if(!
StorePFP(tjs, neutrinoPFP))
return;
130 std::vector<bool> lookedAt3(tjs.
vtx3.size() + 1,
false);
131 std::vector<bool> lookedAt2(tjs.
vtx.size() + 1,
false);
133 std::vector<std::pair<int, int>> pardtr;
135 for(
unsigned short indx = 0; indx < vlist.size(); ++indx) {
136 auto& vx3 = tjs.
vtx3[vlist[indx] - 1];
137 if(lookedAt3[vx3.ID])
continue;
139 lookedAt3[vx3.ID] =
true;
143 if(primTjList.empty())
continue;
145 for(
auto primTjID : primTjList) {
146 auto& primTj = tjs.
allTraj[primTjID - 1];
148 if(primTj.ParentID != -1)
continue;
149 if(prt)
mf::LogVerbatim(
"TC")<<
"Vx3 "<<vx3.ID<<
" Primary tj "<<primTj.ID;
154 for(
unsigned short end = 0;
end < 2; ++
end) {
155 if(primTj.VtxID[
end] == 0)
continue;
156 auto& vx2 = tjs.
vtx[primTj.VtxID[
end] - 1];
157 if(vx2.Vx3ID == vx3.ID)
continue;
160 for(
auto dtrID : dtrList) {
162 if(dtrID == primTjID)
continue;
163 auto& dtj = tjs.
allTraj[dtrID - 1];
164 if(dtj.ParentID != -1) {
168 pardtr.push_back(std::make_pair(primTjID, dtrID));
173 for(
unsigned short end = 0;
end < 2; ++
end) {
174 if(primTj.VtxID[
end] == 0)
continue;
175 auto& vx2 = tjs.
vtx[primTj.VtxID[
end] - 1];
179 if(pardtr.empty())
continue;
183 for(
auto pdtr : pardtr) myprt<<
" "<<pdtr.first<<
"_"<<pdtr.second;
187 for(
unsigned short nit = 0; nit < 100; ++nit) {
188 auto lastPair = pardtr[pardtr.size() - 1];
189 auto& dtj = tjs.
allTraj[lastPair.second - 1];
190 dtj.ParentID = lastPair.first;
193 unsigned short dpt = 0, ppt = 0;
194 auto& ptj = tjs.
allTraj[lastPair.first - 1];
198 unsigned short midPt = (dtj.EndPt[0] + dtj.EndPt[1]) / 2;
204 for(
unsigned short end = 0;
end < 2; ++
end) {
205 if(dtj.VtxID[
end] == 0)
continue;
206 auto& vx2 = tjs.
vtx[dtj.VtxID[
end] - 1];
207 if(lookedAt2[vx2.ID])
continue;
208 lookedAt2[vx2.ID] =
true;
210 for(
auto tjid : tjlist) {
211 if(tjid == dtj.ID || tjid == ptj.ID)
continue;
212 pardtr.push_back(std::make_pair(dtj.ID, tjid));
215 myprt<<
" add par_dtr";
216 for(
auto pdtr : pardtr) myprt<<
" "<<pdtr.first<<
"_"<<pdtr.second;
220 if(pardtr.empty())
break;
224 for(
auto tjid : masterlist) {
225 auto& tj = tjs.
allTraj[tjid - 1];
226 if(tj.ParentID < 0) {
238 if(tjIDs.size() < 2)
return 1;
239 std::vector<float> plnchg(tjs.
NumPlanes);
240 for(
auto tjid : tjIDs) {
241 if(tjid <= 0 || tjid > (
int)tjs.
allTraj.size())
return 1;
242 auto& tj = tjs.
allTraj[tjid - 1];
245 plnchg[plane] += tj.TotChg;
249 for(
unsigned short plane = 0; plane < tjs.
NumPlanes; ++plane) {
250 if(plnchg[plane] == 0)
continue;
251 aveChg += plnchg[plane];
254 if(cnt < 2)
return 1;
257 for(
unsigned short plane = 0; plane < tjs.
NumPlanes; ++plane) {
259 if(plnchg[plane] == 0)
continue;
260 float asym = std::abs(plnchg[plane] - aveChg) / (plnchg[plane] + aveChg);
261 if(asym > maxAsym) maxAsym = asym;
278 std::array<int, 5> codeList = {{0, 11, 13, 211, 2212}};
279 unsigned short codeIndex = 0;
280 if(tjIDs.empty())
return codeList[codeIndex];
282 std::array<unsigned short, 5> cnts;
285 std::array<unsigned short, 2> stopCnt {{0, 0}};
287 for(
auto tjid : tjIDs) {
288 if(tjid <= 0 || tjid > (
int)tjs.
allTraj.size())
continue;
289 auto& tj = tjs.
allTraj[tjid - 1];
290 for(
unsigned short ii = 0; ii < 5; ++ii)
if(tj.PDGCode == codeList[ii]) ++cnts[ii];
292 if(tj.PDGCode != 11 && tj.AlgMod[
kShowerLike]) ++cnts[1];
295 if(len > maxLen) maxLen = len;
299 for(
unsigned short ii = 1; ii < 5; ++ii) {
300 if(cnts[ii] > maxCnt) {
306 bool confused =
false;
307 for(
unsigned short ii = 1; ii < 5; ++ii) {
308 if(ii == codeIndex)
continue;
309 if(cnts[ii] == 0)
continue;
314 if(cnts[4] > 0 && stopCnt[2] > 0 &&
NumDeltaRays(tjs, tjIDs) == 0) {
323 myprt<<
"PDGCodeVote: mixed vote on the PDGCode: Tj_PDGCode";
324 for(
auto tjid : tjIDs) {
325 if(tjid <= 0 || tjid > (
int)tjs.
allTraj.size())
continue;
326 auto& tj = tjs.
allTraj[tjid - 1];
327 myprt<<
" "<<tj.ID<<
"_"<<tj.PDGCode<<
"_"<<tj.StopFlag[1][
kBragg];
331 return codeList[codeIndex];
338 unsigned short cnt = 0;
340 if(dtj.AlgMod[
kKilled])
continue;
342 if(dtj.ParentID == tj.
ID) ++cnt;
351 if(tjIDs.empty())
return 0;
352 if(tjIDs[0] <= 0 || tjIDs[0] > (
int)tjs.
allTraj.size())
return 0;
353 unsigned short cnt = 0;
355 if(tj.AlgMod[
kKilled])
continue;
357 if(std::find(tjIDs.begin(), tjIDs.end(), tj.ParentID) != tjIDs.end()) ++cnt;
370 if(primID <= 0 || primID > (
int)tjs.
allTraj.size())
return -1;
373 auto& ptj = tjs.
allTraj[primID - 1];
374 for(
unsigned short end = 0;
end < 2; ++
end) {
375 if(ptj.VtxID[
end] == 0)
continue;
376 auto& vx2 = tjs.
vtx[ptj.VtxID[
end] - 1];
377 if(vx2.Vx3ID == 0)
continue;
378 auto& vx3 = tjs.
vtx3[vx2.Vx3ID - 1];
379 if(vx3.Neutrino)
return primID;
393 for(
unsigned short nit = 0; nit < 10; ++nit) {
394 if(parid < 1 || parid > (
int)tjs.
allTraj.size())
break;
395 auto& tj = tjs.
allTraj[parid - 1];
411 unsigned short nit = 0;
413 auto& parent = tjs.
pfps[parid - 1];
415 if(parent.PDGCode == 14 || parent.PDGCode == 12)
return dtrid;
417 if(parent.ParentID == 0)
return parent.ID;
418 if(
int(parent.ParentID) == parent.ID)
return parent.ID;
420 parid = parent.ParentID;
421 if(parid < 0)
return 0;
423 if(nit == 10)
return 0;
431 if(mtjid > (
int)tjs.
allTraj.size())
return false;
432 auto& mtj = tjs.
allTraj[mtjid - 1];
435 for(
auto tjid : pfp.
TjIDs) {
436 auto& otj = tjs.
allTraj[tjid - 1];
437 if(otj.CTP == mtj.CTP) {
442 if(otjid == 0)
return false;
444 int newtjid = tjs.
allTraj.size();
445 if(prt)
mf::LogVerbatim(
"TC")<<
"MergeTjIntoPFP: merged T"<<otjid<<
" with T"<<mtjid<<
" -> T"<<newtjid;
446 std::replace(pfp.
TjIDs.begin(), pfp.
TjIDs.begin(), otjid, newtjid);
449 if(prt)
mf::LogVerbatim(
"TC")<<
"MergeTjIntoPFP: merge T"<<otjid<<
" with T"<<mtjid<<
" failed ";
469 if(tjIDs.size() < 2)
return false;
470 unsigned short lasttj = tjIDs[tjIDs.size() - 1] - 1;
471 auto& mtj = tjs.
allTraj[lasttj];
472 bool mtjIsShort = (mtj.Pts.size() < 5);
474 std::array<float, 2> minsep2 {{1000, 1000}};
476 std::array<int, 2> minsepTj {{0, 0}};
478 std::array<unsigned short, 2> minsepPt;
481 std::array<unsigned short, 2> minsepEnd;
482 for(
auto tjid : tjIDs) {
483 auto& tj = tjs.
allTraj[tjid - 1];
484 if(tj.CTP != mtj.CTP)
continue;
485 if(tj.ID == mtj.ID)
continue;
486 for(
unsigned short mend = 0; mend < 2; ++mend) {
487 Point2_t mendPos = mtj.Pts[mtj.EndPt[mend]].Pos;
488 float sep2 = minsep2[mend];
489 unsigned short closePt = 0;
491 minsep2[mend] = sep2;
492 minsepTj[mend] = tjid;
493 minsepPt[mend] = closePt;
496 short dend0 = abs((
short)closePt - tj.EndPt[0]);
497 short dend1 = abs((
short)closePt - tj.EndPt[1]);
498 if(dend0 < dend1 && dend0 < 3) minsepEnd[mend] = 0;
499 if(dend1 < dend0 && dend1 < 3) minsepEnd[mend] = 1;
506 bool isCompatible = (minsepEnd[0] != 2 && minsepEnd[1] != 2);
508 if(isCompatible && mtjIsShort) {
509 float minminsep = minsep2[0];
510 if(minsep2[1] < minminsep) minminsep = minsep2[1];
512 isCompatible = minminsep < 5;
517 myprt<<
"CompatibleMerge: T"<<mtj.ID<<
" end";
518 for(
unsigned short end = 0;
end < 2; ++
end) myprt<<
" T"<<minsepTj[
end]<<
"_I"<<minsepPt[
end]<<
"_E"<<minsepEnd[
end]<<
" minsep "<<sqrt(minsep2[
end]);
519 myprt<<
" Compatible? "<<isCompatible;
531 if(tj1.
CTP != tj2.
CTP)
return false;
532 unsigned short end1 = -1, end2 = 0;
535 if(len2 < minLen) minLen = len2;
537 if(minLen > 10) minLen = 10;
538 for(
unsigned short e1 = 0; e1 < 2; ++e1) {
540 for(
unsigned short e2 = 0; e2 < 2; ++e2) {
542 float sep =
PosSep(tp1.Pos, tp2.Pos);
545 end1 = e1; end2 = e2;
549 if(end1 < 0)
return false;
551 if(end2 != 1 - end1)
return false;
554 if(overlapFraction > 0.25) {
555 if(prt)
mf::LogVerbatim(
"TC")<<
"CM: "<<tj1.
ID<<
" "<<tj2.
ID<<
" overlapFraction "<<overlapFraction<<
" > 0.25 ";
559 auto& tp1 = tj1.
Pts[tj1.
EndPt[end1]];
560 auto& tp2 = tj2.
Pts[tj2.
EndPt[end2]];
567 float doca1 =
PointTrajDOCA(tjs, tp1.Pos[0], tp1.Pos[1], tp2);
568 float doca2 =
PointTrajDOCA(tjs, tp2.Pos[0], tp2.Pos[1], tp1);
569 if(doca1 > 2 && doca2 > 2) {
570 if(prt)
mf::LogVerbatim(
"TC")<<
"CM: "<<tj1.
ID<<
" "<<tj2.
ID<<
" Both docas > 2 "<<doca1<<
" "<<doca2;
588 float maxWire = -1E6;
591 for(
auto& tp : tj1.
Pts) {
592 if(tp.Chg == 0)
continue;
593 if(tp.Pos[0] < 0)
continue;
594 if(tp.Pos[0] < minWire) minWire = tp.Pos[0];
595 if(tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
598 if(cnt1 == 0)
return 0;
600 for(
auto& tp : tj2.
Pts) {
601 if(tp.Chg == 0)
continue;
602 if(tp.Pos[0] < 0)
continue;
603 if(tp.Pos[0] < minWire) minWire = tp.Pos[0];
604 if(tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
607 if(cnt2 == 0)
return 0;
608 int span = maxWire - minWire;
609 if(span <= 0)
return 0;
610 std::vector<unsigned short> wcnt(span);
611 for(
auto& tp : tj1.
Pts) {
612 if(tp.Chg == 0)
continue;
613 if(tp.Pos[0] < -0.4)
continue;
614 int indx = std::nearbyint(tp.Pos[0] - minWire);
615 if(indx < 0 || indx > span - 1)
continue;
618 for(
auto& tp : tj2.
Pts) {
619 if(tp.Chg == 0)
continue;
620 if(tp.Pos[0] < -0.4)
continue;
621 int indx = std::nearbyint(tp.Pos[0] - minWire);
622 if(indx < 0 || indx > span - 1)
continue;
625 float cntOverlap = 0;
626 for(
auto cnt : wcnt)
if(cnt > 1) ++cntOverlap;
628 return cntOverlap / cnt1;
630 return cntOverlap / cnt2;
662 if(angle > M_PI) angle = M_PI;
663 if(angle < -M_PI) angle = M_PI;
664 if(angle < 0) angle = -angle;
665 if(angle > M_PI/2) angle = M_PI - angle;
666 for(
unsigned short ir = 0; ir < tjs.
AngleRanges.size(); ++ir) {
676 unsigned short originPt = tj.
EndPt[1];
677 unsigned short npts = tj.
Pts[originPt].NTPsFit;
679 unsigned short fitDir = -1;
680 FitTraj(tjs, tj, originPt, npts, fitDir, tpFit);
681 tj.
Pts[originPt] = tpFit;
703 if(originPt > tj.
Pts.size() - 1) {
704 mf::LogWarning(
"TC")<<
"FitTraj: Requesting fit of invalid TP "<<originPt;
709 tpFit = tj.
Pts[originPt];
712 if(fitDir < -1 || fitDir > 1)
return;
714 std::vector<double>
x,
y;
717 if(tj.
Pts[originPt].Chg == 0) origin = tj.
Pts[originPt].Pos;
721 for(
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1]; ++ipt) {
722 if(tj.
Pts[ipt].Chg == 0)
continue;
723 double xx = tj.
Pts[ipt].HitPos[0] - origin[0];
724 double yy = tj.
Pts[ipt].HitPos[1] - origin[1];
728 if(x.size() != 2)
return;
732 if(y[1] < y[0]) tpFit.
Ang = -tpFit.
Ang;
734 double dx = x[1] - x[0];
735 double dy = y[1] - y[0];
736 tpFit.
Ang = atan2(dy, dx);
738 tpFit.
Dir[0] = cos(tpFit.
Ang);
739 tpFit.
Dir[1] = sin(tpFit.
Ang);
740 tpFit.
Pos[0] += origin[0];
741 tpFit.
Pos[1] += origin[1];
748 std::vector<double>
w, q;
749 std::array<double, 2>
dir;
750 double xx, yy, xr, yr;
755 double rotAngle = tj.
Pts[originPt].Ang;
756 double cs = cos(-rotAngle);
757 double sn = sin(-rotAngle);
760 if(tj.
Pts[originPt].Chg > 0) {
761 xx = tj.
Pts[originPt].HitPos[0] - origin[0];
762 yy = tj.
Pts[originPt].HitPos[1] - origin[1];
763 xr = cs * xx - sn * yy;
764 yr = sn * xx + cs * yy;
767 chgWt = tj.
Pts[originPt].ChgPull;
768 if(chgWt < 1) chgWt = 1;
770 w.push_back(chgWt * tj.
Pts[originPt].HitPosErr2);
774 if(fitDir != 0) --npts;
778 unsigned short cnt = 0;
779 for(
unsigned short ipt = originPt + 1; ipt < tj.
Pts.size(); ++ipt) {
780 if(tj.
Pts[ipt].Chg == 0)
continue;
781 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
782 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
783 xr = cs * xx - sn * yy;
784 yr = sn * xx + cs * yy;
787 chgWt = tj.
Pts[ipt].ChgPull;
788 if(chgWt < 1) chgWt = 1;
790 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
792 if(cnt == npts)
break;
797 if(fitDir != 1 && originPt > 0) {
798 unsigned short cnt = 0;
799 for(
unsigned short ii = 1; ii < tj.
Pts.size(); ++ii) {
800 unsigned short ipt = originPt - ii;
801 if(ipt > tj.
Pts.size() - 1)
continue;
802 if(tj.
Pts[ipt].Chg == 0)
continue;
803 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
804 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
805 xr = cs * xx - sn * yy;
806 yr = sn * xx + cs * yy;
809 chgWt = tj.
Pts[ipt].ChgPull;
810 if(chgWt < 1) chgWt = 1;
812 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
814 if(cnt == npts)
break;
820 if(x.size() < 2)
return;
831 for(
unsigned short ipt = 0; ipt < x.size(); ++ipt) {
832 if(w[ipt] < 0.00001) w[ipt] = 0.00001;
835 sumx += wght * x[ipt];
836 sumy += wght * y[ipt];
837 sumx2 += wght * x[ipt] * x[ipt];
838 sumy2 += wght * y[ipt] * y[ipt];
839 sumxy += wght * x[ipt] * y[ipt];
842 double delta = sum * sumx2 - sumx * sumx;
843 if(delta == 0)
return;
845 double A = (sumx2 * sumy - sumx * sumxy) / delta;
847 double B = (sumxy * sum - sumx * sumy) / delta;
852 double newang = atan(B);
853 dir[0] = cos(newang);
854 dir[1] = sin(newang);
858 tpFit.
Dir[0] = cs * dir[0] - sn * dir[1];
859 tpFit.
Dir[1] = sn * dir[0] + cs * dir[1];
861 bool flipDir =
false;
863 flipDir = std::signbit(tpFit.
Dir[1]) != std::signbit(tj.
Pts[originPt].Dir[1]);
865 flipDir = std::signbit(tpFit.
Dir[0]) != std::signbit(tj.
Pts[originPt].Dir[0]);
868 tpFit.
Dir[0] = -tpFit.
Dir[0];
869 tpFit.
Dir[1] = -tpFit.
Dir[1];
871 tpFit.
Ang = atan2(tpFit.
Dir[1], tpFit.
Dir[0]);
876 tpFit.
Pos[0] = -sn * A + origin[0];
877 tpFit.
Pos[1] = cs * A + origin[1];
881 if(x.size() < 3)
return;
884 double ndof = x.size() - 2;
885 double varnce = (sumy2 + A*A*sum + B*B*sumx2 - 2 * (A*sumy + B*sumxy - A*B*sumx)) / ndof;
889 double slopeError = sqrt(varnce * sum / delta);
890 tpFit.
AngErr = std::abs(atan(slopeError));
897 for(
unsigned short ii = 0; ii < y.size(); ++ii) {
898 arg = y[ii] - A - B * x[ii];
899 sum += arg * arg / w[ii];
901 tpFit.
FitChi = sum / ndof;
914 std::vector<double>
x,
y;
916 std::vector<double>
w, q;
918 unsigned short firstPt = tj.
EndPt[0] + 2;
919 unsigned short lastPt = tj.
EndPt[1] - 2;
920 if(lastPt < firstPt + 3)
return 0;
922 for(
unsigned short ipt = firstPt; ipt <= lastPt; ++ipt) {
923 auto& tp = tj.
Pts[ipt];
924 if(tp.Chg <= 0)
continue;
927 double sep =
PosSep(tp.Pos, origin);
929 y.push_back((
double)tp.Chg);
930 double wght = 0.2 * tp.Chg;
931 w.push_back(wght * wght);
933 if(w.size() < 3)
return 0;
944 for(
unsigned short ipt = 0; ipt < x.size(); ++ipt) {
947 sumx += wght * x[ipt];
948 sumy += wght * y[ipt];
949 sumx2 += wght * x[ipt] * x[ipt];
950 sumy2 += wght * y[ipt] * y[ipt];
951 sumxy += wght * x[ipt] * y[ipt];
954 double delta = sum * sumx2 - sumx * sumx;
955 if(delta == 0)
return 0;
957 double A = (sumx2 * sumy - sumx * sumxy) / delta;
959 double B = (sumxy * sum - sumx * sumy) / delta;
962 double ndof = x.size() - 2;
963 double varnce = (sumy2 + A*A*sum + B*B*sumx2 - 2 * (A*sumy + B*sumxy - A*B*sumx)) / ndof;
964 if(varnce <= 0)
return 0;
965 double BErr = sqrt(varnce * sum / delta);
968 float slopeSig = B / (3 * BErr);
969 if(slopeSig > 1) slopeSig = 1;
970 if(slopeSig < -1) slopeSig = -1;
972 slopeSig = (1 + slopeSig) / 2;
976 myprt<<
"TjDir: T"<<tj.
ID<<
" slope "<<std::fixed<<std::setprecision(1)<<B<<
" error "<<BErr<<
" DirFOM "<<slopeSig;
984 void WatchHit(std::string someText,
TjStuff& tjs,
const unsigned int& wHit,
short& wInTraj,
const unsigned short& tjID)
987 if(wHit > tjs.
fHits.size() - 1)
return;
989 if(tjs.
fHits[wHit].InTraj != wInTraj) {
990 std::cout<<someText<<
" Hit "<<
PrintHitShort(tjs.
fHits[wHit])<<
" was InTraj "<<wInTraj<<
" now InTraj "<<tjs.
fHits[wHit].InTraj<<
" T"<<tjID<<
"\n";
991 wInTraj = tjs.
fHits[wHit].InTraj;
1002 if(pfp.
PDGCode == 1111)
return;
1004 bool reverseMe =
false;
1008 unsigned short braggCnt0 = 0;
1009 unsigned short braggCnt1 = 0;
1010 for(
auto& tjID : pfp.
TjIDs) {
1011 auto& tj = tjs.
allTraj[tjID - 1];
1012 if(tj.StopFlag[0][
kBragg]) ++braggCnt0;
1013 if(tj.StopFlag[1][
kBragg]) ++braggCnt1;
1015 if(braggCnt0 > 0 || braggCnt1 > 0) {
1018 if(braggCnt0 > braggCnt1) reverseMe =
true;
1022 if(!reverseMe)
return;
1025 for(
auto& tjID : pfp.
TjIDs) {
1026 unsigned short itj = tjID - 1;
1033 std::swap(pfp.
XYZ[0], pfp.
XYZ[1]);
1034 std::swap(pfp.
Dir[0], pfp.
Dir[1]);
1036 std::swap(pfp.
dEdx[0], pfp.
dEdx[1]);
1049 if(tjs.
pfps.empty())
return USHRT_MAX;
1050 for(
unsigned int ipfp = 0; ipfp < tjs.
pfps.size(); ++ipfp) {
1051 const auto& pfp = tjs.
pfps[ipfp];
1052 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tjID) != pfp.TjIDs.end())
return ipfp;
1062 for(
unsigned int ims = 0; ims < tjs.
matchVec.size(); ++ims) {
1063 const auto& ms = tjs.
matchVec[ims];
1064 if(std::find(ms.TjIDs.begin(), ms.TjIDs.end(), tjID) != ms.TjIDs.end())
return ims;
1073 for(
auto& tp : tj.
Pts) {
1074 for(
auto iht : tp.Hits) {
1075 if(tjs.
fHits[iht].InTraj == tj.
ID) tjs.
fHits[iht].InTraj = 0;
1085 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
1103 if(tjs.
allTraj.size() >= USHRT_MAX) {
1112 if(tj.
EndPt[1] > tj.
Pts.size())
return false;
1113 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0] + 1;
1114 if(npts < 2)
return false;
1116 auto& endTp0 = tj.
Pts[tj.
EndPt[0]];
1117 auto& endTp1 = tj.
Pts[tj.
EndPt[1]];
1121 if(endTp0.AveChg <= 0) {
1122 unsigned short cnt = 0;
1124 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1125 if(tj.
Pts[ipt].Chg == 0)
continue;
1126 sum += tj.
Pts[ipt].Chg;
1130 tj.
Pts[tj.
EndPt[0]].AveChg = sum / (float)cnt;
1132 if(endTp1.AveChg <= 0 && npts < 5) endTp1.AveChg = endTp0.AveChg;
1133 if(endTp1.AveChg <= 0) {
1135 unsigned short cnt = 0;
1136 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
1137 short ipt = tj.
EndPt[1] - ii;
1139 if(tj.
Pts[ipt].Chg == 0)
continue;
1140 sum += tj.
Pts[ipt].Chg;
1145 tj.
Pts[tj.
EndPt[1]].AveChg = sum / (float)cnt;
1152 int trID = tjs.
allTraj.size() + 1;
1154 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1155 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1156 if(tj.
Pts[ipt].UseHit[ii]) {
1157 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1158 if(tjs.
fHits[iht].InTraj > 0) {
1159 mf::LogWarning(
"TC")<<
"StoreTraj: Failed trying to store hit "<<
PrintHit(tjs.
fHits[iht])<<
" in T"<<trID<<
" but it is used in T"<<tjs.
fHits[iht].InTraj<<
" with WorkID "<<tjs.
allTraj[tjs.
fHits[iht].InTraj-1].WorkID<<
" Print and quit";
1164 tjs.
fHits[iht].InTraj = trID;
1170 for(
unsigned int iht = 0; iht < tjs.
fHits.size(); ++iht) {
1171 if(tjs.
fHits[iht].InTraj == tj.
ID) {
1186 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
1187 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1188 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1189 if(iht ==
debug.
Hit) std::cout<<
"Debug hit appears in trajectory w WorkID "<<tj.
WorkID<<
" UseHit "<<tj.
Pts[ipt].UseHit[ii]<<
"\n";
1205 unsigned short itj = 0;
1206 std::vector<unsigned int> tHits;
1207 std::vector<unsigned int> atHits;
1210 if(tj.AlgMod[
kKilled])
continue;
1213 std::cout<<someText<<
" ChkInTraj hit size mis-match in tj ID "<<tj.ID<<
" AlgBitNames";
1214 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(tj.AlgMod[ib]) std::cout<<
" "<<
AlgBitNames[ib];
1219 if(tHits.size() < 2) {
1220 std::cout<<someText<<
" ChkInTraj: Insufficient hits in traj "<<tj.ID<<
"\n";
1224 std::sort(tHits.begin(), tHits.end());
1226 for(iht = 0; iht < tjs.
fHits.size(); ++iht) {
1227 if(tjs.
fHits[iht].InTraj == tID) atHits.push_back(iht);
1229 if(atHits.size() < 2) {
1230 std::cout<<someText<<
" ChkInTraj: Insufficient hits in atHits in traj "<<tj.ID<<
" Killing it\n";
1234 if(!std::equal(tHits.begin(), tHits.end(), atHits.begin())) {
1236 myprt<<someText<<
" ChkInTraj failed: inTraj - UseHit mis-match for T"<<tID<<
" tj.WorkID "<<tj.WorkID<<
" atHits size "<<atHits.size()<<
" tHits size "<<tHits.size()<<
" in CTP "<<tj.CTP<<
"\n";
1240 myprt<<
"index inTraj UseHit \n";
1241 for(iht = 0; iht < atHits.size(); ++iht) {
1243 if(iht < tHits.size()) myprt<<
" "<<
PrintHit(tjs.
fHits[tHits[iht]]);
1244 if(atHits[iht] != tHits[iht]) myprt<<
" <<< "<<atHits[iht]<<
" != "<<tHits[iht];
1247 if(tHits.size() > atHits.size()) {
1248 for(iht = atHits.size(); iht < atHits.size(); ++iht) {
1249 myprt<<
"atHits "<<iht<<
" "<<
PrintHit(tjs.
fHits[atHits[iht]])<<
"\n";
1256 for(
unsigned short end = 0;
end < 2; ++
end) {
1257 if(tj.VtxID[
end] > tjs.
vtx.size()) {
1259 std::cout<<someText<<
" ChkInTraj: Bad VtxID "<<tj.ID<<
" vtx size "<<tjs.
vtx.size()<<
"\n";
1284 if(itj > tjs.
allTraj.size() - 1)
return;
1288 if(tj.StopFlag[0][
kBragg])
return;
1290 if(tj.AlgMod[
kKilled])
return;
1291 if(tj.Pts.size() < 20)
return;
1294 float chg2 = tj.Pts[tj.EndPt[0] + 2].AveChg;
1296 float chg15 = tj.Pts[tj.EndPt[0] + 15].AveChg;
1297 if(chg2 < 3 * chg15)
return;
1300 float midChg = 0.5 * (chg2 + chg15);
1302 unsigned short breakPt = USHRT_MAX;
1303 for(
unsigned short ipt = tj.EndPt[0] + 3; ipt < 15; ++ipt) {
1304 float chgm2 = tj.Pts[ipt - 2].Chg;
1305 if(chgm2 == 0)
continue;
1306 float chgm1 = tj.Pts[ipt - 1].Chg;
1307 if(chgm1 == 0)
continue;
1308 float chgp1 = tj.Pts[ipt + 1].Chg;
1309 if(chgp1 == 0)
continue;
1310 float chgp2 = tj.Pts[ipt + 2].Chg;
1311 if(chgp2 == 0)
continue;
1312 if(chgm2 > midChg && chgm1 > midChg && chgp1 < midChg && chgp2 < midChg) {
1317 if(breakPt == USHRT_MAX)
return;
1320 aVtx.
Pos = tj.Pts[breakPt].Pos;
1322 aVtx.
Pass = tj.Pass;
1326 aVtx.
ID = tjs.
vtx.size() + 1;
1328 unsigned short ivx = tjs.
vtx.size();
1330 if(!
SplitTraj(tjs, itj, breakPt, ivx, prt)) {
1356 short minPts = fQualityCuts[1];
1357 if(minPts < 1)
return;
1358 if(npwc < minPts)
return;
1361 if(npwc == minPts + 1) {
1362 unsigned short endPt1 = tj.
EndPt[1];
1363 auto& tp = tj.
Pts[endPt1];
1364 auto& ptp = tj.
Pts[endPt1 - 1];
1367 float dwire = std::abs(ptp.Pos[0] - tp.Pos[0]);
1368 if(ptp.Chg == 0 || dwire > 1.1) {
1378 for(lastPt = tj.
EndPt[1]; lastPt >= minPts; --lastPt) {
1380 if(lastPt == 1)
break;
1381 if(tj.
Pts[lastPt].Chg == 0)
continue;
1383 unsigned short nadj = 0;
1384 unsigned short npwc = 0;
1385 for(
short ipt = lastPt - minPts; ipt < lastPt; ++ipt) {
1388 auto& tp = tj.
Pts[ipt];
1390 auto& ptp = tj.
Pts[ipt - 1];
1391 if(tp.Chg > 0 && ptp.Chg > 0) {
1393 if(std::abs(tp.Pos[0] - ptp.Pos[0]) < 1.5) ++nadj;
1397 float nwires = std::abs(tj.
Pts[tj.
EndPt[0]].Pos[0] - tj.
Pts[lastPt].Pos[0]) + 1;
1398 float hitFrac = ntpwc / nwires;
1399 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
"-TEP: T"<<tj.
ID<<
" lastPt "<<lastPt<<
" npwc "<<npwc<<
" nadj "<<nadj<<
" hitFrac "<<hitFrac;
1400 if(hitFrac > fQualityCuts[0] && npwc == minPts && nadj == minPts)
break;
1404 if(tj.
Pts[lastPt].Pos[0] > -0.4) {
1405 unsigned int prevWire = std::nearbyint(tj.
Pts[lastPt].Pos[0]);
1412 mf::LogVerbatim(
"TC")<<fcnLabel<<
"-TEP: is prevWire "<<prevWire<<
" dead? ";
1419 if(lastPt == tj.
EndPt[1]) {
1429 fcnLabel +=
"-TEPo";
1443 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0];
1446 if(npts > 50)
return;
1448 if(npts < 8)
return;
1451 unsigned short atPt = 0;
1453 for(
unsigned short ipt = tj.
EndPt[0] + 2; ipt <= tj.
EndPt[1] - 2; ++ipt) {
1454 auto& tp = tj.
Pts[ipt];
1455 if(tp.ChgPull > bigPull) {
1456 bigPull = tp.ChgPull;
1460 if(atPt == 0)
return;
1462 if((atPt - tj.
EndPt[0]) < 0.5 * npts)
return;
1463 if(prt)
mf::LogVerbatim(
"TC")<<
"CCA: T"<<tj.
ID<<
" Large Chg point at "<<atPt<<
". Check charge asymmetry around it.";
1464 unsigned short nchk = 0;
1465 unsigned short npos = 0;
1466 unsigned short nneg = 0;
1467 for(
short ii = 1; ii < 5; ++ii) {
1468 short iplu = atPt + ii;
1469 if(iplu > tj.
EndPt[1])
break;
1470 short ineg = atPt - ii;
1471 if(ineg < tj.
EndPt[0])
break;
1472 if(tj.
Pts[iplu].Chg == 0)
continue;
1473 if(tj.
Pts[ineg].Chg == 0)
continue;
1474 float asym = (tj.
Pts[iplu].Chg - tj.
Pts[ineg].Chg) / (tj.
Pts[iplu].Chg + tj.
Pts[ineg].Chg);
1476 if(asym > 0.5) ++npos;
1477 if(asym < -0.5) ++nneg;
1478 if(prt)
mf::LogVerbatim(
"TC")<<
" ineg "<<ineg<<
" iplu "<<iplu<<
" asym "<<asym<<
" nchk "<<nchk;
1480 if(nchk < 3)
return;
1483 bool doTrim = (nneg > nchk) || (npos > nchk);
1486 auto& prevTP = tj.
Pts[atPt - 1];
1487 if(std::abs(prevTP.ChgPull) > 2) --atPt;
1498 if(MinWireSignalFraction == 0)
return true;
1500 if(tp1.
Pos[0] < -0.4 || tp2.
Pos[0] < -0.4)
return false;
1501 int fromWire = std::nearbyint(tp1.
Pos[0]);
1502 int toWire = std::nearbyint(tp2.
Pos[0]);
1504 if(fromWire == toWire) {
1507 tp.
Pos[1] = 0.5 * (tp1.
Pos[1] + tp2.
Pos[1]);
1514 return SignalBetween(tjs, tp, toWire, MinWireSignalFraction, prt);
1523 return ChgFracBetween(tjs, tp, toPos0, prt) >= MinWireSignalFraction;
1532 if(tp.
Pos[0] < -0.4 || toPos0 < -0.4)
return 0;
1533 int fromWire = std::nearbyint(tp.
Pos[0]);
1534 int toWire = std::nearbyint(toPos0);
1536 if(fromWire == toWire) {
1541 int nWires = abs(toWire - fromWire) + 1;
1543 if(std::abs(tp.
Dir[0]) < 0.001) tp.
Dir[0] = 0.001;
1544 float stepSize = std::abs(1/tp.
Dir[0]);
1546 if(toWire > fromWire && tp.
Dir[0] < 0) stepSize = -stepSize;
1547 if(toWire < fromWire && tp.
Dir[0] > 0) stepSize = -stepSize;
1550 for(
unsigned short cnt = 0; cnt < nWires; ++cnt) {
1553 tp.
Pos[0] += tp.
Dir[0] * stepSize;
1554 tp.
Pos[1] += tp.
Dir[1] * stepSize;
1556 float sigFrac = nsig / num;
1557 if(prt)
mf::LogVerbatim(
"TC")<<
" ChgFracBetween fromWire "<<fromWire<<
" toWire "<<toWire<<
" nWires "<<num<<
" nsig "<<nsig<<
" "<<sigFrac;
1563 bool TrajHitsOK(
TjStuff& tjs,
const std::vector<unsigned int>& iHitsInMultiplet,
const std::vector<unsigned int>& jHitsInMultiplet)
1567 if(iHitsInMultiplet.empty() || jHitsInMultiplet.empty())
return false;
1573 for(
auto& iht : iHitsInMultiplet) {
1574 float cv = tjs.
fHits[iht].PeakTime;
1575 float rms = tjs.
fHits[iht].RMS;
1576 float arg = cv - 3 * rms;
1577 if(arg < minI) minI = arg;
1579 if(arg > maxI) maxI = arg;
1585 for(
auto& jht : jHitsInMultiplet) {
1586 float cv = tjs.
fHits[jht].PeakTime;
1587 float rms = tjs.
fHits[jht].RMS;
1588 float arg = cv - 3 * rms;
1589 if(arg < minJ) minJ = arg;
1591 if(arg > maxJ) maxJ = arg;
1595 if(maxI > minJ)
return true;
1597 if(minI < maxJ)
return true;
1606 if(iht > tjs.
fHits.size() - 1)
return false;
1607 if(jht > tjs.
fHits.size() - 1)
return false;
1613 if(std::abs(iwire - jwire) > 1)
return false;
1617 if(maxJSignal > minISignal)
return true;
1621 if(minJSignal > maxISignal)
return true;
1630 if(std::abs(tp.
Dir[0]) > 0.001) {
1643 if(tp.
Pos[0] < -0.4)
return false;
1644 unsigned int wire = std::nearbyint(tp.
Pos[0]);
1646 unsigned int ipl = planeID.
Plane;
1647 if(wire >= tjs.
NumWires[ipl])
return false;
1648 if(tp.
Pos[1] > tjs.
MaxPos1[ipl])
return false;
1650 if(tjs.
WireHitRange[ipl][wire].first == -1)
return true;
1652 float tickRange = 0;
1653 if(std::abs(tp.
Dir[1]) != 0) {
1656 if(tickRange > 40) tickRange = 40;
1658 float loTpTick = projTick - tickRange;
1659 float hiTpTick = projTick + tickRange;
1660 unsigned int firstHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].first;
1661 unsigned int lastHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].second;
1663 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
1667 if(hiTpTick > loHitTick)
return true;
1670 if(loTpTick < hiHitTick)
return true;
1680 for (
size_t i = 0; i<tp.
Hits.size(); ++i){
1681 if (!tp.
UseHit[i])
continue;
1682 totchg += tjs.
fHits[tp.
Hits[i]].Integral;
1740 unsigned short firstPt = tj.
EndPt[0];
1741 unsigned short lastPt = tj.
EndPt[1];
1748 unsigned short ntp = 0;
1749 for(
unsigned short ipt = firstPt; ipt <= lastPt; ++ipt)
if(tj.
Pts[ipt].Chg > 0) ++ntp;
1764 if(inWirePos1 < -0.4 || inWirePos2 < -0.4)
return 0;
1765 unsigned int inWire1 = std::nearbyint(inWirePos1);
1766 unsigned int inWire2 = std::nearbyint(inWirePos2);
1768 unsigned short plane = planeID.
Plane;
1769 if(inWire1 > tjs.
NumWires[plane] || inWire2 > tjs.
NumWires[plane])
return 0;
1770 if(inWire1 > inWire2) {
1772 unsigned int tmp = inWire1;
1777 unsigned int wire, ndead = 0;
1778 for(wire = inWire1; wire < inWire2; ++wire)
if(tjs.
WireHitRange[plane][wire].first == -1) ++ndead;
1785 unsigned short pdg = abs(PDGCode);
1786 if(pdg == 11)
return 0;
1787 if(pdg == 13)
return 1;
1788 if(pdg == 211)
return 2;
1789 if(pdg == 321)
return 3;
1790 if(pdg == 2212)
return 4;
1801 if(itj > tjs.
allTraj.size() - 1)
return;
1802 int killTjID = tjs.
allTraj[itj].ID;
1803 for(
auto&
hit : tjs.
fHits)
if(
hit.InTraj == killTjID)
hit.InTraj = 0;
1810 if(itj > tjs.
allTraj.size() - 1)
return;
1812 mf::LogWarning(
"TC")<<
"RestoreObsoleteTrajectory: Trying to restore not-obsolete trajectory "<<tjs.
allTraj[itj].ID;
1816 for(
auto& tp : tjs.
allTraj[itj].Pts) {
1817 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
1820 if(tjs.
fHits[iht].InTraj == 0) {
1835 for(
auto& shortTj : tjs.
allTraj) {
1836 if(shortTj.AlgMod[
kKilled])
continue;
1837 if(shortTj.CTP != inCTP)
continue;
1838 unsigned short spts = shortTj.EndPt[1] - shortTj.EndPt[0];
1839 if(spts > 20)
continue;
1841 if(shortTj.PDGCode == 11)
continue;
1843 if(shortTj.SSID > 0)
continue;
1845 if(tjhits.empty())
continue;
1846 std::vector<int> tids;
1847 std::vector<unsigned short> tcnt;
1848 for(
auto iht : tjhits) {
1850 if(
hit.InTraj <= 0)
continue;
1851 if((
unsigned int)
hit.InTraj > tjs.
allTraj.size())
continue;
1852 if(
hit.InTraj == shortTj.ID)
continue;
1853 unsigned short indx = 0;
1854 for(indx = 0; indx < tids.size(); ++indx)
if(
hit.InTraj == tids[indx])
break;
1855 if(indx == tids.size()) {
1856 tids.push_back(
hit.InTraj);
1862 if(tids.empty())
continue;
1864 unsigned short maxcnt = 0;
1865 for(
unsigned short indx = 0; indx < tids.size(); ++indx) {
1866 if(tcnt[indx] > maxcnt) {
1867 auto& ltj = tjs.
allTraj[tids[indx] - 1];
1868 unsigned short lpts = ltj.EndPt[1] - ltj.EndPt[0];
1869 if(lpts < spts)
continue;
1870 maxcnt = tcnt[indx];
1873 float hitFrac = (float)maxcnt / (
float)tjhits.size();
1874 if(hitFrac < 0.1)
continue;
1882 if(itj > tjs.
allTraj.size()-1)
return false;
1887 unsigned short atPt = USHRT_MAX;
1888 for(
unsigned short ipt = tj.EndPt[0] + 1; ipt <= tj.EndPt[1]; ++ipt) {
1889 if(tj.Pts[ipt].Pos[1] > tj.Pts[ipt - 1].Pos[1]) {
1891 if(tj.Pts[ipt - 1].Pos[1] < atPos1 && tj.Pts[ipt].Pos[1] >= atPos1) {
1897 if(tj.Pts[ipt - 1].Pos[1] >= atPos1 && tj.Pts[ipt].Pos[1] < atPos1) {
1903 if(atPt == USHRT_MAX)
return false;
1904 unsigned short vx2Index = USHRT_MAX;
1907 newVx2.
CTP = tj.CTP;
1908 newVx2.
Pos[0] = 0.5 * (tj.Pts[atPt - 1].Pos[0] + tj.Pts[atPt].Pos[0]);
1909 newVx2.
Pos[1] = 0.5 * (tj.Pts[atPt - 1].Pos[1] + tj.Pts[atPt].Pos[1]);
1914 return SplitTraj(tjs, itj, atPt, vx2Index, prt);
1918 bool SplitTraj(
TjStuff& tjs,
unsigned short itj,
unsigned short pos,
unsigned short ivx,
bool prt)
1925 if(itj > tjs.
allTraj.size()-1)
return false;
1926 if(pos < tjs.
allTraj[itj].EndPt[0] + 1 || pos > tjs.
allTraj[itj].EndPt[1] - 1)
return false;
1927 if(ivx != USHRT_MAX && ivx > tjs.
vtx.size() - 1)
return false;
1932 bool splittingMuon = (tj.
PDGCode == 13);
1933 if(splittingMuon) tj.
PDGCode = 0;
1937 myprt<<
"SplitTraj: Split T"<<tj.
ID<<
" at point "<<pos;
1938 if(ivx < tjs.
vtx.size()) myprt<<
" with Vtx 2V"<<tjs.
vtx[ivx].ID;
1942 unsigned short ipt, ii, ntp = 0;
1943 for(ipt = 0; ipt < pos; ++ipt) {
1944 if(tj.
Pts[ipt].Chg > 0) ++ntp;
1948 if(prt)
mf::LogVerbatim(
"TC")<<
" Split point to small at begin "<<ntp<<
" pos "<<pos<<
" ID ";
1952 for(ipt = pos + 1; ipt < tj.
Pts.size(); ++ipt) {
1953 if(tj.
Pts[ipt].Chg > 0) ++ntp;
1957 if(prt)
mf::LogVerbatim(
"TC")<<
" Split point too small at end "<<ntp<<
" pos "<<pos<<
" EndPt "<<tj.
EndPt[1];
1970 for(ipt = pos + 1; ipt < tj.
Pts.size(); ++ipt) {
1971 tj.
Pts[ipt].Chg = 0;
1972 for(ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1973 if(!tj.
Pts[ipt].UseHit[ii])
continue;
1974 iht = tj.
Pts[ipt].Hits[ii];
1976 if(tjs.
fHits[iht].InTraj != tj.
ID)
continue;
1977 tjs.
fHits[iht].InTraj = newTj.
ID;
1978 tj.
Pts[ipt].UseHit[ii] =
false;
1988 unsigned short eraseSize = pos - 2;
1989 if(eraseSize > newTj.
Pts.size() - 1) {
1994 if(ivx < tjs.
vtx.size()) tj.
VtxID[1] = tjs.
vtx[ivx].ID;
2001 newTj.
Pts.erase(newTj.
Pts.begin(), newTj.
Pts.begin() + eraseSize);
2003 for(ipt = 0; ipt < 3; ++ipt) {
2004 for(ii = 0; ii < newTj.
Pts[ipt].Hits.size(); ++ii) newTj.
Pts[ipt].UseHit[ii] =
false;
2005 newTj.
Pts[ipt].Chg = 0;
2010 if(ivx < tjs.
vtx.size()) newTj.
VtxID[0] = tjs.
vtx[ivx].ID;
2029 float best = minSep * minSep;
2030 closePt = USHRT_MAX;
2033 for(ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
2034 dw = tj.
Pts[ipt].Pos[0] - tp.
Pos[0];
2035 dt = tj.
Pts[ipt].Pos[1] - tp.
Pos[1];
2036 dp2 = dw * dw + dt * dt;
2042 minSep = sqrt(best);
2048 return TrajTrajDOCA(tjs, tj1, tj2, ipt1, ipt2, minSep,
false);
2057 for(
unsigned short iwt = 0; iwt < 2; ++iwt) {
2060 float wt0 = tj1.
Pts[tj1.
EndPt[0]].Pos[iwt];
2061 float wt1 = tj1.
Pts[tj1.
EndPt[1]].Pos[iwt];
2069 wt0 = tj2.
Pts[tj2.
EndPt[0]].Pos[iwt];
2070 wt1 = tj2.
Pts[tj2.
EndPt[1]].Pos[iwt];
2080 if(lowt2 > hiwt1 + minSep)
return false;
2082 if(lowt1 > hiwt2 + minSep)
return false;
2085 float best = minSep * minSep;
2088 bool isClose =
false;
2089 for(
unsigned short i1 = tj1.
EndPt[0]; i1 < tj1.
EndPt[1] + 1; ++i1) {
2090 for(
unsigned short i2 = tj2.
EndPt[0]; i2 < tj2.
EndPt[1] + 1; ++i2) {
2092 float dw = tj1.
Pts[i1].Pos[0] - tj2.
Pts[i2].Pos[0] - dwc;
2093 if(std::abs(dw) > minSep)
continue;
2094 float dt = tj1.
Pts[i1].Pos[1] - tj2.
Pts[i2].Pos[1];
2095 if(std::abs(dt) > minSep)
continue;
2096 float dp2 = dw * dw + dt * dt;
2105 minSep = sqrt(best);
2113 if(iht > tjs.
fHits.size()-1 || jht > tjs.
fHits.size()-1)
return 1E6;
2114 float dw = (float)tjs.
fHits[iht].ArtPtr->WireID().Wire - (float)tjs.
fHits[jht].ArtPtr->WireID().Wire;
2116 return dw * dw + dt * dt;
2122 unsigned short endPt = tj.
EndPt[0];
2123 auto& tp0 = tj.
Pts[endPt];
2124 endPt = tj.
EndPt[1];
2125 auto& tp1 = tj.
Pts[endPt];
2133 float dw = wire - tp.
Pos[0];
2134 float dt = time - tp.
Pos[1];
2135 return dw * dw + dt * dt;
2141 float wire = tjs.
fHits[iht].ArtPtr->WireID().Wire;
2158 float t = (wire - tp.
Pos[0]) * tp.
Dir[0] + (time - tp.
Pos[1]) * tp.
Dir[1];
2159 float dw = tp.
Pos[0] + t * tp.
Dir[0] - wire;
2160 float dt = tp.
Pos[1] + t * tp.
Dir[1] - time;
2161 return (dw * dw + dt * dt);
2175 x = -9999; y = -9999;
2177 double arg1 = tp1.
Pos[0] * tp1.
Dir[1] - tp1.
Pos[1] * tp1.
Dir[0];
2178 double arg2 = tp2.
Pos[0] * tp1.
Dir[1] - tp2.
Pos[1] * tp1.
Dir[0];
2179 double arg3 = tp2.
Dir[0] * tp1.
Dir[1] - tp2.
Dir[1] * tp1.
Dir[0];
2180 if(arg3 == 0)
return;
2181 double s = (arg1 - arg2) / arg3;
2183 x = (float)(tp2.
Pos[0] + s * tp2.
Dir[0]);
2184 y = (float)(tp2.
Pos[1] + s * tp2.
Dir[1]);
2192 if(tjIDs.empty())
return 0;
2194 for(
auto tjid : tjIDs) {
2195 if(tjid < 1 || tjid > (
int)tjs.
allTraj.size())
continue;
2196 auto& tj = tjs.
allTraj[tjid - 1];
2197 float sep2 =
PosSep2(tj.Pts[tj.EndPt[0]].Pos, tj.Pts[tj.EndPt[1]].Pos);
2198 if(sep2 > maxLen) maxLen = sep2;
2200 return sqrt(maxLen);
2206 float len = 0, dx, dy;
2208 unsigned short prevPt = tj.
EndPt[0];
2209 for(ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1] + 1; ++ipt) {
2210 if(tj.
Pts[ipt].Chg == 0)
continue;
2211 dx = tj.
Pts[ipt].Pos[0] - tj.
Pts[prevPt].Pos[0];
2212 dy = tj.
Pts[ipt].Pos[1] - tj.
Pts[prevPt].Pos[1];
2213 len += sqrt(dx * dx + dy * dy);
2222 return sqrt(
PosSep2(pos1, pos2));
2229 float d0 = pos1[0] - pos2[0];
2230 float d1 = pos1[1] - pos2[1];
2238 float dx = tp1.
Pos[0] - tp2.
Pos[0];
2239 float dy = tp1.
Pos[1] - tp2.
Pos[1];
2240 return sqrt(dx * dx + dy * dy);
2250 float close2 = DOCA * DOCA;
2252 bool foundClose =
false;
2254 for(
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1] + 1; ++ipt) {
2255 if(tj.
Pts[ipt].Chg == 0)
continue;
2256 float dx = tj.
Pts[ipt].Pos[0] -
x;
2257 if(std::abs(dx) > DOCA)
continue;
2258 float dy = tj.
Pts[ipt].Pos[1] -
y;
2259 if(std::abs(dy) > DOCA)
continue;
2260 float sep2 = dx * dx + dy * dy;
2268 DOCA = sqrt(close2);
2277 float dw = tp2.
Pos[0] - tp1.
Pos[0];
2278 float dt = tp2.
Pos[1] - tp1.
Pos[1];
2279 return atan2(dw, dt);
2286 std::vector<unsigned int> hitVec;
2290 for(
auto& tp : tj.
Pts) hitVec.insert(hitVec.end(), tp.Hits.begin(), tp.Hits.end());
2295 hitVec.reserve(tj.
Pts.size());
2296 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2297 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
2298 unsigned int iht = tj.
Pts[ipt].Hits[ii];
2299 bool useit = (hitRequest ==
kAllHits);
2300 if(tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUsedHits) useit =
true;
2301 if(!tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUnusedHits) useit =
true;
2302 if(useit) hitVec.push_back(iht);
2316 if(tj.
Pts.size() > 10)
return;
2318 unsigned short nhm = 0;
2319 unsigned short npwc = 0;
2320 for(
auto& tp : tj.
Pts) {
2321 if(tp.Chg == 0)
continue;
2323 unsigned short nused = 0;
2324 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
2325 if(tp.UseHit[ii]) ++nused;
2327 if(nused > 3) ++nhm;
2339 for(
unsigned short ii = 0; ii < tjHits.size() - 1; ++ii) {
2340 for(
unsigned short jj = ii + 1; jj < tjHits.size(); ++jj) {
2341 if(tjHits[ii] == tjHits[jj]) {
2354 if(tp.
Dir[0] == 0)
return;
2355 float dw = wire - tp.
Pos[0];
2356 if(std::abs(dw) < 0.01)
return;
2358 tp.
Pos[1] += dw * tp.
Dir[1] / tp.
Dir[0];
2362 std::vector<unsigned int>
FindCloseHits(
TjStuff const& tjs, std::array<int, 2>
const& wireWindow,
Point2_t const& timeWindow,
const unsigned short plane,
HitStatus_t hitRequest,
bool usePeakTime,
bool& hitsNear)
2378 std::vector<unsigned int> closeHits;
2379 if(plane > tjs.
FirstWire.size() - 1)
return closeHits;
2381 int loWire = wireWindow[0];
2383 int hiWire = wireWindow[1];
2388 for(
int wire = loWire; wire <= hiWire; ++wire) {
2390 if(tjs.
WireHitRange[plane][wire].first == -2) hitsNear =
true;
2392 unsigned int firstHit = (
unsigned int)tjs.
WireHitRange[plane][wire].first;
2393 unsigned int lastHit = (
unsigned int)tjs.
WireHitRange[plane][wire].second;
2394 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2395 if(tjs.
fHits[iht].InTraj == INT_MAX)
continue;
2397 if(tjs.
fHits[iht].PeakTime < minTick)
continue;
2398 if(tjs.
fHits[iht].PeakTime > maxTick)
break;
2401 if(tjs.
fHits[iht].StartTick > hiLo) hiLo = tjs.
fHits[iht].StartTick;
2403 if(tjs.
fHits[iht].EndTick < loHi) loHi = tjs.
fHits[iht].EndTick;
2404 if(loHi < hiLo)
continue;
2405 if(hiLo > loHi)
break;
2408 bool takeit = (hitRequest ==
kAllHits);
2409 if(hitRequest ==
kUsedHits && tjs.
fHits[iht].InTraj > 0) takeit =
true;
2411 if(takeit) closeHits.push_back(iht);
2431 unsigned short ipl = planeID.
Plane;
2432 if(tp.
Pos[0] < -0.4)
return false;
2433 unsigned int wire = std::nearbyint(tp.
Pos[0]);
2434 if(wire < tjs.
FirstWire[ipl])
return false;
2435 if(wire > tjs.
LastWire[ipl]-1)
return false;
2438 if(tjs.
WireHitRange[ipl][wire].first == -1)
return true;
2440 if(tjs.
WireHitRange[ipl][wire].first == -2)
return false;
2442 unsigned int firstHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].first;
2443 unsigned int lastHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].second;
2446 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2447 if(tjs.
fHits[iht].InTraj == INT_MAX)
continue;
2448 bool useit = (hitRequest ==
kAllHits);
2449 if(hitRequest ==
kUsedHits && tjs.
fHits[iht].InTraj > 0) useit =
true;
2451 if(!useit)
continue;
2454 if(delta < maxDelta) tp.
Hits.push_back(iht);
2456 if(tp.
Hits.size() > 16) {
2484 std::vector<int>
tmp;
2485 if(fromTp.
Pos[0] < -0.4 || toTp.
Pos[0] < -0.4)
return tmp;
2489 unsigned int firstWire, lastWire;
2490 if(toTp.
Pos[0] > fromTp.
Pos[0]) {
2492 firstWire = std::nearbyint(fromTp.
Pos[0]);
2493 lastWire = std::nearbyint(toTp.
Pos[0]);
2494 }
else if(toTp.
Pos[0] < fromTp.
Pos[0]) {
2496 firstWire = std::nearbyint(toTp.
Pos[0]);
2497 lastWire = std::nearbyint(fromTp.
Pos[0]);
2500 float tmp = fromTp.
Pos[0] - maxDelta;
2501 if(tmp < 0) tmp = 0;
2502 firstWire = std::nearbyint(tmp);
2503 tmp = fromTp.
Pos[0] + maxDelta;
2504 lastWire = std::nearbyint(tmp);
2508 unsigned short ipl = planeID.
Plane;
2515 for(
unsigned int wire = firstWire; wire <= lastWire; ++wire) {
2522 unsigned int firstHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].first;
2523 unsigned int lastHit = (
unsigned int)tjs.
WireHitRange[ipl][wire].second;
2524 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2525 if(tjs.
fHits[iht].InTraj <= 0)
continue;
2526 if((
unsigned int)tjs.
fHits[iht].InTraj > tjs.
allTraj.size())
continue;
2527 if(tjs.
fHits[iht].PeakTime < minTick)
continue;
2529 if(tjs.
fHits[iht].PeakTime > maxTick)
break;
2530 if(std::find(tmp.begin(), tmp.end(), tjs.
fHits[iht].InTraj) != tmp.end())
continue;
2531 tmp.push_back(tjs.
fHits[iht].InTraj);
2618 if(tjIDs.empty())
return 0;
2619 std::array<int, 2> wireWindow;
2622 constexpr
float NNDelta = 5;
2623 wireWindow[0] = pos[0] - NNDelta;
2624 wireWindow[1] = pos[0] + NNDelta;
2625 timeWindow[0] = pos[1] - NNDelta;
2626 timeWindow[1] = pos[1] + NNDelta;
2628 for(
auto& tjID : tjIDs)
if(tjID <= 0 || tjID > (
int)tjs.
allTraj.size())
return 0;
2634 if(closeHits.empty())
return 0;
2639 for(
auto& iht : closeHits) {
2640 chg += tjs.
fHits[iht].Integral;
2641 if(tjs.
fHits[iht].InTraj == 0)
continue;
2642 if(std::find(tjIDs.begin(), tjIDs.end(), tjs.
fHits[iht].InTraj) != tjIDs.end()) tchg += tjs.
fHits[iht].Integral;
2644 if(chg == 0)
return 0;
2651 float delta, md = 0;
2654 for(
auto& tp : tj.
Pts) {
2655 for(ii = 0; ii < tp.Hits.size(); ++ii) {
2656 if(!tp.UseHit[ii])
continue;
2659 if(delta > md) md = delta;
2669 if(tj.
Pts.empty())
return;
2686 std::reverse(tj.
Pts.begin(), tj.
Pts.end());
2691 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2692 if(tj.
Pts[ipt].Dir[0] != 0) tj.
Pts[ipt].Dir[0] = -tj.
Pts[ipt].Dir[0];
2693 if(tj.
Pts[ipt].Dir[1] != 0) tj.
Pts[ipt].Dir[1] = -tj.
Pts[ipt].Dir[1];
2694 if(tj.
Pts[ipt].Ang > 0) {
2695 tj.
Pts[ipt].Ang -= M_PI;
2697 tj.
Pts[ipt].Ang += M_PI;
2713 unsigned short nvx = Envelope.size();
2714 double angleSum = 0;
2715 for(
unsigned short ii = 0; ii < Envelope.size(); ++ii) {
2716 p1[0] = Envelope[ii][0] - Point[0];
2717 p1[1] = Envelope[ii][1] - Point[1];
2718 p2[0] = Envelope[(ii+1)%nvx][0] - Point[0];
2719 p2[1] = Envelope[(ii+1)%nvx][1] - Point[1];
2722 if(abs(angleSum) < M_PI)
return false;
2731 double den = v1[0] * v1[0] + v1[1] * v1[1];
2732 if(den == 0)
return false;
2746 if(pos1[0] == pos2[0] && pos1[1] == pos2[1])
return;
2747 pos1[0] = pos2[0] - pos1[0];
2748 pos1[1] = pos2[1] - pos1[1];
2749 double sep = sqrt(pos1[0] * pos1[0] + pos1[1] * pos1[1]);
2750 if(sep < 1
E-6)
return;
2752 ptDir[0] = pos1[0] / sep;
2753 ptDir[1] = pos1[1] / sep;
2755 double costh =
DotProd(dir1, ptDir);
2756 if(costh > 1.0 || costh < -1.0)
return;
2757 alongTrans[0] = costh * sep;
2758 double sinth = sqrt(1 - costh * costh);
2759 alongTrans[1] = sinth * sep;
2766 double ang1 = atan2(p1[1], p1[0]);
2767 double ang2 = atan2(p2[1], p2[0]);
2774 constexpr
double twopi = 2 * M_PI;
2775 double dang = Ang1 - Ang2;
2776 while(dang > M_PI) dang -= twopi;
2777 while(dang < -M_PI) dang += twopi;
2784 return std::abs(std::remainder(Ang1 - Ang2, M_PI));
2795 if(tj.
Pts.size() == 0)
return;
2798 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2799 if(tj.
Pts[ipt].Chg != 0) {
2804 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
2805 unsigned short ipt = tj.
Pts.size() - 1 - ii;
2806 if(tj.
Pts[ipt].Chg != 0) {
2818 unsigned short nUsed = 0;
2819 unsigned short nTotHits = 0;
2820 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
2822 nTotHits += tp.
Hits.size();
2823 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
2824 if(tp.
UseHit[ii]) ++nUsed;
2827 if(nTotHits == 0)
return false;
2828 float fracUsed = (float)nUsed / (
float)nTotHits;
2829 if(prt)
mf::LogVerbatim(
"TC")<<
"TrajIsClean: nTotHits "<<nTotHits<<
" nUsed "<<nUsed<<
" fracUsed "<<fracUsed;
2831 if(fracUsed > 0.9)
return true;
2840 if(tjIDs.empty())
return 0;
2843 for(
auto tjid : tjIDs) {
2844 auto& tj = tjs.
allTraj[tjid - 1];
2845 float npts = tj.EndPt[1] - tj.EndPt[0] + 1;
2846 summ += npts * tj.MCSMom;
2849 return (
short)(summ / suml);
2863 if(firstPt == lastPt)
return 0;
2864 if(firstPt > lastPt) std::swap(firstPt, lastPt);
2868 if(firstPt >= lastPt)
return 0;
2870 if(firstPt < tj.
EndPt[0])
return 0;
2871 if(lastPt > tj.
EndPt[1])
return 0;
2878 if(tjLen < 1)
return 0;
2880 double thetaRMS =
MCSThetaRMS(tjs, tj, firstPt, lastPt);
2881 if(thetaRMS < 0.001)
return 999;
2882 double mom = 13.8 * sqrt(tjLen / 14) / thetaRMS;
2883 if(mom > 999) mom = 999;
2892 if(thePt > tj.
EndPt[1])
return thePt;
2893 if(tj.
Pts[thePt].Chg > 0)
return thePt;
2895 short endPt0 = tj.
EndPt[0];
2896 short endPt1 = tj.
EndPt[1];
2897 for(
short off = 1; off < 10; ++off) {
2898 short ipt = thePt + off;
2899 if(ipt <= endPt1 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
2901 if(ipt >= endPt0 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
2914 if(tps < 1)
return 1;
2926 if(firstPt < tj.
EndPt[0])
return 1;
2927 if(lastPt > tj.
EndPt[1])
return 1;
2931 if(firstPt >= lastPt)
return 1;
2935 TjDeltaRMS(tjs, tj, firstPt, lastPt, sigmaS, cnt);
2936 if(sigmaS < 0)
return 1;
2940 unsigned short numPts = lastPt - firstPt - 1;
2942 if(numPts > 5 && cnt < 0.7 * numPts)
return tj.
MCSMom;
2944 if(tjLen < 1)
return 1;
2946 return (6.8 * sigmaS / tjLen);
2956 if(firstPt < tj.
EndPt[0])
return;
2957 if(lastPt > tj.
EndPt[1])
return;
2961 if(firstPt >= lastPt)
return;
2974 for(
unsigned short ipt = firstPt + 1; ipt < lastPt; ++ipt) {
2975 if(tj.
Pts[ipt].Chg == 0)
continue;
2980 rms = sqrt(dsum / (
double)cnt);
3004 unsigned short minMuonLength = 2 * tjs.
Vertex2DCuts[2];
3005 unsigned short minpts = 4;
3006 if(prt)
mf::LogVerbatim(
"TC")<<
"TagDeltaRays: maxSep "<<maxSep<<
" maxMinSep "<<maxMinSep<<
" Mom range "<<minMom<<
" to "<<maxMom<<
" minpts "<<minpts;
3008 for(
unsigned short itj = 0; itj < tjs.
allTraj.size(); ++itj) {
3010 if(muTj.
CTP != inCTP)
continue;
3012 if(muTj.
PDGCode != 13)
continue;
3015 if(muTj.
EndPt[1] - muTj.
EndPt[0] < minMuonLength)
continue;
3016 auto& mtp0 = muTj.
Pts[muTj.
EndPt[0]];
3017 auto& mtp1 = muTj.
Pts[muTj.
EndPt[1]];
3019 for(
unsigned short jtj = 0; jtj < tjs.
allTraj.size(); ++jtj) {
3020 if(jtj == itj)
continue;
3023 if(dtj.
CTP != inCTP)
continue;
3024 if(dtj.
PDGCode == 13)
continue;
3026 if(dtj.
MCSMom < minMom)
continue;
3027 if(dtj.
MCSMom > maxMom)
continue;
3028 if(dtj.
EndPt[1] - dtj.
EndPt[0] < minpts)
continue;
3031 auto& dtp0 = dtj.
Pts[dtj.
EndPt[0]];
3032 auto& dtp1 = dtj.
Pts[dtj.
EndPt[1]];
3034 if(dtp0.Pos[0] < mtp0.Pos[0])
continue;
3035 if(dtp1.Pos[0] > mtp1.Pos[0])
continue;
3037 if(dtp0.Pos[0] > mtp0.Pos[0])
continue;
3038 if(dtp1.Pos[0] < mtp1.Pos[0])
continue;
3041 float doca = maxMinSep;
3042 unsigned short mpt = 0;
3043 unsigned short dpt = 0;
3045 if(doca == maxMinSep)
continue;
3046 auto& dTp = dtj.
Pts[dpt];
3054 bool closeDeltaRay = (doca < 2 && dtj.
MCSMom < 20);
3055 if(!closeDeltaRay && dang > tjs.
KinkCuts[0])
continue;
3058 unsigned short oend = 0;
3061 if(dpt > 0.5 * (dtj.
EndPt[0] + dtj.
EndPt[1])) oend = 1;
3062 auto& farEndTP = dtj.
Pts[dtj.
EndPt[oend]];
3063 float farEndDelta =
PointTrajDOCA(tjs, farEndTP.Pos[0], farEndTP.Pos[1], muTj.
Pts[mpt]);
3065 if(farEndDelta > maxSep)
continue;
3082 if(tjs.
MuonTag[0] < 0)
return;
3084 unsigned short minLen = tjs.
MuonTag[3];
3086 for(
unsigned short itj = 0; itj < tjs.
allTraj.size(); ++itj) {
3089 bool prt = (debugWorkID < 0 && muTj.
WorkID == debugWorkID);
3093 if(muTj.
PDGCode != 13)
continue;
3095 unsigned short nPos = 0;
3096 unsigned short nNeg = 0;
3097 for(
auto& dtj : tjs.
allTraj) {
3098 if(dtj.AlgMod[
kKilled])
continue;
3099 if(dtj.ParentID != muTj.
ID)
continue;
3100 if(dtj.EndPt[1] - dtj.EndPt[0] > minLen)
continue;
3101 if(dtj.StepDir > 0) {
3107 if(nPos == nNeg)
continue;
3129 std::string fcnLabel = inFcnLabel +
".UpTjProp";
3132 for(
auto& tp : tj.
Pts) {
3133 if(tp.Chg <= 0)
continue;
3135 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
3136 if(tp.UseHit[ii])
continue;
3137 unsigned int iht = tp.Hits[ii];
3138 if(tjs.
fHits[iht].InTraj == 0) {
3169 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
3170 auto& tp = tj.
Pts[ipt];
3171 if(tp.Chg <= 0)
continue;
3176 bsum2 += tp.Chg * tp.Chg;
3182 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
3183 if(!tp.UseHit[ii])
continue;
3184 unsigned int iht = tp.Hits[ii];
3185 tpchg += tjs.
fHits[iht].Integral;
3188 vsum2 += tpchg * tpchg;
3191 if(bcnt == 0)
return;
3199 if(arg > 0) tj.
ChgRMS = sqrt(arg / (bcnt - 1));
3201 for(
auto& tp : tj.
Pts) tp.AveChg = tj.
AveChg;
3205 double nWires = tj.
EndPt[1] - tj.
EndPt[0] + 1;
3206 if(nWires < 2)
return;
3211 for(
unsigned short end = 0;
end < 2; ++
end) {
3215 int dw = std::abs(tp.Pos[0] - vx2.Pos[0]);
3227 if(arg > 0) rms = sqrt(arg / (vcnt - 1));
3230 if(rms < 0.1) rms = 0.1;
3234 double defFrac = 1 / vcnt;
3235 rms = defFrac * 0.5 + (1 - defFrac) * rms;
3243 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
3244 auto& tp = tj.
Pts[ipt];
3245 if(tp.Chg <= 0)
continue;
3252 for(
auto& tp : tj.
Pts) tp.AveChg = tj.
AveChg;
3257 for(
auto& tp : tj.
Pts) tp.AveChg = 0;
3259 unsigned short nptsave = tjs.
NPtsAve;
3260 unsigned short minPt = tj.
EndPt[0] + nptsave;
3262 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
3263 unsigned short ipt = tj.
EndPt[1] - ii;
3264 if(ipt < minPt)
break;
3267 for(
unsigned short iii = 0; iii < nptsave; ++iii) {
3268 unsigned short iipt = ipt - iii;
3270 if(iipt == tj.
EndPt[0])
break;
3271 auto& tp = tj.
Pts[iipt];
3272 if(tp.Chg <= 0)
continue;
3277 tj.
Pts[ipt].AveChg = sum / cnt;
3278 lastAve = tj.
Pts[ipt].AveChg;
3282 for(
unsigned short ii = tj.
EndPt[0]; ii <= tj.
EndPt[1]; ++ii) {
3283 unsigned short ipt = tj.
EndPt[1] - ii;
3284 auto& tp = tj.
Pts[ipt];
3285 if(tp.AveChg == 0) {
3286 tp.AveChg = lastAve;
3288 lastAve = tp.AveChg;
3302 if(vx2.
ID == 0)
return;
3305 std::string fcnLabel = inFcnLabel +
".UpVxProp";
3307 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" UpdateTjEnvironment check Tjs attached to vx2 "<<vx2.
ID;
3309 std::vector<int> tjlist;
3310 std::vector<unsigned short> tjends;
3311 if(vx2.
Pos[0] < -0.4)
return;
3312 unsigned int vxWire = std::nearbyint(vx2.
Pos[0]);
3313 unsigned int loWire = vxWire;
3314 unsigned int hiWire = vxWire;
3316 if(tj.AlgMod[
kKilled])
continue;
3317 if(tj.CTP != vx2.
CTP)
continue;
3319 if(tj.AlgMod[
kPhoton])
continue;
3320 for(
unsigned short end = 0;
end < 2; ++
end) {
3321 if(tj.VtxID[
end] != vx2.
ID)
continue;
3322 tjlist.push_back(tj.ID);
3323 tjends.push_back(
end);
3324 if(tj.Pts[tj.EndPt[
end]].Pos[0] < -0.4)
return;
3325 unsigned int endWire = std::nearbyint(tj.Pts[tj.EndPt[
end]].Pos[0]);
3326 if(endWire < loWire) loWire = endWire;
3327 if(endWire > hiWire) hiWire = endWire;
3330 if(tjlist.size() < 2)
return;
3331 if(hiWire < loWire + 1)
return;
3332 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" check Tjs on wires in the range "<<loWire<<
" to "<<hiWire;
3336 std::vector<std::vector<TrajPoint>> wire_tjpt;
3338 std::vector<int> tjids;
3340 unsigned short nwires = hiWire - loWire + 1;
3341 for(
unsigned short itj = 0; itj < tjlist.size(); ++itj) {
3342 auto& tj = tjs.
allTraj[tjlist[itj] - 1];
3343 unsigned short end = tjends[itj];
3344 std::vector<TrajPoint> tjpt(nwires);
3346 for(
unsigned short ii = 0; ii < tj.Pts.size(); ++ii) {
3348 if(end == 0) { ipt = tj.EndPt[0] + ii; }
else { ipt = tj.EndPt[1] - ii; }
3349 if(ipt > tj.Pts.size() - 1)
break;
3351 auto tp = tj.Pts[ipt];
3352 if(tp.Chg <= 0)
continue;
3355 if(tp.Pos[0] < -0.4)
continue;
3356 unsigned int wire = std::nearbyint(tp.Pos[0]);
3357 unsigned short indx = wire - loWire;
3358 if(indx > nwires - 1)
break;
3368 if(ltp.
Dir[0] == 0)
continue;
3369 if(ltp.
Pos[0] < -0.4)
continue;
3370 unsigned int wire = std::nearbyint(ltp.
Pos[0]);
3372 unsigned short indx = wire - loWire;
3374 if(tjpt[indx].Chg == 0) tjpt[indx] = ltp;
3375 double stepSize = std::abs(1/ltp.
Dir[0]);
3376 for(
unsigned short ii = 0; ii < nwires; ++ii) {
3378 for(
unsigned short iwt = 0; iwt < 2; ++iwt) ltp.
Pos[iwt] += ltp.
Dir[iwt] * stepSize;
3379 if(ltp.
Pos[0] < -0.4)
break;
3380 wire = std::nearbyint(ltp.
Pos[0]);
3381 if(wire < loWire || wire > hiWire)
break;
3382 indx = wire - loWire;
3383 if(tjpt[indx].Chg > 0)
continue;
3388 myprt<<fcnLabel<<
" T"<<tj.ID;
3389 for(
auto& tp : tjpt) myprt<<
" "<<
PrintPos(tjs, tp.Pos)<<
"_"<<tp.Step<<
"_"<<(int)tp.Chg;
3391 wire_tjpt.push_back(tjpt);
3392 tjids.push_back(tj.ID);
3396 for(
unsigned short indx = 0; indx < nwires; ++indx) {
3398 unsigned short npts = 0;
3400 unsigned short npwc = 0;
3401 for(
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
3402 if(wire_tjpt[itj][indx].Pos[0] == 0)
continue;
3405 if(wire_tjpt[itj][indx].Chg > 0) ++npwc;
3409 if(npts == 0)
continue;
3411 if(npwc == npts)
continue;
3413 for(
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
3414 if(wire_tjpt[itj][indx].Pos[0] == 0)
continue;
3415 if(wire_tjpt[itj][indx].Chg == 0)
continue;
3416 auto& tj = tjs.
allTraj[tjids[itj] - 1];
3417 unsigned short ipt = wire_tjpt[itj][indx].Step;
3419 tj.NeedsUpdate =
true;
3420 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" Set kEnvOverlap bit on T"<<tj.ID<<
" ipt "<<ipt;
3425 for(
auto tjid : tjids) {
3426 auto& tj = tjs.
allTraj[tjid - 1];
3427 if(!tj.NeedsUpdate)
continue;
3428 if(tj.CTP != vx2.
CTP)
continue;
3454 if(dir[0] == 0 && dir[1] == 0 && dir[2] == 0)
return tp;
3459 Point3_t pos3 = {{100 * dir[0], 100 * dir[1], 100 * dir[2]}};
3461 std::array<double, 2> ori2;
3462 std::array<double, 2> pos2;
3463 std::array<double, 2> dir2;
3471 dir2[0] = pos2[0] - ori2[0];
3472 dir2[1] = pos2[1] - ori2[1];
3474 double norm = sqrt(dir2[0] * dir2[0] + dir2[1] * dir2[1]);
3477 tp.
Ang = atan2(dir2[1], dir2[0]);
3478 tp.
Delta = norm / 100;
3486 norm = sqrt(cs * cs + sn * sn);
3497 (float)tjs.
fHits[toHit].ArtPtr->WireID().Wire, tjs.
fHits[toHit].PeakTime, tCTP, tp);
3505 tp.
Pos[0] = fromWire;
3507 tp.
Dir[0] = toWire - fromWire;
3510 if(norm == 0)
return false;
3520 tpOut.
Pos = fromPos;
3530 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
3549 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
3557 if(tj.
ID == 0)
return 0;
3567 for(
unsigned short xyz = 0; xyz < 2; ++xyz) dir[xyz] = p2[xyz] - p1[xyz];
3568 if(dir[0] == 0 && dir[1] == 0)
return dir;
3569 double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
3586 if(tp.
Hits.empty())
return 0;
3587 float minVal = 9999;
3589 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
3590 bool useit = (hitRequest ==
kAllHits);
3593 if(!useit)
continue;
3594 unsigned int iht = tp.
Hits[ii];
3595 float cv = tjs.
fHits[iht].PeakTime;
3596 float rms = tjs.
fHits[iht].RMS;
3597 float arg = cv - rms;
3598 if(arg < minVal) minVal = arg;
3600 if(arg > maxVal) maxVal = arg;
3602 if(maxVal == 0)
return 0;
3603 return (maxVal - minVal) / 2;
3615 if(hitsInMultiplet.empty())
return 0;
3617 if(hitsInMultiplet.size() == 1)
return tjs.
fHits[hitsInMultiplet[0]].RMS;
3619 float minVal = 9999;
3621 for(
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
3622 unsigned int iht = hitsInMultiplet[ii];
3623 bool useit = (hitRequest ==
kAllHits);
3624 if(hitRequest ==
kUsedHits && tjs.
fHits[iht].InTraj > 0) useit =
true;
3626 if(!useit)
continue;
3627 float cv = tjs.
fHits[iht].PeakTime;
3628 float rms = tjs.
fHits[iht].RMS;
3629 float arg = cv - rms;
3630 if(arg < minVal) minVal = arg;
3632 if(arg > maxVal) maxVal = arg;
3634 if(maxVal == 0)
return 0;
3635 return (maxVal - minVal) / 2;
3650 for(
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
3651 unsigned int iht = hitsInMultiplet[ii];
3652 bool useit = (hitRequest ==
kAllHits);
3653 if(hitRequest ==
kUsedHits && tjs.
fHits[iht].InTraj > 0) useit =
true;
3655 if(!useit)
continue;
3656 float chg = tjs.
fHits[iht].Integral;
3657 pos += chg * tjs.
fHits[iht].PeakTime;
3660 if(sum == 0)
return 0;
3668 if(tj.
Pts.empty())
return 0;
3669 unsigned short nhits = 0;
3670 for(
auto& tp : tj.
Pts) {
3671 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii)
if(tp.UseHit[ii]) ++nhits;
3680 if(tp.
Hits.empty())
return 0;
3684 unsigned short nhits = 0;
3685 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
3687 if(tp.
UseHit[ii]) ++nhits;
3690 if(!tp.
UseHit[ii]) ++nhits;
3699 if(itj > tjs.
allTraj.size() - 1)
return;
3710 if(tjs.
MuonTag[0] <= 0)
return;
3712 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0];
3715 if(npts > 500) isAMuon =
true;
3729 unsigned int cstat = tpcid.
Cryostat;
3730 unsigned int tpc = tpcid.
TPC;
3731 unsigned short nplanes = TPC.
Nplanes();
3736 double local[3] = {0.,0.,0.};
3737 double world[3] = {0.,0.,0.};
3761 std::pair<int, int> flag;
3762 flag.first = -2; flag.second = -2;
3775 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3785 flag.first = -1; flag.second = -1;
3786 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3787 for(
unsigned int wire = 0; wire < tjs.
NumWires[ipl]; ++wire) {
3789 if(!channelStatus.IsGood(chan)) tjs.
WireHitRange[ipl][wire] = flag;
3793 unsigned int lastwire = 0, lastipl = 0;
3794 for(
unsigned int iht = 0; iht < tjs.
fHits.size(); ++iht) {
3795 if(tjs.
fHits[iht].ArtPtr->WireID().Cryostat != cstat)
continue;
3796 if(tjs.
fHits[iht].ArtPtr->WireID().TPC != tpc)
continue;
3797 unsigned short ipl = tjs.
fHits[iht].ArtPtr->WireID().Plane;
3798 unsigned int wire = tjs.
fHits[iht].ArtPtr->WireID().Wire;
3800 mf::LogWarning(
"TC")<<
"FillWireHitRange: Invalid wire number "<<wire<<
" > "<<tjs.
NumWires[ipl] - 1<<
" in plane "<<ipl<<
" Quitting";
3803 if(ipl == lastipl && wire < lastwire) {
3804 mf::LogWarning(
"TC")<<
"FillWireHitRange: Hits are not in increasing wire order. Quitting ";
3819 std::cout<<
"tpc "<<tpc<<
" tjs.UnitsPerTick "<<std::setprecision(3)<<tjs.
UnitsPerTick<<
"\n";
3820 std::cout<<
"Fiducial volume (";
3821 std::cout<<std::fixed<<std::setprecision(1)<<tjs.
XLo<<
" < X < "<<tjs.
XHi<<
") (";
3822 std::cout<<std::fixed<<std::setprecision(1)<<tjs.
YLo<<
" < Y < "<<tjs.
YHi<<
") (";
3823 std::cout<<std::fixed<<std::setprecision(1)<<tjs.
ZLo<<
" < Z < "<<tjs.
ZHi<<
")\n";
3825 for(
unsigned short ipl = 0; ipl < tjs.
NumPlanes; ++ipl) {
3828 unsigned int cnt = 0;
3829 for(
unsigned int wire = 0; wire < tjs.
NumWires[ipl]; ++wire) {
3831 unsigned int firstHit = tjs.
WireHitRange[ipl][wire].first;
3832 unsigned int lastHit = tjs.
WireHitRange[ipl][wire].second;
3834 if(lastHit - firstHit > 100)
continue;
3835 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
3836 if(tjs.
fHits[iht].Multiplicity != 1)
continue;
3837 if(tjs.
fHits[iht].GoodnessOfFit < 0 || tjs.
fHits[iht].GoodnessOfFit > 100)
continue;
3839 if(tjs.
fHits[iht].PeakAmplitude < 1)
continue;
3841 sumRMS += tjs.
fHits[iht].RMS;
3842 sumAmp += tjs.
fHits[iht].PeakAmplitude;
3845 if(cnt < 4)
continue;
3847 sumAmp /= (float)cnt;
3848 if(tjs.
DebugMode) std::cout<<
"Pln "<<ipl<<
" tjs.AveHitRMS "<<tjs.
AveHitRMS[ipl]<<
" Ave PeakAmplitude "<<sumAmp<<
"\n";
3858 for(
unsigned short ipl = 0; ipl < tjs.
NumPlanes; ++ipl) {
3859 for(
unsigned int wire = 0; wire < tjs.
NumWires[ipl]; ++wire) {
3862 unsigned int firstHit = tjs.
WireHitRange[ipl][wire].first;
3863 unsigned int lastHit = tjs.
WireHitRange[ipl][wire].second;
3864 if(lastHit > tjs.
fHits.size()) {
3865 mf::LogWarning(
"TC")<<
"CheckWireHitRange: Invalid lastHit "<<lastHit<<
" > fHits.size "<<tjs.
fHits.size()<<
" in plane "<<ipl;
3868 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
3869 if(tjs.
fHits[iht].ArtPtr->WireID().Plane != ipl) {
3870 mf::LogWarning(
"TC")<<
"CheckWireHitRange: Invalid plane "<<tjs.
fHits[iht].ArtPtr->WireID().Plane<<
" != "<<ipl;
3873 if(tjs.
fHits[iht].ArtPtr->WireID().Wire != wire) {
3874 mf::LogWarning(
"TC")<<
"CheckWireHitRange: Invalid wire "<<tjs.
fHits[iht].ArtPtr->WireID().Wire<<
" != "<<wire<<
" in plane "<<ipl;
3903 if(itj1 > tjs.
allTraj.size() - 1)
return false;
3904 if(itj2 > tjs.
allTraj.size() - 1)
return false;
3913 if(pfp1 != USHRT_MAX || pfp2 != USHRT_MAX) {
3914 if(pfp1 != USHRT_MAX && pfp2 != USHRT_MAX) {
3919 if(pfp1 == USHRT_MAX) std::swap(itj1, itj2);
3940 std::swap(tj1, tj2);
3941 std::swap(tp1e0, tp2e0);
3942 std::swap(tp1e1, tp2e1);
3958 if(tp2e0[0] > tp1e0[0] && tp2e1[0] < tp1e1[0])
return false;
3962 if(tp1e0[0] > tp2e0[0] && tp1e1[0] < tp2e1[0])
return false;
3965 if(tp2e1[0] > tp1e1[0] && tp2e0[0] < tp1e0[0])
return false;
3966 if(tp1e1[0] > tp2e1[0] && tp1e0[0] < tp2e0[0])
return false;
3970 auto& vx = tjs.
vtx[tj1.
VtxID[1] - 1];
3972 if(doPrt)
mf::LogVerbatim(
"TC")<<
"MergeAndStore: Found a good vertex between Tjs "<<tj1.
VtxID[1]<<
" No merging";
3978 if(doPrt)
mf::LogVerbatim(
"TC")<<
"MergeAndStore: You are merging the end of trajectory T"<<tj1.
ID<<
" with a Bragg peak. Not merging\n";
3989 float minSep = 1000;
3990 unsigned short tj2ClosePt = 0;
3995 if(tj2ClosePt > tj2.
EndPt[1])
return false;
4004 std::vector<unsigned int> tj1Hits;
4005 for(
unsigned short ii = 0; ii < tj1.
Pts.size(); ++ii) {
4008 unsigned short ipt = tj1.
Pts.size() - 1 - ii;
4009 tj1Hits.insert(tj1Hits.end(), tj1.
Pts[ipt].Hits.begin(), tj1.
Pts[ipt].Hits.end());
4013 bool bumpedPt =
true;
4016 for(
unsigned short ii = 0; ii < tj2.
Pts[tj2ClosePt].Hits.size(); ++ii) {
4017 unsigned int iht = tj2.
Pts[tj2ClosePt].Hits[ii];
4018 if(std::find(tj1Hits.begin(), tj1Hits.end(), iht) != tj1Hits.end()) bumpedPt =
true;
4020 if(bumpedPt && tj2ClosePt < tj2.
EndPt[1]) {
4029 tj1.
Pts.insert(tj1.
Pts.end(), tj2.
Pts.begin() + tj2ClosePt, tj2.
Pts.end());
4037 mf::LogVerbatim(
"TC")<<
"MergeAndStore found duplicate hits. Coding error";
4044 if(tj2.
VtxID[1] > 0) {
4064 int newTjID = tjs.
allTraj.size();
4073 for(
auto& tj : tjs.
allTraj)
if(tj.ParentID == tj1ID || tj.ParentID == tj2ID) tj.ParentID = newTjID;
4079 std::vector<int>
GetAssns(
const TjStuff& tjs, std::string type1Name,
int id, std::string type2Name)
4084 std::vector<int>
tmp;
4085 if(
id <= 0)
return tmp;
4086 unsigned int uid = id;
4088 if(type1Name ==
"T" && uid <= tjs.
allTraj.size() && type2Name ==
"P") {
4090 for(
auto& pfp : tjs.
pfps) {
4091 if(pfp.ID <= 0)
continue;
4092 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), id) != pfp.TjIDs.end()) tmp.push_back(pfp.ID);
4097 if(type1Name ==
"P" && uid <= tjs.
pfps.size() && (type2Name ==
"2S" || type2Name ==
"3S")) {
4099 auto& pfp = tjs.
pfps[uid - 1];
4101 std::vector<int> ssid;
4102 for(
auto&
ss : tjs.
cots) {
4103 if(
ss.ID <= 0)
continue;
4105 if(!shared.empty() && std::find(ssid.begin(), ssid.end(),
ss.ID) == ssid.end()) ssid.push_back(
ss.ID);
4107 if(type2Name ==
"2S")
return ssid;
4108 for(
auto& ss3 : tjs.
showers) {
4109 if(ss3.ID <= 0)
continue;
4111 if(!shared.empty() && std::find(tmp.begin(), tmp.end(), ss3.ID) == tmp.end()) tmp.push_back(ss3.ID);
4116 if(type1Name ==
"2V" && uid <= tjs.
vtx.size() && type2Name ==
"T" ) {
4119 if(tj.AlgMod[
kKilled])
continue;
4120 for(
unsigned short end = 0;
end < 2; ++
end) {
4121 if(tj.VtxID[
end] !=
id)
continue;
4122 if(std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4128 if(type1Name ==
"3V" && uid <= tjs.
vtx3.size() && type2Name ==
"P") {
4129 for(
auto& pfp : tjs.
pfps) {
4130 if(pfp.ID == 0)
continue;
4131 for(
unsigned short end = 0;
end < 2; ++
end) {
4132 if(pfp.Vx3ID[
end] !=
id)
continue;
4134 if(std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4140 if(type1Name ==
"3V" && uid <= tjs.
vtx3.size() && type2Name ==
"T") {
4143 if(tj.AlgMod[
kKilled])
continue;
4144 for(
unsigned short end = 0;
end < 2; ++
end) {
4145 if(tj.VtxID[
end] > 0 && tj.VtxID[
end] <= tjs.
vtx.size()) {
4146 auto& vx2 = tjs.
vtx[tj.VtxID[
end] - 1];
4147 if(vx2.Vx3ID !=
id)
continue;
4148 if(std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4155 if(type1Name ==
"3V" && uid <= tjs.
vtx3.size() && type2Name ==
"2V") {
4157 for(
auto& vx2 : tjs.
vtx) {
4158 if(vx2.ID == 0)
continue;
4159 if(vx2.Vx3ID ==
id) tmp.push_back(vx2.ID);
4164 if(type1Name ==
"3S" && uid <= tjs.
showers.size() && type2Name ==
"T") {
4166 auto& ss3 = tjs.
showers[uid - 1];
4167 if(ss3.ID == 0)
return tmp;
4168 for(
auto cid : ss3.CotIDs) {
4169 auto&
ss = tjs.
cots[cid - 1];
4170 if(
ss.ID == 0)
continue;
4171 tmp.insert(tmp.end(),
ss.TjIDs.begin(),
ss.TjIDs.end());
4177 if(type1Name ==
"2S" && uid <= tjs.
cots.size() && type2Name ==
"T") {
4179 auto&
ss = tjs.
cots[uid - 1];
4183 if(type1Name ==
"3S" && uid <= tjs.
showers.size() && type2Name ==
"P") {
4185 auto& ss3 = tjs.
showers[uid - 1];
4186 if(ss3.ID == 0)
return tmp;
4187 for(
auto cid : ss3.CotIDs) {
4188 auto&
ss = tjs.
cots[cid - 1];
4189 if(
ss.ID == 0)
continue;
4190 for(
auto tid :
ss.TjIDs) {
4191 auto& tj = tjs.
allTraj[tid - 1];
4192 if(tj.AlgMod[
kKilled])
continue;
4193 if(!tj.AlgMod[
kMat3D])
continue;
4194 for(
auto& pfp : tjs.
pfps) {
4195 if(pfp.ID <= 0)
continue;
4196 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tj.ID) == pfp.TjIDs.end())
continue;
4197 if(std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4204 if(type1Name ==
"T" && uid <= tjs.
allTraj.size() && type2Name ==
"2S") {
4206 for(
auto&
ss : tjs.
cots) {
4207 if(
ss.ID == 0)
continue;
4208 if(std::find(
ss.TjIDs.begin(),
ss.TjIDs.end(), id) !=
ss.TjIDs.end()) tmp.push_back(
ss.ID);
4213 if(type1Name ==
"T" && uid <= tjs.
allTraj.size() && type2Name ==
"3S") {
4215 for(
auto&
ss : tjs.
cots) {
4216 if(
ss.ID == 0)
continue;
4217 if(std::find(
ss.TjIDs.begin(),
ss.TjIDs.end(), id) ==
ss.TjIDs.end())
continue;
4218 if(
ss.SS3ID > 0) tmp.push_back(
ss.SS3ID);
4223 std::cout<<
"GetAssns doesn't know about "<<type1Name<<
" -> "<<type2Name<<
" assns, or id "<<
id<<
" is not valid.\n";
4238 if(!tjs.
vtx3.empty()) {
4240 myprt<<someText<<
"****** 3D vertices ******************************************__2DVtx_ID__*******\n";
4241 myprt<<someText<<
" Vtx Cstat TPC X Y Z XEr YEr ZEr pln0 pln1 pln2 Wire score Prim? Nu? nTru";
4242 myprt<<
" ___________2D_Pos____________ _____Tjs________\n";
4243 for(
unsigned short iv = 0; iv < tjs.
vtx3.size(); ++iv) {
4244 if(tjs.
vtx3[iv].ID == 0)
continue;
4248 myprt<<
std::right<<std::setw(5)<<std::fixed<<vid;
4249 myprt<<std::setprecision(1);
4262 unsigned short nTruMatch = 0;
4263 for(
unsigned short ipl = 0; ipl < tjs.
NumPlanes; ++ipl) {
4264 if(vx3.
Vx2ID[ipl] == 0)
continue;
4265 unsigned short iv2 = vx3.
Vx2ID[ipl] - 1;
4269 myprt<<std::setw(6)<<vx3.
Primary;
4273 for(
unsigned short plane = 0; plane < tjs.
NumPlanes; ++plane) {
4277 if(vx3.
Wire == -2) {
4279 for(
auto& pfp : tjs.
pfps) {
4280 if(pfp.Vx3ID[0] == tjs.
vtx3[iv].ID) {
4281 for(
auto& tjID : pfp.TjIDs) myprt<<
" T"<<tjID;
4283 if(pfp.Vx3ID[1] == tjs.
vtx3[iv].ID) {
4284 for(
auto& tjID : pfp.TjIDs) myprt<<
" T"<<tjID;
4288 auto vxtjs =
GetAssns(tjs,
"3V", vx3.
ID,
"T");
4289 for(
auto tjid : vxtjs) myprt<<
" T"<<tjid;
4294 if(!tjs.
vtx.empty()) {
4295 bool foundOne =
false;
4296 for(
unsigned short iv = 0; iv < tjs.
vtx.size(); ++iv) {
4297 auto& vx2 = tjs.
vtx[iv];
4299 if(vx2.NTraj == 0)
continue;
4304 myprt<<someText<<
"************ 2D vertices ************\n";
4305 myprt<<someText<<
" Vtx CTP wire err tick err ChiDOF NTj Pass Topo ChgFrac Score v3D TjIDs\n";
4306 for(
auto& vx2 : tjs.
vtx) {
4307 if(vx2.ID == 0)
continue;
4311 myprt<<
std::right<<std::setw(5)<<std::fixed<<vid;
4313 myprt<<
std::right<<std::setw(8)<<std::setprecision(0)<<std::nearbyint(vx2.Pos[0]);
4314 myprt<<
std::right<<std::setw(5)<<std::setprecision(1)<<vx2.PosErr[0];
4321 myprt<<
std::right<<std::setw(9)<<std::setprecision(2)<<vx2.TjChgFrac;
4322 myprt<<
std::right<<std::setw(6)<<std::setprecision(1)<<vx2.Score;
4326 for(
unsigned short ii = 0; ii < tjs.
allTraj.size(); ++ii) {
4327 auto const& aTj = tjs.
allTraj[ii];
4329 if(aTj.AlgMod[
kKilled])
continue;
4330 for(
unsigned short end = 0;
end < 2; ++
end) {
4331 if(aTj.VtxID[
end] != (
short)vx2.ID)
continue;
4351 if(itj == USHRT_MAX) {
4353 std::vector<unsigned int>
tmp;
4355 myprt<<someText<<
" ID CTP Pass Pts W:T Ang CS AveQ fnTj W:T Ang CS AveQ fnTj Chg(k) chgRMS Mom SDr __Vtx__ PDG DirFOM Par Pri NuPar TRuPDG E*P TruKE WorkID \n";
4356 for(
unsigned short ii = 0; ii < tjs.
allTraj.size(); ++ii) {
4359 myprt<<someText<<
" ";
4362 myprt<<std::fixed<<std::setw(5)<<tid;
4363 myprt<<std::setw(6)<<aTj.CTP;
4364 myprt<<std::setw(5)<<aTj.Pass;
4366 myprt<<std::setw(5)<<aTj.EndPt[1] - aTj.EndPt[0] + 1;
4367 unsigned short endPt0 = aTj.EndPt[0];
4368 auto& tp0 = aTj.Pts[endPt0];
4370 if(itick < 0) itick = 0;
4371 myprt<<std::setw(6)<<(int)(tp0.Pos[0]+0.5)<<
":"<<itick;
4372 if(itick < 10) { myprt<<
" "; }
4373 if(itick < 100) { myprt<<
" "; }
4374 if(itick < 1000) { myprt<<
" "; }
4375 myprt<<std::setw(6)<<std::setprecision(2)<<tp0.Ang;
4376 myprt<<std::setw(2)<<tp0.AngleCode;
4377 if(aTj.StopFlag[0][
kBragg]) {
4379 }
else if(aTj.StopFlag[0][
kAtVtx]) {
4381 }
else if(aTj.StopFlag[0][
kAtKink]) {
4383 }
else if(aTj.StopFlag[0][
kAtTj]) {
4388 myprt<<std::setw(5)<<(int)tp0.AveChg;
4392 unsigned short midPt = 0.5 * (aTj.EndPt[0] + aTj.EndPt[1]);
4393 for(
unsigned short ipt = aTj.EndPt[0]; ipt < midPt; ++ipt) {
4394 auto& tp = aTj.Pts[ipt];
4399 if(cnt > 0) frac /= cnt;
4400 myprt<<std::setw(5)<<std::setprecision(1)<<frac;
4406 unsigned short endPt1 = aTj.EndPt[1];
4407 auto& tp1 = aTj.Pts[endPt1];
4409 myprt<<std::setw(6)<<(int)(tp1.Pos[0]+0.5)<<
":"<<itick;
4410 if(itick < 10) { myprt<<
" "; }
4411 if(itick < 100) { myprt<<
" "; }
4412 if(itick < 1000) { myprt<<
" "; }
4413 myprt<<std::setw(6)<<std::setprecision(2)<<tp1.Ang;
4414 myprt<<std::setw(2)<<tp1.AngleCode;
4415 if(aTj.StopFlag[1][
kBragg]) {
4417 }
else if(aTj.StopFlag[1][
kAtVtx]) {
4422 myprt<<std::setw(5)<<(int)tp1.AveChg;
4426 for(
unsigned short ipt = midPt; ipt <= aTj.EndPt[1]; ++ipt) {
4427 auto& tp = aTj.Pts[ipt];
4432 if(cnt > 0) frac /= cnt;
4433 myprt<<std::setw(5)<<std::setprecision(1)<<frac;
4439 myprt<<std::setw(7)<<std::setprecision(1)<<aTj.TotChg/1000;
4440 myprt<<std::setw(7)<<std::setprecision(2)<<aTj.ChgRMS;
4441 myprt<<std::setw(5)<<aTj.MCSMom;
4442 myprt<<std::setw(4)<<aTj.StepDir;
4443 myprt<<std::setw(4)<<aTj.VtxID[0];
4444 myprt<<std::setw(4)<<aTj.VtxID[1];
4445 myprt<<std::setw(5)<<aTj.PDGCode;
4446 myprt<<std::setw(7)<<std::setprecision(1)<<aTj.DirFOM;
4447 myprt<<std::setw(5)<<aTj.ParentID;
4448 myprt<<std::setw(5)<<
PrimaryID(tjs, aTj);
4452 if(aTj.MCPartListIndex < tjs.
MCPartList.size()) {
4453 auto& mcp = tjs.
MCPartList[aTj.MCPartListIndex];
4454 truKE = 1000 * (mcp->E() - mcp->Mass());
4455 pdg = mcp->PdgCode();
4457 myprt<<std::setw(6)<<pdg;
4458 myprt<<std::setw(6)<<std::setprecision(2)<<aTj.EffPur;
4459 myprt<<std::setw(5)<<truKE;
4460 myprt<<std::setw(7)<<aTj.WorkID;
4461 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(aTj.AlgMod[ib]) myprt<<
" "<<
AlgBitNames[ib];
4467 if(itj > tjs.
allTraj.size()-1)
return;
4469 auto const& aTj = tjs.
allTraj[itj];
4471 mf::LogVerbatim(
"TC")<<
"Print tjs.allTraj["<<itj<<
"]: ClusterIndex "<<aTj.ClusterIndex<<
" Vtx[0] "<<aTj.VtxID[0]<<
" Vtx[1] "<<aTj.VtxID[1];
4473 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(aTj.AlgMod[ib]) myprt<<
" "<<
AlgBitNames[ib];
4477 if(ipt == USHRT_MAX) {
4479 for(
unsigned short ii = 0; ii < aTj.Pts.size(); ++ii)
PrintTrajPoint(someText, tjs, ii, aTj.
StepDir, aTj.Pass, aTj.Pts[ii]);
4495 if(tPoint == USHRT_MAX) {
4498 myprt<<someText<<
" ";
4499 myprt<<
"Work: ID "<<tj.
ID<<
" CTP "<<tj.
CTP<<
" StepDir "<<tj.
StepDir<<
" PDG "<<tj.
PDGCode<<
" TruPDG "<<trupdg<<
" tjs.vtx "<<tj.
VtxID[0]<<
" "<<tj.
VtxID[1]<<
" nPts "<<tj.
Pts.size()<<
" EndPts "<<tj.
EndPt[0]<<
" "<<tj.
EndPt[1];
4500 myprt<<
" MCSMom "<<tj.
MCSMom;
4502 myprt<<
" AlgMod names:";
4506 myprt<<someText<<
" ";
4507 myprt<<
"tjs.allTraj: ID "<<tj.
ID<<
" WorkID "<<tj.
WorkID<<
" StepDir "<<tj.
StepDir<<
" PDG "<<tj.
PDGCode<<
" TruPDG "<<trupdg<<
" tjs.vtx "<<tj.
VtxID[0]<<
" "<<tj.
VtxID[1]<<
" nPts "<<tj.
Pts.size()<<
" EndPts "<<tj.
EndPt[0]<<
" "<<tj.
EndPt[1];
4508 myprt<<
" MCSMom "<<tj.
MCSMom;
4510 myprt<<
" AlgMod names:";
4517 for(
unsigned short ic = 0; ic < tjs.
cots.size(); ++ic) {
4518 if(tjs.
cots[ic].TjIDs.empty())
continue;
4520 if(tjs.
cots[ic].ShowerTjID != tj.
ID)
continue;
4523 myprt<<
"cots index "<<ic<<
" ";
4524 myprt<<someText<<
" Envelope";
4530 myprt<<
" Energy "<<(int)ss.
Energy;
4532 myprt<<
"\nInShower TjIDs";
4533 for(
auto& tjID : ss.
TjIDs) {
4544 myprt<<
"Angle "<<std::fixed<<std::setprecision(2)<<ss.
Angle<<
" +/- "<<ss.
AngleErr;
4545 myprt<<
" AspectRatio "<<std::fixed<<std::setprecision(2)<<ss.
AspectRatio;
4546 myprt<<
" DirectionFOM "<<std::fixed<<std::setprecision(2)<<ss.
DirectionFOM;
4550 myprt<<
" No parent";
4553 if(ss.
NeedsUpdate) myprt<<
"*********** This shower needs to be updated ***********";
4554 myprt<<
"................................................";
4559 if(tPoint > tj.
Pts.size() -1) {
4560 mf::LogVerbatim(
"TC")<<
"Can't print non-existent traj point "<<tPoint;
4570 mf::LogVerbatim(
"TC")<<someText<<
" TRP CTP Ind Stp W:Tick Delta RMS Ang C Err Dir0 Dir1 Q AveQ Pull FitChi NTPF Hits ";
4577 myprt<<someText<<
" TRP"<<std::fixed;
4579 if(dir > 0) { myprt<<
"+"; }
else { myprt<<
"-"; }
4580 myprt<<std::setw(6)<<tp.
CTP;
4581 myprt<<std::setw(5)<<ipt;
4582 myprt<<std::setw(5)<<tp.
Step;
4583 myprt<<std::setw(7)<<std::setprecision(1)<<tp.
Pos[0]<<
":"<<tp.
Pos[1]/tjs.
UnitsPerTick;
4584 if(tp.
Pos[1] < 10) { myprt<<
" "; }
4585 if(tp.
Pos[1] < 100) { myprt<<
" "; }
4586 if(tp.
Pos[1] < 1000) { myprt<<
" "; }
4587 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Delta;
4588 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
DeltaRMS;
4589 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Ang;
4591 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
AngErr;
4592 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Dir[0];
4593 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Dir[1];
4594 myprt<<std::setw(7)<<(int)tp.
Chg;
4595 myprt<<std::setw(8)<<(int)tp.
AveChg;
4596 myprt<<std::setw(6)<<std::setprecision(1)<<tp.
ChgPull;
4597 myprt<<std::setw(7)<<tp.
FitChi;
4598 myprt<<std::setw(6)<<tp.
NTPsFit;
4600 if(tp.
Hits.size() > 16) {
4602 myprt<<
" "<<tp.
Hits.size()<<
" shower hits";
4604 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
4605 unsigned int iht = tp.
Hits[ii];
4606 myprt<<
" "<<tjs.
fHits[iht].ArtPtr->WireID().Wire<<
":"<<(int)tjs.
fHits[iht].PeakTime;
4613 myprt<<tjs.
fHits[iht].InTraj;
4625 myprt<<
" PFP sVx ________sPos_______ CS _______sDir______ ____sdEdx_____ eVx ________ePos_______ CS _______eDir______ ____edEdx____ Len nTp3 MCSMom ShLike? PDG mcpIndx Par Prim E*P\n";
4629 myprt<<std::setw(5)<<pid;
4631 for(
unsigned short startend = 0; startend < 2; ++startend) {
4632 myprt<<std::setw(4)<<pfp.
Vx3ID[startend];
4633 myprt<<std::fixed<<
std::right<<std::setprecision(1);
4634 myprt<<std::setw(7)<<pfp.
XYZ[startend][0];
4635 myprt<<std::setw(7)<<pfp.
XYZ[startend][1];
4636 myprt<<std::setw(7)<<pfp.
XYZ[startend][2];
4643 myprt<<std::fixed<<
std::right<<std::setprecision(2);
4644 myprt<<std::setw(6)<<pfp.
Dir[startend][0];
4645 myprt<<std::setw(6)<<pfp.
Dir[startend][1];
4646 myprt<<std::setw(6)<<pfp.
Dir[startend][2];
4647 for(
auto& dedx : pfp.
dEdx[startend]) {
4649 myprt<<std::setw(5)<<std::setprecision(1)<<dedx;
4651 myprt<<std::setw(5)<<std::setprecision(0)<<dedx;
4654 if (pfp.
dEdx[startend].size()<3){
4655 for(
size_t i = 0; i<3-pfp.
dEdx[startend].size(); ++i){
4656 myprt<<std::setw(6)<<
' ';
4664 myprt<<std::setw(5)<<std::setprecision(1)<<
length;
4666 myprt<<std::setw(5)<<std::setprecision(0)<<
length;
4668 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
Tp3s.size();
4671 myprt<<std::setw(5)<<pfp.
PDGCode;
4678 myprt<<std::setw(5)<<
PrimaryID(tjs, pfp);
4679 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
EffPur;
4680 if(!pfp.
TjIDs.empty()) {
4681 for(
auto& tjID : pfp.
TjIDs) myprt<<
" T"<<tjID;
4683 if(!pfp.
DtrIDs.empty()) {
4685 for(
auto& dtrID : pfp.
DtrIDs) myprt<<
" P"<<dtrID;
4692 if(tjs.
pfps.empty())
return;
4696 myprt<<
" PFP sVx ________sPos_______ ______sDir______ ______sdEdx_____ eVx ________ePos_______ ______eDir______ ______edEdx_____ BstPln PDG TruPDG Par Prim E*P\n";
4697 bool printHeader =
true;
4698 for(
auto& pfp : tjs.
pfps) {
4700 PrintPFP(someText, tjs, pfp, printHeader);
4701 printHeader =
false;
4709 if(end > 1)
return "Invalid end";
4712 for(
unsigned short ib = 0; ib <
StopFlagNames.size(); ++ib) {
4746 unsigned int wire = 0;
4747 if(pos[0] > -0.4) wire = std::nearbyint(pos[0]);
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
float AveChg
Calculated using ALL hits.
unsigned short MatchVecIndex(const TjStuff &tjs, int tjID)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Point2_t dEdx
dE/dx for 3D matched trajectories
std::array< std::vector< float >, 2 > dEdxErr
Functions to help with numbers.
std::vector< float > Vertex2DCuts
Max position pull, max Position error rms.
void ChkChgAsymmetry(TjStuff &tjs, Trajectory &tj, bool prt)
float TPHitsRMSTime(TjStuff &tjs, TrajPoint &tp, HitStatus_t hitRequest)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
struct of temporary 2D vertices (end points)
void PrintTrajectory(std::string someText, const TjStuff &tjs, const Trajectory &tj, unsigned short tPoint)
int PrimaryID(const TjStuff &tjs, const PFPStruct &pfp)
float OverlapFraction(TjStuff &tjs, const Trajectory &tj1, const Trajectory &tj2)
const std::vector< std::string > AlgBitNames
CTP_t CTP
Cryostat, TPC, Plane code.
float HitSep2(TjStuff &tjs, unsigned int iht, unsigned int jht)
art::Ptr< recob::Hit > ArtPtr
std::vector< int > NearTjIDs
std::array< double, 3 > Point3_t
std::bitset< 64 > AlgMod
Bit set if algorithm AlgBit_t modifed the trajectory.
void UpdateVxEnvironment(std::string inFcnLabel, TjStuff &tjs, VtxStore &vx2, bool prt)
float PosSep(const Point2_t &pos1, const Point2_t &pos2)
void RestoreObsoleteTrajectory(TjStuff &tjs, unsigned int itj)
std::vector< Point2_t > Envelope
void PrintAllTraj(std::string someText, const TjStuff &tjs, const DebugStuff &debug, unsigned short itj, unsigned short ipt, bool prtVtx)
bool HasDuplicateHits(TjStuff const &tjs, Trajectory const &tj, bool prt)
geo::WireID WireID() const
Initial tdc tick for hit.
unsigned int Nplanes() const
Number of planes in this tpc.
std::vector< unsigned int > PutTrajHitsInVector(Trajectory const &tj, HitStatus_t hitRequest)
void TagJunkTj(TjStuff const &tjs, Trajectory &tj, bool prt)
vertex position fixed manually - no fitting done
std::vector< float > AveHitRMS
average RMS of an isolated hit
unsigned short NearestPtWithChg(TjStuff &tjs, Trajectory &tj, unsigned short thePt)
unsigned short PDGCodeIndex(TjStuff &tjs, int PDGCode)
std::vector< float > MaxPos1
float TpSumHitChg(TjStuff &tjs, TrajPoint const &tp)
unsigned short NumDeltaRays(const TjStuff &tjs, std::vector< int > &tjIDs)
std::array< std::bitset< 8 >, 2 > StopFlag
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
std::vector< PFPStruct > pfps
int ParentID
ID of the parent, or the ID of the Tj this one was merged with if it is killed.
std::vector< unsigned int > Hits
float TotChg
Total including an estimate for dead wires.
float DeadWireCount(const TjStuff &tjs, const float &inWirePos1, const float &inWirePos2, CTP_t tCTP)
void FindAlongTrans(Point2_t pos1, Vector2_t dir1, Point2_t pos2, Point2_t &alongTrans)
unsigned short FarEnd(const TjStuff &tjs, const Trajectory &tj, const Point2_t &pos)
float HitsRMSTime(TjStuff &tjs, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
float HitsRMSTick(TjStuff &tjs, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
CryostatID_t Cryostat
Index of cryostat.
void TrimEndPts(std::string fcnLabel, TjStuff &tjs, Trajectory &tj, const std::vector< float > &fQualityCuts, bool prt)
bool TrajClosestApproach(Trajectory const &tj, float x, float y, unsigned short &closePt, float &DOCA)
float TrajPointSeparation(TrajPoint &tp1, TrajPoint &tp2)
WireID_t Wire
Index of the wire within its plane.
std::vector< ShowerStruct3D > showers
void FitTraj(TjStuff &tjs, Trajectory &tj, unsigned short originPt, unsigned short npts, short fitDir, TrajPoint &tpFit)
void SetAngleCode(TjStuff &tjs, TrajPoint &tp)
bool SetMag(Vector2_t &v1, double mag)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned short NumPtsWithCharge(const TjStuff &tjs, const Trajectory &tj, bool includeDeadWires, unsigned short firstPt, unsigned short lastPt)
std::array< std::bitset< 8 >, 2 > StopFlag
bool MergeTjIntoPFP(TjStuff &tjs, int mtjid, PFPStruct &pfp, bool prt)
std::array< int, 2 > Vx3ID
std::array< double, 2 > Dir
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
void MergeGhostTjs(TjStuff &tjs, CTP_t inCTP)
bool MakeBareTrajPoint(const TjStuff &tjs, const TrajPoint &tpIn1, const TrajPoint &tpIn2, TrajPoint &tpOut)
std::vector< TrajPoint3 > Tp3s
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
double DeltaAngle2(double Ang1, double Ang2)
std::vector< T > SetIntersection(const std::vector< T > &set1, const std::vector< T > &set2)
bool SignalAtTp(TjStuff &tjs, const TrajPoint &tp)
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
unsigned short Pass
the pass on which it was created
void TagDeltaRays(TjStuff &tjs, const CTP_t &inCTP)
void CheckTrajBeginChg(TjStuff &tjs, unsigned short itj, bool prt)
bool TrajIsClean(TjStuff &tjs, Trajectory &tj, bool prt)
void ReleaseHits(TjStuff &tjs, Trajectory &tj)
void ReverseTraj(TjStuff &tjs, Trajectory &tj)
bool IsShowerLike(const TjStuff &tjs, const std::vector< int > TjIDs)
float ChgFracBetween(TjStuff &tjs, TrajPoint tp, float toPos0, bool prt)
tagged as a vertex between Tjs that are matched to MC truth neutrino interaction particles ...
unsigned int Hit
set to the hit index in fHits if a Plane:Wire:Tick match is found
std::vector< ShowerStruct > cots
struct of temporary 3D vertices
bool CompatibleMerge(TjStuff &tjs, const Trajectory &tj1, const Trajectory &tj2, bool prt)
bool CheckWireHitRange(const TjStuff &tjs)
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
bool MakeVertexObsolete(TjStuff &tjs, VtxStore &vx2, bool forceKill)
std::array< float, 2 > Point2_t
int PDGCodeVote(TjStuff &tjs, std::vector< int > &tjIDs, bool prt)
std::array< Point3_t, 2 > XYZ
const geo::GeometryCore * geom
float PointTrajDOCA2(TjStuff const &tjs, float wire, float time, TrajPoint const &tp)
CTP_t CTP
Cryostat, TPC, Plane code.
float HitsPosTime(TjStuff &tjs, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
void UpdateTjChgProperties(std::string inFcnLabel, TjStuff &tjs, Trajectory &tj, bool prt)
std::vector< unsigned int > LastWire
the last wire with a hit
std::array< Vector3_t, 2 > DirErr
std::vector< VtxStore > vtx
2D vertices
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
const std::vector< std::string > StopFlagNames
void UpdateMatchStructs(TjStuff &tjs, int oldTj, int newTj)
std::vector< TrajPoint > Pts
Trajectory points.
short MCSMom(TjStuff &tjs, Trajectory &tj, unsigned short firstPt, unsigned short lastPt)
TrajPoint MakeBareTP(TjStuff &tjs, Point3_t &pos, Vector3_t &dir, CTP_t inCTP)
virtual double Temperature() const =0
bool TrajTrajDOCA(const TjStuff &tjs, const Trajectory &tj1, const Trajectory &tj2, unsigned short &ipt1, unsigned short &ipt2, float &minSep, bool considerDeadWires)
std::array< Vector3_t, 2 > Dir
float MaxTjLen(TjStuff const &tjs, std::vector< int > &tjIDs)
unsigned short CloseEnd(TjStuff &tjs, const Trajectory &tj, const Point2_t &pos)
std::vector< int > FindCloseTjs(const TjStuff &tjs, const TrajPoint &fromTp, const TrajPoint &toTp, const float &maxDelta)
float TrajLength(Trajectory &tj)
std::vector< Trajectory > allTraj
vector of all trajectories in each plane
std::bitset< 64 > UseAlg
Allow user to mask off specific algorithms.
std::array< unsigned short, 2 > EndPt
First and last point in the trajectory that has charge.
unsigned short PDGCode
shower-like or track-like {default is track-like}
bool PointInsideEnvelope(const Point2_t &Point, const std::vector< Point2_t > &Envelope)
std::vector< float > MaxPos0
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
void DefineTjParents(TjStuff &tjs, const geo::TPCID &tpcid, bool prt)
std::vector< unsigned int > FirstWire
the first wire with a hit
std::vector< MatchStruct > matchVec
3D matching vector
bool TestBeam
Expect tracks entering from the front face. Don't create neutrino PFParticles.
std::string PrintHit(const TCHit &hit)
float UnitsPerTick
scale factor from Tick to WSE equivalent units
virtual unsigned int NumberTimeSamples() const =0
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
float EffPur
Efficiency * Purity.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
std::array< double, 2 > Vector2_t
unsigned short NumHitsInTP(const TrajPoint &tp, HitStatus_t hitRequest)
void TagMuonDirections(TjStuff &tjs, short debugWorkID)
std::vector< int > GetVtxTjIDs(const TjStuff &tjs, const VtxStore &vx2)
std::array< unsigned short, 2 > VtxID
ID of 2D vertex.
Detector simulation of raw signals on wires.
void TjDeltaRMS(TjStuff &tjs, Trajectory &tj, unsigned short firstPt, unsigned short lastPt, double &rms, unsigned short &cnt)
void WatchHit(std::string someText, TjStuff &tjs, const unsigned int &wHit, short &wInTraj, const unsigned short &tjID)
std::vector< int > DtrIDs
float PosSep2(const Point2_t &pos1, const Point2_t &pos2)
std::vector< Vtx3Store > vtx3
3D vertices
float ChgFracNearPos(TjStuff &tjs, const Point2_t &pos, const std::vector< int > &tjIDs)
float TwoTPAngle(TrajPoint &tp1, TrajPoint &tp2)
bool MergeShowerTjsAndStore(TjStuff &tjs, unsigned short istj, unsigned short jstj, bool prt)
unsigned int MCPartListIndex
std::bitset< 16 > Stat
Vertex status bits using kVtxBit_t.
std::array< int, 3 > Vx2ID
int Tick
Select hit PeakTime for debugging (< 0 for vertex finding)
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
const std::vector< std::string > VtxBitNames
std::vector< short > MuonTag
min length and min MCSMom for a muon tag
float PointTrajDOCA(TjStuff const &tjs, float wire, float time, TrajPoint const &tp)
std::string PrintPos(const TjStuff &tjs, const Point2_t &pos)
double DotProd(const Vector3_t &v1, const Vector3_t &v2)
bool InTrajOK(TjStuff &tjs, std::string someText)
std::vector< std::vector< std::pair< int, int > > > WireHitRange
int NeutrinoPrimaryTjID(const TjStuff &tjs, const Trajectory &tj)
bool FillWireHitRange(TjStuff &tjs, const geo::TPCID &tpcid)
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
std::vector< TCHit > fHits
unsigned int MCPartListIndex
PFPStruct CreatePFP(const TjStuff &tjs, const geo::TPCID &tpcid)
std::string PrintHitShort(const TCHit &hit)
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
short StepDir
-1 = going US (-> small wire#), 1 = going DS (-> large wire#)
geo::PlaneID DecodeCTP(CTP_t CTP)
std::vector< float > Match3DCuts
3D matching cuts
float ExpectedHitsRMS(TjStuff &tjs, const TrajPoint &tp)
void Reverse3DMatchTjs(TjStuff &tjs, PFPStruct &pfp, bool prt)
Vector2_t PointDirection(const Point2_t p1, const Point2_t p2)
bool SplitTraj(TjStuff &tjs, unsigned short itj, unsigned short pos, unsigned short ivx, bool prt)
float MaxChargeAsymmetry(TjStuff &tjs, std::vector< int > &tjIDs)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SetVx2Score(TjStuff &tjs, bool prt)
void SetEndPoints(TjStuff &tjs, Trajectory &tj)
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
std::vector< simb::MCParticle * > MCPartList
bool MergeAndStore(TjStuff &tjs, unsigned int itj1, unsigned int itj2, bool doPrt)
float PointTrajSep2(float wire, float time, TrajPoint const &tp)
std::array< double, 3 > Vector3_t
bool SignalBetween(TjStuff &tjs, TrajPoint tp, float toPos0, const float &MinWireSignalFraction, bool prt)
float MaxHitDelta(TjStuff &tjs, Trajectory &tj)
bool WireHitRangeOK(const TjStuff &tjs, const CTP_t &inCTP)
std::array< std::vector< float >, 2 > dEdx
unsigned short AngleRange(TjStuff &tjs, float angle)
void PosInPlane(const TjStuff &tjs, const Vtx3Store &vx3, unsigned short plane, Point2_t &pos)
unsigned short GetPFPIndex(const TjStuff &tjs, int tjID)
std::string PrintStopFlag(const Trajectory &tj, unsigned short end)
std::vector< short > DeltaRayTag
min length, min MCSMom and min separation (WSE) for a delta ray tag
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void MakeTrajectoryObsolete(TjStuff &tjs, unsigned int itj)
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
float TjDirFOM(const TjStuff &tjs, const Trajectory &tj, bool prt)
void PrintPFP(std::string someText, const TjStuff &tjs, const PFPStruct &pfp, bool printHeader)
void PrintPFPs(std::string someText, const TjStuff &tjs)
void UnsetUsedHits(TjStuff &tjs, TrajPoint &tp)
bool FindCloseHits(TjStuff const &tjs, TrajPoint &tp, float const &maxDelta, HitStatus_t hitRequest)
std::vector< float > AngleRanges
list of max angles for each angle range
float HitsPosTick(TjStuff &tjs, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
void MoveTPToWire(TrajPoint &tp, float wire)
bool StoreVertex(TjStuff &tjs, VtxStore &vx)
std::vector< float > KinkCuts
kink angle, nPts fit, (alternate) kink angle significance
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
void TrajIntersection(TrajPoint const &tp1, TrajPoint const &tp2, float &x, float &y)
bool StoreTraj(TjStuff &tjs, Trajectory &tj)
float TPHitsRMSTick(TjStuff &tjs, TrajPoint &tp, HitStatus_t hitRequest)
bool valIncreasing(SortEntry c1, SortEntry c2)
void PrintTrajPoint(std::string someText, const TjStuff &tjs, unsigned short ipt, short dir, unsigned short pass, TrajPoint const &tp)
double DeltaAngle(double Ang1, double Ang2)
void PrintHeader(std::string someText)
bool NeedsUpdate
Set true when the Tj needs to be updated (only for the TP Environment right now)
void TrajPointTrajDOCA(TjStuff &tjs, TrajPoint const &tp, Trajectory const &tj, unsigned short &closePt, float &minSep)
bool StorePFP(TjStuff &tjs, PFPStruct &pfp)
bool TrajHitsOK(TjStuff &tjs, const unsigned int iht, const unsigned int jht)
double MCSThetaRMS(TjStuff &tjs, Trajectory &tj, unsigned short firstPt, unsigned short lastPt)
bool DebugMode
print additional info when in debug mode
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
std::vector< int > GetAssns(const TjStuff &tjs, std::string type1Name, int id, std::string type2Name)
std::vector< unsigned int > NumWires
bool valDecreasing(SortEntry c1, SortEntry c2)
short StepDir
the normal user-defined stepping direction = 1 (US -> DS) or -1 (DS -> US)
CTP_t CTP
set to an invalid CTP
constexpr Point origin()
Returns a origin position with a point of the specified type.
unsigned short NumUsedHitsInTj(const TjStuff &tjs, const Trajectory &tj)
void SetPDGCode(TjStuff &tjs, Trajectory &tj)
float DirFOM
Normalized RMS using ALL hits. Assume it is 50% to start.
const detinfo::DetectorProperties * detprop