4 #include <boost/algorithm/string/classification.hpp> 5 #include <boost/algorithm/string/split.hpp> 33 std::vector<int> dtrs;
34 for(
auto& dtj : slc.
tjs) {
35 if(dtj.AlgMod[
kKilled])
continue;
36 if(dtj.ParentID != muTj.
ID)
continue;
37 dtrs.push_back(dtj.ID);
39 if(prt) std::cout<<
"MakeHaloTj: Killing delta-ray T"<<dtj.ID<<
"\n";
43 if(pfpIndex == USHRT_MAX) {
44 if(prt) std::cout<<
" No PFP found for 3D-matched delta-ray\n";
46 auto& pfp = slc.
pfps[pfpIndex];
47 if(prt) std::cout<<
" Killing delta-ray PFParticle P"<<pfp.UID<<
"\n";
50 if(pfp.ParentUID > 0) {
52 if(parentIndx.first != USHRT_MAX) {
53 auto& parent =
slices[parentIndx.first].pfps[parentIndx.second];
54 std::vector<int> newDtrUIDs;
55 for(
auto uid : parent.DtrUIDs)
if(uid != dtj.UID) newDtrUIDs.push_back(uid);
56 parent.DtrUIDs = newDtrUIDs;
68 tj.
ID = slc.
tjs.size() + 1;
84 std::vector<int> closeTjs;
85 for(
unsigned short ipt = muTj.
EndPt[0]; ipt <= muTj.
EndPt[1]; ++ipt) {
86 auto tp = muTj.
Pts[ipt];
89 tp.Chg = 0; tp.AveChg = 0; tp.ChgPull = 0;
90 tp.Delta = 0; tp.DeltaRMS = 0;
91 tp.FitChi = 0; tp.NTPsFit = 0;
93 if(tp.Dir[0] != 0) window *= std::abs(1/tp.Dir[0]);
96 bool hitsAdded =
false;
97 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
98 unsigned int iht = tp.Hits[ii];
99 auto inTraj = slc.
slHits[iht].InTraj;
100 if(inTraj < 0)
continue;
102 tp.UseHit[ii] =
true;
107 if(inTraj != muTj.
ID && std::find(closeTjs.begin(), closeTjs.end(), inTraj) == closeTjs.end()) closeTjs.push_back(inTraj);
112 tp.Delta =
PointTrajDOCA(slc, tp.HitPos[0], tp.HitPos[1], tp);
114 tj.
Pts.push_back(tp);
117 if(tj.
Pts.empty())
return;
120 std::cout<<
"MHTj: T"<<muTj.
ID<<
" npts "<<tj.
Pts.size()<<
" close";
121 for(
auto tid : closeTjs) std::cout<<
" T"<<tid;
125 slc.
tjs.push_back(tj);
162 for(
auto& tj : slc.
tjs) {
163 if(tj.AlgMod[
kKilled])
continue;
170 std::vector<int> temp;
171 for(
auto& vx3 : slc.
vtx3s) {
172 if(vx3.ID == 0)
continue;
175 temp.push_back(vx3.ID);
177 if(temp.empty())
return;
180 std::vector<int> masterlist;
181 for(
auto vx3id : temp) {
182 auto& vx3 = slc.
vtx3s[vx3id - 1];
185 for(
auto tjid : tjlist) {
187 auto& tj = slc.
tjs[tjid - 1];
188 if(tj.ParentID != 0) {
192 if(std::find(masterlist.begin(), masterlist.end(), tjid) == masterlist.end()) masterlist.push_back(tjid);
197 myprt<<
"DTP: masterlist Tjs";
198 for(
auto tjid : masterlist) myprt<<
" "<<tjid;
202 std::vector<SortEntry> sortVec(temp.size());
203 for(
unsigned short indx = 0; indx < temp.size(); ++indx) {
204 auto& vx3 = slc.
vtx3s[temp[indx] - 1];
205 sortVec[indx].index = indx;
206 sortVec[indx].val = vx3.Score;
208 if(sortVec.size() > 1) std::sort(sortVec.begin(), sortVec.end(),
valDecreasing);
211 for(
unsigned short indx = 0; indx < temp.size(); ++indx) vlist[indx] = temp[sortVec[indx].
index];
215 auto& vx3 = slc.
vtx3s[vlist[0] - 1];
221 neutrinoPFP.XYZ[1][0] = vx3.X;
222 neutrinoPFP.XYZ[1][1] = vx3.Y;
223 neutrinoPFP.XYZ[1][2] = vx3.Z;
224 neutrinoPFP.XYZ[0] = neutrinoPFP.XYZ[1];
225 neutrinoPFP.Dir[1][2] = 1;
226 neutrinoPFP.Dir[0][2] = 1;
228 neutrinoPFP.PDGCode = 14;
229 neutrinoPFP.Vx3ID[1] = vx3.ID;
230 neutrinoPFP.Vx3ID[0] = vx3.ID;
231 neutrinoPFP.NeedsUpdate =
false;
233 if(!
StorePFP(slc, neutrinoPFP))
return;
237 std::vector<bool> lookedAt3(slc.
vtx3s.size() + 1,
false);
238 std::vector<bool> lookedAt2(slc.
vtxs.size() + 1,
false);
240 std::vector<std::pair<int, int>> pardtr;
242 for(
unsigned short indx = 0; indx < vlist.size(); ++indx) {
243 auto& vx3 = slc.
vtx3s[vlist[indx] - 1];
244 if(lookedAt3[vx3.ID])
continue;
246 lookedAt3[vx3.ID] =
true;
250 if(primTjList.empty())
continue;
252 for(
auto primTjID : primTjList) {
253 auto& primTj = slc.
tjs[primTjID - 1];
255 if(primTj.ParentID != -1)
continue;
256 if(prt)
mf::LogVerbatim(
"TC")<<
"Vx3 "<<vx3.ID<<
" Primary tj "<<primTj.ID;
261 for(
unsigned short end = 0;
end < 2; ++
end) {
262 if(primTj.VtxID[
end] == 0)
continue;
263 auto& vx2 = slc.
vtxs[primTj.VtxID[
end] - 1];
264 if(vx2.Vx3ID == vx3.ID)
continue;
267 for(
auto dtrID : dtrList) {
269 if(dtrID == primTjID)
continue;
270 auto& dtj = slc.
tjs[dtrID - 1];
271 if(dtj.ParentID != -1) {
275 pardtr.push_back(std::make_pair(primTjID, dtrID));
280 for(
unsigned short end = 0;
end < 2; ++
end) {
281 if(primTj.VtxID[
end] == 0)
continue;
282 auto& vx2 = slc.
vtxs[primTj.VtxID[
end] - 1];
286 if(pardtr.empty())
continue;
290 for(
auto pdtr : pardtr) myprt<<
" "<<pdtr.first<<
"_"<<pdtr.second;
294 for(
unsigned short nit = 0; nit < 100; ++nit) {
295 auto lastPair = pardtr[pardtr.size() - 1];
296 auto& dtj = slc.
tjs[lastPair.second - 1];
297 dtj.ParentID = lastPair.first;
300 unsigned short dpt = 0, ppt = 0;
301 auto& ptj = slc.
tjs[lastPair.first - 1];
309 for(
unsigned short end = 0;
end < 2; ++
end) {
310 if(dtj.VtxID[
end] == 0)
continue;
311 auto& vx2 = slc.
vtxs[dtj.VtxID[
end] - 1];
312 if(lookedAt2[vx2.ID])
continue;
313 lookedAt2[vx2.ID] =
true;
315 for(
auto tjid : tjlist) {
316 if(tjid == dtj.ID || tjid == ptj.ID)
continue;
317 pardtr.push_back(std::make_pair(dtj.ID, tjid));
320 myprt<<
" add par_dtr";
321 for(
auto pdtr : pardtr) myprt<<
" "<<pdtr.first<<
"_"<<pdtr.second;
325 if(pardtr.empty())
break;
329 for(
auto tjid : masterlist) {
330 auto& tj = slc.
tjs[tjid - 1];
331 if(tj.ParentID < 0) {
343 if(tjIDs.size() < 2)
return 1;
344 std::vector<float> plnchg(slc.
nPlanes);
345 for(
auto tjid : tjIDs) {
346 if(tjid <= 0 || tjid > (
int)slc.
tjs.size())
return 1;
347 auto& tj = slc.
tjs[tjid - 1];
350 plnchg[plane] += tj.TotChg;
354 for(
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
355 if(plnchg[plane] == 0)
continue;
356 aveChg += plnchg[plane];
359 if(cnt < 2)
return 1;
362 for(
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
364 if(plnchg[plane] == 0)
continue;
365 float asym = std::abs(plnchg[plane] - aveChg) / (plnchg[plane] + aveChg);
366 if(asym > maxAsym) maxAsym = asym;
381 std::array<int, 5> codeList = {{0, 11, 13, 111, 211}};
382 unsigned short codeIndex = 0;
383 if(tjIDs.empty())
return codeList[codeIndex];
385 std::array<unsigned short, 5> cnts;
390 for(
auto tjid : tjIDs) {
391 if(tjid <= 0 || tjid > (
int)slc.
tjs.size())
continue;
392 auto& tj = slc.
tjs[tjid - 1];
393 for(
unsigned short ii = 0; ii < 5; ++ii)
if(tj.PDGCode == codeList[ii]) ++cnts[ii];
398 if(len > maxLen) maxLen = len;
402 for(
unsigned short ii = 1; ii < 5; ++ii) {
403 if(cnts[ii] > maxCnt) {
409 return codeList[codeIndex];
416 unsigned short cnt = 0;
417 for(
auto& dtj : slc.
tjs) {
420 if(dtj.ParentID == tj.
ID) ++cnt;
429 if(tjIDs.empty())
return 0;
430 if(tjIDs[0] <= 0 || tjIDs[0] > (
int)slc.
tjs.size())
return 0;
431 unsigned short cnt = 0;
432 for(
auto& tj : slc.
tjs) {
435 if(std::find(tjIDs.begin(), tjIDs.end(), tj.ParentID) != tjIDs.end()) ++cnt;
448 if(primID <= 0 || primID > (
int)slc.
tjs.size())
return -1;
451 auto& ptj = slc.
tjs[primID - 1];
452 for(
unsigned short end = 0;
end < 2; ++
end) {
453 if(ptj.VtxID[
end] == 0)
continue;
454 auto& vx2 = slc.
vtxs[ptj.VtxID[
end] - 1];
455 if(vx2.Vx3ID == 0)
continue;
456 auto& vx3 = slc.
vtx3s[vx2.Vx3ID - 1];
457 if(vx3.Neutrino)
return primID;
471 for(
unsigned short nit = 0; nit < 10; ++nit) {
472 if(parid < 1 || parid > (
int)slc.
tjs.size())
break;
473 auto& tj = slc.
tjs[parid - 1];
488 int dtruid = pfp.
UID;
489 unsigned short nit = 0;
492 auto& parent =
slices[slcIndx.first].pfps[slcIndx.second];
494 if(parent.PDGCode == 14 || parent.PDGCode == 12)
return dtruid;
496 if(parent.ParentUID == 0)
return parent.UID;
497 if(
int(parent.ParentUID) == parent.UID)
return parent.UID;
499 paruid = parent.ParentUID;
500 if(paruid < 0)
return 0;
502 if(nit == 10)
return 0;
510 if(mtjid > (
int)slc.
tjs.size())
return false;
511 auto& mtj = slc.
tjs[mtjid - 1];
514 for(
auto tjid : pfp.
TjIDs) {
515 auto& otj = slc.
tjs[tjid - 1];
516 if(otj.CTP == mtj.CTP) {
521 if(otjid == 0)
return false;
523 int newtjid = slc.
tjs.size();
524 if(prt)
mf::LogVerbatim(
"TC")<<
"MergeTjIntoPFP: merged T"<<otjid<<
" with T"<<mtjid<<
" -> T"<<newtjid;
525 std::replace(pfp.
TjIDs.begin(), pfp.
TjIDs.begin(), otjid, newtjid);
528 if(prt)
mf::LogVerbatim(
"TC")<<
"MergeTjIntoPFP: merge T"<<otjid<<
" with T"<<mtjid<<
" failed ";
548 if(tjIDs.size() < 2)
return false;
549 unsigned short lasttj = tjIDs[tjIDs.size() - 1] - 1;
550 auto& mtj = slc.
tjs[lasttj];
551 bool mtjIsShort = (mtj.Pts.size() < 5);
553 std::array<float, 2> minsep2 {{1000, 1000}};
555 std::array<int, 2> minsepTj {{0, 0}};
557 std::array<unsigned short, 2> minsepPt;
560 std::array<unsigned short, 2> minsepEnd;
561 for(
auto tjid : tjIDs) {
562 auto& tj = slc.
tjs[tjid - 1];
563 if(tj.CTP != mtj.CTP)
continue;
564 if(tj.ID == mtj.ID)
continue;
565 for(
unsigned short mend = 0; mend < 2; ++mend) {
566 Point2_t mendPos = mtj.Pts[mtj.EndPt[mend]].Pos;
567 float sep2 = minsep2[mend];
568 unsigned short closePt = 0;
570 minsep2[mend] = sep2;
571 minsepTj[mend] = tjid;
572 minsepPt[mend] = closePt;
575 short dend0 = abs((
short)closePt - tj.EndPt[0]);
576 short dend1 = abs((
short)closePt - tj.EndPt[1]);
577 if(dend0 < dend1 && dend0 < 3) minsepEnd[mend] = 0;
578 if(dend1 < dend0 && dend1 < 3) minsepEnd[mend] = 1;
585 bool isCompatible = (minsepEnd[0] != 2 && minsepEnd[1] != 2);
587 if(isCompatible && mtjIsShort) {
588 float minminsep = minsep2[0];
589 if(minsep2[1] < minminsep) minminsep = minsep2[1];
591 isCompatible = minminsep < 5;
596 myprt<<
"CompatibleMerge: T"<<mtj.ID<<
" end";
597 for(
unsigned short end = 0;
end < 2; ++
end) myprt<<
" T"<<minsepTj[
end]<<
"_I"<<minsepPt[
end]<<
"_E"<<minsepEnd[
end]<<
" minsep "<<sqrt(minsep2[
end]);
598 myprt<<
" Compatible? "<<isCompatible;
611 if(tj1.
CTP != tj2.
CTP)
return false;
612 unsigned short end1 = -1, end2 = 0;
615 if(len2 < minLen) minLen = len2;
617 if(minLen > 10) minLen = 10;
618 for(
unsigned short e1 = 0; e1 < 2; ++e1) {
620 for(
unsigned short e2 = 0; e2 < 2; ++e2) {
622 float sep =
PosSep(tp1.Pos, tp2.Pos);
625 end1 = e1; end2 = e2;
629 if(end1 < 0)
return false;
631 if(end2 != 1 - end1)
return false;
634 if(overlapFraction > 0.25) {
635 if(prt)
mf::LogVerbatim(
"TC")<<
"CM: "<<tj1.
ID<<
" "<<tj2.
ID<<
" overlapFraction "<<overlapFraction<<
" > 0.25 ";
639 auto& tp1 = tj1.
Pts[tj1.
EndPt[end1]];
640 auto& tp2 = tj2.
Pts[tj2.
EndPt[end2]];
647 float doca1 =
PointTrajDOCA(slc, tp1.Pos[0], tp1.Pos[1], tp2);
648 float doca2 =
PointTrajDOCA(slc, tp2.Pos[0], tp2.Pos[1], tp1);
649 if(doca1 > 2 && doca2 > 2) {
650 if(prt)
mf::LogVerbatim(
"TC")<<
"CM: "<<tj1.
ID<<
" "<<tj2.
ID<<
" Both docas > 2 "<<doca1<<
" "<<doca2;
668 float maxWire = -1E6;
671 for(
auto& tp : tj1.
Pts) {
672 if(tp.Chg == 0)
continue;
673 if(tp.Pos[0] < 0)
continue;
674 if(tp.Pos[0] < minWire) minWire = tp.Pos[0];
675 if(tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
678 if(cnt1 == 0)
return 0;
680 for(
auto& tp : tj2.
Pts) {
681 if(tp.Chg == 0)
continue;
682 if(tp.Pos[0] < 0)
continue;
683 if(tp.Pos[0] < minWire) minWire = tp.Pos[0];
684 if(tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
687 if(cnt2 == 0)
return 0;
688 int span = maxWire - minWire;
689 if(span <= 0)
return 0;
690 std::vector<unsigned short> wcnt(span);
691 for(
auto& tp : tj1.
Pts) {
692 if(tp.Chg == 0)
continue;
693 if(tp.Pos[0] < -0.4)
continue;
694 int indx = std::nearbyint(tp.Pos[0] - minWire);
695 if(indx < 0 || indx > span - 1)
continue;
698 for(
auto& tp : tj2.
Pts) {
699 if(tp.Chg == 0)
continue;
700 if(tp.Pos[0] < -0.4)
continue;
701 int indx = std::nearbyint(tp.Pos[0] - minWire);
702 if(indx < 0 || indx > span - 1)
continue;
705 float cntOverlap = 0;
706 for(
auto cnt : wcnt)
if(cnt > 1) ++cntOverlap;
708 return cntOverlap / cnt1;
710 return cntOverlap / cnt2;
742 if(angle > M_PI) angle = M_PI;
743 if(angle < -M_PI) angle = M_PI;
744 if(angle < 0) angle = -angle;
745 if(angle > M_PI/2) angle = M_PI - angle;
756 unsigned short originPt = tj.
EndPt[1];
757 unsigned short npts = tj.
Pts[originPt].NTPsFit;
759 unsigned short fitDir = -1;
760 FitTraj(slc, tj, originPt, npts, fitDir, tpFit);
761 tj.
Pts[originPt] = tpFit;
783 if(originPt > tj.
Pts.size() - 1) {
784 mf::LogWarning(
"TC")<<
"FitTraj: Requesting fit of invalid TP "<<originPt;
789 tpFit = tj.
Pts[originPt];
792 if(fitDir < -1 || fitDir > 1)
return;
794 std::vector<double>
x,
y;
797 if(tj.
Pts[originPt].Chg == 0) origin = tj.
Pts[originPt].Pos;
801 for(
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1]; ++ipt) {
802 if(tj.
Pts[ipt].Chg == 0)
continue;
803 double xx = tj.
Pts[ipt].HitPos[0] - origin[0];
804 double yy = tj.
Pts[ipt].HitPos[1] - origin[1];
808 if(x.size() != 2)
return;
812 if(y[1] < y[0]) tpFit.
Ang = -tpFit.
Ang;
814 double dx = x[1] - x[0];
815 double dy = y[1] - y[0];
816 tpFit.
Ang = atan2(dy, dx);
818 tpFit.
Dir[0] = cos(tpFit.
Ang);
819 tpFit.
Dir[1] = sin(tpFit.
Ang);
820 tpFit.
Pos[0] += origin[0];
821 tpFit.
Pos[1] += origin[1];
828 std::vector<double>
w, q;
829 std::array<double, 2>
dir;
830 double xx, yy, xr, yr;
835 double rotAngle = tj.
Pts[originPt].Ang;
836 double cs = cos(-rotAngle);
837 double sn = sin(-rotAngle);
840 if(tj.
Pts[originPt].Chg > 0) {
841 xx = tj.
Pts[originPt].HitPos[0] - origin[0];
842 yy = tj.
Pts[originPt].HitPos[1] - origin[1];
843 xr = cs * xx - sn * yy;
844 yr = sn * xx + cs * yy;
847 chgWt = tj.
Pts[originPt].ChgPull;
848 if(chgWt < 1) chgWt = 1;
850 w.push_back(chgWt * tj.
Pts[originPt].HitPosErr2);
854 if(fitDir != 0) --npts;
858 unsigned short cnt = 0;
859 for(
unsigned short ipt = originPt + 1; ipt < tj.
Pts.size(); ++ipt) {
860 if(tj.
Pts[ipt].Chg == 0)
continue;
861 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
862 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
863 xr = cs * xx - sn * yy;
864 yr = sn * xx + cs * yy;
867 chgWt = tj.
Pts[ipt].ChgPull;
868 if(chgWt < 1) chgWt = 1;
870 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
872 if(cnt == npts)
break;
877 if(fitDir != 1 && originPt > 0) {
878 unsigned short cnt = 0;
879 for(
unsigned short ii = 1; ii < tj.
Pts.size(); ++ii) {
880 unsigned short ipt = originPt - ii;
881 if(ipt > tj.
Pts.size() - 1)
continue;
882 if(tj.
Pts[ipt].Chg == 0)
continue;
883 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
884 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
885 xr = cs * xx - sn * yy;
886 yr = sn * xx + cs * yy;
889 chgWt = tj.
Pts[ipt].ChgPull;
890 if(chgWt < 1) chgWt = 1;
892 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
894 if(cnt == npts)
break;
900 if(x.size() < 2)
return;
911 for(
unsigned short ipt = 0; ipt < x.size(); ++ipt) {
912 if(w[ipt] < 0.00001) w[ipt] = 0.00001;
915 sumx += wght * x[ipt];
916 sumy += wght * y[ipt];
917 sumx2 += wght * x[ipt] * x[ipt];
918 sumy2 += wght * y[ipt] * y[ipt];
919 sumxy += wght * x[ipt] * y[ipt];
922 double delta = sum * sumx2 - sumx * sumx;
923 if(delta == 0)
return;
925 double A = (sumx2 * sumy - sumx * sumxy) / delta;
927 double B = (sumxy * sum - sumx * sumy) / delta;
932 double newang = atan(B);
933 dir[0] = cos(newang);
934 dir[1] = sin(newang);
938 tpFit.
Dir[0] = cs * dir[0] - sn * dir[1];
939 tpFit.
Dir[1] = sn * dir[0] + cs * dir[1];
941 bool flipDir =
false;
943 flipDir = std::signbit(tpFit.
Dir[1]) != std::signbit(tj.
Pts[originPt].Dir[1]);
945 flipDir = std::signbit(tpFit.
Dir[0]) != std::signbit(tj.
Pts[originPt].Dir[0]);
948 tpFit.
Dir[0] = -tpFit.
Dir[0];
949 tpFit.
Dir[1] = -tpFit.
Dir[1];
951 tpFit.
Ang = atan2(tpFit.
Dir[1], tpFit.
Dir[0]);
956 tpFit.
Pos[0] = -sn * A + origin[0];
957 tpFit.
Pos[1] = cs * A + origin[1];
961 if(x.size() < 3)
return;
964 double ndof = x.size() - 2;
965 double varnce = (sumy2 + A*A*sum + B*B*sumx2 - 2 * (A*sumy + B*sumxy - A*B*sumx)) / ndof;
969 double slopeError = sqrt(varnce * sum / delta);
970 tpFit.
AngErr = std::abs(atan(slopeError));
977 for(
unsigned short ii = 0; ii < y.size(); ++ii) {
978 arg = y[ii] - A - B * x[ii];
979 sum += arg * arg / w[ii];
981 tpFit.
FitChi = sum / ndof;
994 std::vector<double>
x,
y;
996 std::vector<double>
w, q;
998 unsigned short firstPt = tj.
EndPt[0] + 2;
999 unsigned short lastPt = tj.
EndPt[1] - 2;
1000 if(lastPt < firstPt + 3)
return 0;
1002 for(
unsigned short ipt = firstPt; ipt <= lastPt; ++ipt) {
1003 auto& tp = tj.
Pts[ipt];
1004 if(tp.Chg <= 0)
continue;
1007 double sep =
PosSep(tp.Pos, origin);
1009 y.push_back((
double)tp.Chg);
1010 double wght = 0.2 * tp.Chg;
1011 w.push_back(wght * wght);
1013 if(w.size() < 3)
return 0;
1024 for(
unsigned short ipt = 0; ipt < x.size(); ++ipt) {
1027 sumx += wght * x[ipt];
1028 sumy += wght * y[ipt];
1029 sumx2 += wght * x[ipt] * x[ipt];
1030 sumy2 += wght * y[ipt] * y[ipt];
1031 sumxy += wght * x[ipt] * y[ipt];
1034 double delta = sum * sumx2 - sumx * sumx;
1035 if(delta == 0)
return 0;
1037 double A = (sumx2 * sumy - sumx * sumxy) / delta;
1039 double B = (sumxy * sum - sumx * sumy) / delta;
1042 double ndof = x.size() - 2;
1043 double varnce = (sumy2 + A*A*sum + B*B*sumx2 - 2 * (A*sumy + B*sumxy - A*B*sumx)) / ndof;
1044 if(varnce <= 0)
return 0;
1045 double BErr = sqrt(varnce * sum / delta);
1048 float slopeSig = B / (3 * BErr);
1049 if(slopeSig > 1) slopeSig = 1;
1050 if(slopeSig < -1) slopeSig = -1;
1052 slopeSig = (1 + slopeSig) / 2;
1056 myprt<<
"TjDir: T"<<tj.
ID<<
" slope "<<std::fixed<<std::setprecision(1)<<B<<
" error "<<BErr<<
" DirFOM "<<slopeSig;
1084 if(pfp.
PDGCode == 1111)
return;
1086 bool reverseMe =
false;
1090 unsigned short braggCnt0 = 0;
1091 unsigned short braggCnt1 = 0;
1092 for(
auto& tjID : pfp.
TjIDs) {
1093 auto& tj = slc.
tjs[tjID - 1];
1094 if(tj.StopFlag[0][
kBragg]) ++braggCnt0;
1095 if(tj.StopFlag[1][
kBragg]) ++braggCnt1;
1097 if(braggCnt0 > 0 || braggCnt1 > 0) {
1100 if(braggCnt0 > braggCnt1) reverseMe =
true;
1104 if(!reverseMe)
return;
1107 for(
auto& tjID : pfp.
TjIDs) {
1108 unsigned short itj = tjID - 1;
1115 std::swap(pfp.
XYZ[0], pfp.
XYZ[1]);
1116 std::swap(pfp.
Dir[0], pfp.
Dir[1]);
1118 std::swap(pfp.
dEdx[0], pfp.
dEdx[1]);
1129 if(slc.
pfps.empty())
return USHRT_MAX;
1130 for(
unsigned int ipfp = 0; ipfp < slc.
pfps.size(); ++ipfp) {
1131 const auto& pfp = slc.
pfps[ipfp];
1132 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tjID) != pfp.TjIDs.end())
return ipfp;
1142 for(
unsigned int ims = 0; ims < slc.
matchVec.size(); ++ims) {
1143 const auto& ms = slc.
matchVec[ims];
1144 if(std::find(ms.TjIDs.begin(), ms.TjIDs.end(), tjID) != ms.TjIDs.end())
return ims;
1153 for(
auto& tp : tj.
Pts) {
1154 for(
auto iht : tp.Hits) {
1165 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
1183 if(slc.
tjs.size() >= USHRT_MAX) {
1184 mf::LogError(
"TC")<<
"StoreTraj: Too many trajectories "<<slc.
tjs.size();
1192 if(tj.
EndPt[1] > tj.
Pts.size())
return false;
1193 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0] + 1;
1194 if(npts < 2)
return false;
1196 auto& endTp0 = tj.
Pts[tj.
EndPt[0]];
1197 auto& endTp1 = tj.
Pts[tj.
EndPt[1]];
1201 if(endTp0.AveChg <= 0) {
1202 unsigned short cnt = 0;
1204 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1205 if(tj.
Pts[ipt].Chg == 0)
continue;
1206 sum += tj.
Pts[ipt].Chg;
1210 tj.
Pts[tj.
EndPt[0]].AveChg = sum / (float)cnt;
1212 if(endTp1.AveChg <= 0 && npts < 5) endTp1.AveChg = endTp0.AveChg;
1213 if(endTp1.AveChg <= 0) {
1215 unsigned short cnt = 0;
1216 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
1217 short ipt = tj.
EndPt[1] - ii;
1219 if(tj.
Pts[ipt].Chg == 0)
continue;
1220 sum += tj.
Pts[ipt].Chg;
1225 tj.
Pts[tj.
EndPt[1]].AveChg = sum / (float)cnt;
1232 int trID = slc.
tjs.size() + 1;
1234 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1235 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1236 if(tj.
Pts[ipt].UseHit[ii]) {
1237 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1238 if(iht > slc.
slHits.size() - 1) {
1239 std::cout<<
"StoreTraj bad iht "<<iht<<
" slHits size "<<slc.
slHits.size()<<
" tj.ID "<<tj.
ID<<
"\n";
1243 if(slc.
slHits[iht].InTraj > 0) {
1244 std::cout<<
"StoreTraj fail "<<iht<<
" "<<slc.
slHits[iht].InTraj<<
" WorkID "<<tj.
WorkID<<
" InTraj "<<slc.
slHits[iht].InTraj;
1245 std::cout<<
" algs ";
1251 slc.
slHits[iht].InTraj = trID;
1257 for(
unsigned int iht = 0; iht < slc.
slHits.size(); ++iht) {
1258 if(slc.
slHits[iht].InTraj == tj.
ID) {
1272 slc.
tjs.push_back(tj);
1275 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
1276 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1277 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1278 if(slc.
slHits[iht].allHitsIndex ==
debug.
Hit) std::cout<<
"Debug hit appears in trajectory w WorkID "<<tj.
WorkID<<
" UseHit "<<tj.
Pts[ipt].UseHit[ii]<<
"\n";
1310 Fit2D(0, inPt, chgErr, outVec, outVecErr, chiDOF);
1312 unsigned short cnt = 0;
1313 for(
unsigned short ipt = fromPt; ipt <= toPt; ++ipt) {
1314 auto& tp = tj.
Pts[ipt];
1315 if(tp.Chg <= 0)
continue;
1317 if(wire0 < 0) wire0 = tp.Pos[0];
1319 inPt[0] = std::abs(tp.Pos[0] - wire0);
1322 chgErr = 0.1 * tp.Chg;
1323 if(!
Fit2D(2, inPt, chgErr, outVec, outVecErr, chiDOF))
break;
1327 if(!
Fit2D(-1, inPt, chgErr, outVec, outVecErr, chiDOF))
return;
1329 slopeErr = outVecErr[1];
1339 unsigned short itj = 0;
1340 std::vector<unsigned int> tHits;
1341 std::vector<unsigned int> atHits;
1342 for(
auto& tj : slc.
tjs) {
1344 if(tj.AlgMod[
kKilled])
continue;
1347 std::cout<<someText<<
" ChkInTraj hit size mis-match in tj ID "<<tj.ID<<
" AlgBitNames";
1348 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(tj.AlgMod[ib]) std::cout<<
" "<<
AlgBitNames[ib];
1353 if(tHits.size() < 2) {
1354 std::cout<<someText<<
" ChkInTraj: Insufficient hits in traj "<<tj.ID<<
"\n";
1358 std::sort(tHits.begin(), tHits.end());
1360 for(iht = 0; iht < slc.
slHits.size(); ++iht) {
1361 if(slc.
slHits[iht].InTraj == tID) atHits.push_back(iht);
1363 if(atHits.size() < 2) {
1364 std::cout<<someText<<
" ChkInTraj: Insufficient hits in atHits in traj "<<tj.ID<<
" Killing it\n";
1368 if(!std::equal(tHits.begin(), tHits.end(), atHits.begin())) {
1370 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";
1374 myprt<<
"index inTraj UseHit \n";
1375 for(iht = 0; iht < atHits.size(); ++iht) {
1377 if(iht < tHits.size()) myprt<<
" "<<
PrintHit(slc.
slHits[tHits[iht]]);
1378 if(atHits[iht] != tHits[iht]) myprt<<
" <<< "<<atHits[iht]<<
" != "<<tHits[iht];
1381 if(tHits.size() > atHits.size()) {
1382 for(iht = atHits.size(); iht < atHits.size(); ++iht) {
1383 myprt<<
"atHits "<<iht<<
" "<<
PrintHit(slc.
slHits[atHits[iht]])<<
"\n";
1390 for(
unsigned short end = 0;
end < 2; ++
end) {
1391 if(tj.VtxID[
end] > slc.
vtxs.size()) {
1393 std::cout<<someText<<
" ChkInTraj: Bad VtxID "<<tj.ID<<
" vtx size "<<slc.
vtxs.size()<<
"\n";
1418 if(itj > slc.
tjs.size() - 1)
return;
1419 auto& tj = slc.
tjs[itj];
1422 if(tj.StopFlag[0][
kBragg])
return;
1425 if(tj.Pts.size() < 20)
return;
1430 float chg2 = tj.Pts[tj.EndPt[0] + 2].AveChg;
1432 float chg15 = tj.Pts[tj.EndPt[0] + 15].AveChg;
1433 if(chg2 < 3 * chg15)
return;
1436 float midChg = 0.5 * (chg2 + chg15);
1438 unsigned short breakPt = USHRT_MAX;
1439 for(
unsigned short ipt = tj.EndPt[0] + 3; ipt < 15; ++ipt) {
1440 float chgm2 = tj.Pts[ipt - 2].Chg;
1441 if(chgm2 == 0)
continue;
1442 float chgm1 = tj.Pts[ipt - 1].Chg;
1443 if(chgm1 == 0)
continue;
1444 float chgp1 = tj.Pts[ipt + 1].Chg;
1445 if(chgp1 == 0)
continue;
1446 float chgp2 = tj.Pts[ipt + 2].Chg;
1447 if(chgp2 == 0)
continue;
1448 if(chgm2 > midChg && chgm1 > midChg && chgp1 < midChg && chgp2 < midChg) {
1453 if(breakPt == USHRT_MAX)
return;
1456 std::array<double, 2> cnt, sum, sum2;
1457 for(
unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
1458 auto& tp = tj.Pts[ipt];
1459 if(tp.Chg <= 0)
continue;
1460 unsigned short end = 0;
1461 if(ipt > breakPt) end = 1;
1464 sum2[
end] += tp.Chg * tp.Chg;
1466 for(
unsigned short end = 0;
end < 2; ++
end) {
1467 if(cnt[
end] < 3)
return;
1468 double ave = sum[
end] / cnt[
end];
1469 double arg = sum2[
end] - cnt[
end] * ave * ave;
1470 if(arg <= 0)
return;
1471 sum2[
end] = sqrt(arg / (cnt[
end] - 1));
1475 bool doSplit =
true;
1478 if(tj.ChgRMS > 0.5 && sum2[0] > 0.3 && sum2[1] > 0.3) doSplit =
false;
1481 myprt<<
"CTBC: T"<<tj.ID<<
" chgRMS "<<tj.ChgRMS;
1482 myprt<<
" AveChg before split point "<<(int)sum[0]<<
" rms "<<sum2[0];
1483 myprt<<
" after "<<(int)sum[1]<<
" rms "<<sum2[1]<<
" doSplit? "<<doSplit;
1485 if(!doSplit)
return;
1489 aVtx.
Pos = tj.Pts[breakPt].Pos;
1491 aVtx.
Pass = tj.Pass;
1495 aVtx.
ID = slc.
vtxs.size() + 1;
1497 unsigned short ivx = slc.
vtxs.size();
1499 if(!
SplitTraj(slc, itj, breakPt, ivx, prt)) {
1526 short minPts = fQualityCuts[1];
1527 if(minPts < 1)
return;
1528 if(npwc < minPts)
return;
1531 if(npwc == minPts + 1) {
1532 unsigned short endPt1 = tj.
EndPt[1];
1533 auto& tp = tj.
Pts[endPt1];
1534 auto& ptp = tj.
Pts[endPt1 - 1];
1537 float dwire = std::abs(ptp.Pos[0] - tp.Pos[0]);
1538 if(ptp.Chg == 0 || dwire > 1.1) {
1548 for(lastPt = tj.
EndPt[1]; lastPt >= minPts; --lastPt) {
1550 if(lastPt == 1)
break;
1551 if(tj.
Pts[lastPt].Chg == 0)
continue;
1553 unsigned short nadj = 0;
1554 unsigned short npwc = 0;
1555 for(
short ipt = lastPt - minPts; ipt < lastPt; ++ipt) {
1558 auto& tp = tj.
Pts[ipt];
1560 auto& ptp = tj.
Pts[ipt - 1];
1561 if(tp.Chg > 0 && ptp.Chg > 0) {
1563 if(std::abs(tp.Pos[0] - ptp.Pos[0]) < 1.5) ++nadj;
1567 float nwires = std::abs(tj.
Pts[tj.
EndPt[0]].Pos[0] - tj.
Pts[lastPt].Pos[0]) + 1;
1568 float hitFrac = ntpwc / nwires;
1569 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
"-TEP: T"<<tj.
ID<<
" lastPt "<<lastPt<<
" npwc "<<npwc<<
" ntpwc "<<ntpwc<<
" nadj "<<nadj<<
" hitFrac "<<hitFrac;
1572 if(hitFrac > fQualityCuts[0] && ntpwc > minPts)
break;
1574 if(hitFrac > fQualityCuts[0] && npwc == minPts && nadj == minPts)
break;
1579 if(tj.
Pts[lastPt].Pos[0] > -0.4) {
1580 unsigned int prevWire = std::nearbyint(tj.
Pts[lastPt].Pos[0]);
1587 mf::LogVerbatim(
"TC")<<fcnLabel<<
"-TEP: is prevWire "<<prevWire<<
" dead? ";
1590 if(prevWire < slc.
nWires[plane] && slc.
wireHitRange[plane][prevWire].first == -1) --lastPt;
1594 if(lastPt == tj.
EndPt[1]) {
1604 fcnLabel +=
"-TEPo";
1619 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0];
1622 if(npts > 50)
return;
1624 if(npts < 8)
return;
1627 unsigned short atPt = 0;
1629 for(
unsigned short ipt = tj.
EndPt[0] + 2; ipt <= tj.
EndPt[1] - 2; ++ipt) {
1630 auto& tp = tj.
Pts[ipt];
1631 if(tp.ChgPull > bigPull) {
1632 bigPull = tp.ChgPull;
1636 if(atPt == 0)
return;
1638 if((atPt - tj.
EndPt[0]) < 0.5 * npts)
return;
1639 if(prt)
mf::LogVerbatim(
"TC")<<
"CCA: T"<<tj.
ID<<
" Large Chg point at "<<atPt<<
". Check charge asymmetry around it.";
1640 unsigned short nchk = 0;
1641 unsigned short npos = 0;
1642 unsigned short nneg = 0;
1643 for(
short ii = 1; ii < 5; ++ii) {
1644 short iplu = atPt + ii;
1645 if(iplu > tj.
EndPt[1])
break;
1646 short ineg = atPt - ii;
1647 if(ineg < tj.
EndPt[0])
break;
1648 if(tj.
Pts[iplu].Chg == 0)
continue;
1649 if(tj.
Pts[ineg].Chg == 0)
continue;
1650 float asym = (tj.
Pts[iplu].Chg - tj.
Pts[ineg].Chg) / (tj.
Pts[iplu].Chg + tj.
Pts[ineg].Chg);
1652 if(asym > 0.5) ++npos;
1653 if(asym < -0.5) ++nneg;
1654 if(prt)
mf::LogVerbatim(
"TC")<<
" ineg "<<ineg<<
" iplu "<<iplu<<
" asym "<<asym<<
" nchk "<<nchk;
1656 if(nchk < 3)
return;
1659 bool doTrim = (nneg > nchk) || (npos > nchk);
1662 auto& prevTP = tj.
Pts[atPt - 1];
1663 if(std::abs(prevTP.ChgPull) > 2) --atPt;
1674 if(MinWireSignalFraction == 0)
return true;
1676 if(tp1.
Pos[0] < -0.4 || tp2.
Pos[0] < -0.4)
return false;
1677 int fromWire = std::nearbyint(tp1.
Pos[0]);
1678 int toWire = std::nearbyint(tp2.
Pos[0]);
1680 if(fromWire == toWire) {
1683 tp.
Pos[1] = 0.5 * (tp1.
Pos[1] + tp2.
Pos[1]);
1689 return SignalBetween(slc, tp, toWire, MinWireSignalFraction);
1707 if(tp.
Pos[0] < -0.4 || toPos0 < -0.4)
return 0;
1708 int fromWire = std::nearbyint(tp.
Pos[0]);
1709 int toWire = std::nearbyint(toPos0);
1711 if(fromWire == toWire) {
1715 int nWires = abs(toWire - fromWire) + 1;
1717 if(std::abs(tp.
Dir[0]) < 0.001) tp.
Dir[0] = 0.001;
1718 float stepSize = std::abs(1/tp.
Dir[0]);
1720 if(toWire > fromWire && tp.
Dir[0] < 0) stepSize = -stepSize;
1721 if(toWire < fromWire && tp.
Dir[0] > 0) stepSize = -stepSize;
1724 for(
unsigned short cnt = 0; cnt < nWires; ++cnt) {
1727 tp.
Pos[0] += tp.
Dir[0] * stepSize;
1728 tp.
Pos[1] += tp.
Dir[1] * stepSize;
1730 float sigFrac = nsig / num;
1736 bool TrajHitsOK(
TCSlice& slc,
const std::vector<unsigned int>& iHitsInMultiplet,
const std::vector<unsigned int>& jHitsInMultiplet)
1740 if(iHitsInMultiplet.empty() || jHitsInMultiplet.empty())
return false;
1746 for(
auto& iht : iHitsInMultiplet) {
1748 float cv =
hit.PeakTime();
1749 float rms =
hit.RMS();
1750 float arg = cv - 3.1 * rms;
1751 if(arg < minI) minI = arg;
1752 arg = cv + 3.1 * rms;
1753 if(arg > maxI) maxI = arg;
1759 for(
auto& jht : jHitsInMultiplet) {
1761 float cv =
hit.PeakTime();
1762 float rms =
hit.RMS();
1763 float arg = cv - 3.1 * rms;
1764 if(arg < minJ) minJ = arg;
1765 arg = cv + 3.1 * rms;
1766 if(arg > maxJ) maxJ = arg;
1770 if(maxI > minJ)
return true;
1772 if(minI < maxJ)
return true;
1781 if(iht > slc.
slHits.size() - 1)
return false;
1782 if(jht > slc.
slHits.size() - 1)
return false;
1786 int iwire = ihit.WireID().Wire;
1787 int jwire = jhit.WireID().Wire;
1788 if(std::abs(iwire - jwire) > 1)
return false;
1789 if(ihit.PeakTime() > jhit.PeakTime()) {
1790 float minISignal = ihit.PeakTime() - 3 * ihit.RMS();
1791 float maxJSignal = jhit.PeakTime() + 3 * ihit.RMS();
1792 if(maxJSignal > minISignal)
return true;
1794 float maxISignal = ihit.PeakTime() + 3 * ihit.RMS();
1795 float minJSignal = jhit.PeakTime() - 3 * ihit.RMS();
1796 if(minJSignal > maxISignal)
return true;
1805 if(std::abs(tp.
Dir[0]) > 0.001) {
1818 if(tp.
Pos[0] < -0.4)
return false;
1819 unsigned int wire = std::nearbyint(tp.
Pos[0]);
1821 unsigned int ipl = planeID.
Plane;
1822 if(wire >= slc.
nWires[ipl])
return false;
1825 if(slc.
wireHitRange[ipl][wire].first == -1)
return true;
1827 float tickRange = 0;
1828 if(std::abs(tp.
Dir[1]) != 0) {
1831 if(tickRange > 40) tickRange = 40;
1833 float loTpTick = projTick - tickRange;
1834 float hiTpTick = projTick + tickRange;
1835 unsigned int firstHit = (
unsigned int)slc.
wireHitRange[ipl][wire].first;
1836 unsigned int lastHit = (
unsigned int)slc.
wireHitRange[ipl][wire].second;
1838 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
1840 if(projTick <
hit.PeakTime()) {
1841 float loHitTick =
hit.PeakTime() - 3 *
hit.RMS();
1842 if(hiTpTick > loHitTick)
return true;
1844 float hiHitTick =
hit.PeakTime() + 3 *
hit.RMS();
1845 if(loTpTick < hiHitTick)
return true;
1855 for (
size_t i = 0; i<tp.
Hits.size(); ++i){
1856 if (!tp.
UseHit[i])
continue;
1865 unsigned short firstPt = tj.
EndPt[0];
1866 unsigned short lastPt = tj.
EndPt[1];
1873 unsigned short ntp = 0;
1874 for(
unsigned short ipt = firstPt; ipt <= lastPt; ++ipt)
if(tj.
Pts[ipt].Chg > 0) ++ntp;
1889 if(inWirePos1 < -0.4 || inWirePos2 < -0.4)
return 0;
1890 unsigned int inWire1 = std::nearbyint(inWirePos1);
1891 unsigned int inWire2 = std::nearbyint(inWirePos2);
1893 unsigned short plane = planeID.
Plane;
1894 if(inWire1 > slc.
nWires[plane] || inWire2 > slc.
nWires[plane])
return 0;
1895 if(inWire1 > inWire2) {
1897 unsigned int tmp = inWire1;
1902 unsigned int wire, ndead = 0;
1903 for(wire = inWire1; wire < inWire2; ++wire)
if(slc.
wireHitRange[plane][wire].first == -1) ++ndead;
1910 unsigned short pdg = abs(PDGCode);
1911 if(pdg == 11)
return 0;
1912 if(pdg == 13)
return 1;
1913 if(pdg == 211)
return 2;
1914 if(pdg == 321)
return 3;
1915 if(pdg == 2212)
return 4;
1926 if(itj > slc.
tjs.size() - 1)
return;
1927 int killTjID = slc.
tjs[itj].ID;
1928 for(
auto&
hit : slc.
slHits)
if(
hit.InTraj == killTjID)
hit.InTraj = 0;
1935 if(itj > slc.
tjs.size() - 1)
return;
1937 mf::LogWarning(
"TC")<<
"RestoreObsoleteTrajectory: Trying to restore not-obsolete trajectory "<<slc.
tjs[itj].ID;
1941 for(
auto& tp : slc.
tjs[itj].Pts) {
1942 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
1945 if(slc.
slHits[iht].InTraj == 0) {
1946 slc.
slHits[iht].InTraj = slc.
tjs[itj].ID;
1960 for(
auto& shortTj : slc.
tjs) {
1962 if(shortTj.CTP != inCTP)
continue;
1963 unsigned short spts = shortTj.EndPt[1] - shortTj.EndPt[0];
1964 if(spts > 20)
continue;
1966 if(shortTj.PDGCode == 11)
continue;
1968 if(shortTj.SSID > 0)
continue;
1970 if(tjhits.empty())
continue;
1971 std::vector<int> tids;
1972 std::vector<unsigned short> tcnt;
1973 for(
auto iht : tjhits) {
1975 if(
hit.InTraj <= 0)
continue;
1976 if((
unsigned int)
hit.InTraj > slc.
tjs.size())
continue;
1977 if(
hit.InTraj == shortTj.ID)
continue;
1978 unsigned short indx = 0;
1979 for(indx = 0; indx < tids.size(); ++indx)
if(
hit.InTraj == tids[indx])
break;
1980 if(indx == tids.size()) {
1981 tids.push_back(
hit.InTraj);
1987 if(tids.empty())
continue;
1989 unsigned short maxcnt = 0;
1990 for(
unsigned short indx = 0; indx < tids.size(); ++indx) {
1991 if(tcnt[indx] > maxcnt) {
1992 auto& ltj = slc.
tjs[tids[indx] - 1];
1993 unsigned short lpts = ltj.EndPt[1] - ltj.EndPt[0];
1994 if(lpts < spts)
continue;
1995 maxcnt = tcnt[indx];
1998 float hitFrac = (float)maxcnt / (
float)tjhits.size();
1999 if(hitFrac < 0.1)
continue;
2007 if(itj > slc.
tjs.size()-1)
return false;
2009 auto& tj = slc.
tjs[itj];
2012 unsigned short atPt = USHRT_MAX;
2013 for(
unsigned short ipt = tj.EndPt[0] + 1; ipt <= tj.EndPt[1]; ++ipt) {
2014 if(tj.Pts[ipt].Pos[1] > tj.Pts[ipt - 1].Pos[1]) {
2016 if(tj.Pts[ipt - 1].Pos[1] < atPos1 && tj.Pts[ipt].Pos[1] >= atPos1) {
2022 if(tj.Pts[ipt - 1].Pos[1] >= atPos1 && tj.Pts[ipt].Pos[1] < atPos1) {
2028 if(atPt == USHRT_MAX)
return false;
2029 unsigned short vx2Index = USHRT_MAX;
2032 newVx2.
CTP = tj.CTP;
2033 newVx2.
Pos[0] = 0.5 * (tj.Pts[atPt - 1].Pos[0] + tj.Pts[atPt].Pos[0]);
2034 newVx2.
Pos[1] = 0.5 * (tj.Pts[atPt - 1].Pos[1] + tj.Pts[atPt].Pos[1]);
2039 return SplitTraj(slc, itj, atPt, vx2Index, prt);
2043 bool SplitTraj(
TCSlice& slc,
unsigned short itj,
unsigned short pos,
unsigned short ivx,
bool prt)
2050 if(itj > slc.
tjs.size()-1)
return false;
2051 if(pos < slc.
tjs[itj].EndPt[0] + 1 || pos > slc.
tjs[itj].EndPt[1] - 1)
return false;
2052 if(ivx != USHRT_MAX && ivx > slc.
vtxs.size() - 1)
return false;
2057 bool splittingMuon = (tj.
PDGCode == 13);
2058 if(splittingMuon) tj.
PDGCode = 0;
2062 myprt<<
"SplitTraj: Split T"<<tj.
ID<<
" at point "<<pos;
2063 if(ivx < slc.
vtxs.size()) myprt<<
" with Vtx 2V"<<slc.
vtxs[ivx].ID;
2067 unsigned short ipt, ii, ntp = 0;
2068 for(ipt = 0; ipt < pos; ++ipt) {
2069 if(tj.
Pts[ipt].Chg > 0) ++ntp;
2073 if(prt)
mf::LogVerbatim(
"TC")<<
" Split point to small at begin "<<ntp<<
" pos "<<pos<<
" ID ";
2077 for(ipt = pos + 1; ipt < tj.
Pts.size(); ++ipt) {
2078 if(tj.
Pts[ipt].Chg > 0) ++ntp;
2082 if(prt)
mf::LogVerbatim(
"TC")<<
" Split point too small at end "<<ntp<<
" pos "<<pos<<
" EndPt "<<tj.
EndPt[1];
2088 newTj.
ID = slc.
tjs.size() + 1;
2097 for(ipt = pos + 1; ipt < tj.
Pts.size(); ++ipt) {
2098 tj.
Pts[ipt].Chg = 0;
2099 for(ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
2100 if(!tj.
Pts[ipt].UseHit[ii])
continue;
2101 iht = tj.
Pts[ipt].Hits[ii];
2103 if(slc.
slHits[iht].InTraj != tj.
ID)
continue;
2105 tj.
Pts[ipt].UseHit[ii] =
false;
2116 unsigned short eraseSize = pos - 2;
2117 if(eraseSize > newTj.
Pts.size() - 1) {
2129 newTj.
Pts.erase(newTj.
Pts.begin(), newTj.
Pts.begin() + eraseSize);
2131 for(ipt = 0; ipt < 3; ++ipt) {
2132 for(ii = 0; ii < newTj.
Pts[ipt].Hits.size(); ++ii) newTj.
Pts[ipt].UseHit[ii] =
false;
2133 newTj.
Pts[ipt].Chg = 0;
2138 if(splittingMuon)
SetPDGCode(slc, newTj,
true);
2139 if(ivx < slc.
vtxs.size()) newTj.
VtxID[0] = slc.
vtxs[ivx].ID;
2144 slc.
tjs.push_back(newTj);
2158 float best = minSep * minSep;
2159 closePt = USHRT_MAX;
2162 for(ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
2163 dw = tj.
Pts[ipt].Pos[0] - tp.
Pos[0];
2164 dt = tj.
Pts[ipt].Pos[1] - tp.
Pos[1];
2165 dp2 = dw * dw + dt * dt;
2171 minSep = sqrt(best);
2177 return TrajTrajDOCA(slc, tj1, tj2, ipt1, ipt2, minSep,
false);
2186 for(
unsigned short iwt = 0; iwt < 2; ++iwt) {
2189 float wt0 = tj1.
Pts[tj1.
EndPt[0]].Pos[iwt];
2190 float wt1 = tj1.
Pts[tj1.
EndPt[1]].Pos[iwt];
2198 wt0 = tj2.
Pts[tj2.
EndPt[0]].Pos[iwt];
2199 wt1 = tj2.
Pts[tj2.
EndPt[1]].Pos[iwt];
2209 if(lowt2 > hiwt1 + minSep)
return false;
2211 if(lowt1 > hiwt2 + minSep)
return false;
2214 float best = minSep * minSep;
2217 bool isClose =
false;
2218 for(
unsigned short i1 = tj1.
EndPt[0]; i1 < tj1.
EndPt[1] + 1; ++i1) {
2219 for(
unsigned short i2 = tj2.
EndPt[0]; i2 < tj2.
EndPt[1] + 1; ++i2) {
2221 float dw = tj1.
Pts[i1].Pos[0] - tj2.
Pts[i2].Pos[0] - dwc;
2222 if(std::abs(dw) > minSep)
continue;
2223 float dt = tj1.
Pts[i1].Pos[1] - tj2.
Pts[i2].Pos[1];
2224 if(std::abs(dt) > minSep)
continue;
2225 float dp2 = dw * dw + dt * dt;
2234 minSep = sqrt(best);
2242 if(iht > slc.
slHits.size()-1 || jht > slc.
slHits.size()-1)
return 1E6;
2245 float dw = (float)ihit.WireID().Wire - (float)jhit.WireID().Wire;
2247 return dw * dw + dt * dt;
2253 unsigned short endPt = tj.
EndPt[0];
2254 auto& tp0 = tj.
Pts[endPt];
2255 endPt = tj.
EndPt[1];
2256 auto& tp1 = tj.
Pts[endPt];
2264 float dw = wire - tp.
Pos[0];
2265 float dt = time - tp.
Pos[1];
2266 return dw * dw + dt * dt;
2272 if(iht > slc.
slHits.size() - 1)
return 1E6;
2274 float wire =
hit.WireID().Wire;
2291 double t = (double)(wire - tp.
Pos[0]) * tp.
Dir[0] + (double)(time - tp.
Pos[1]) * tp.
Dir[1];
2292 double dw = tp.
Pos[0] + t * tp.
Dir[0] - wire;
2293 double dt = tp.
Pos[1] + t * tp.
Dir[1] - time;
2294 return (
float)(dw * dw + dt * dt);
2308 x = -9999; y = -9999;
2310 double arg1 = tp1.
Pos[0] * tp1.
Dir[1] - tp1.
Pos[1] * tp1.
Dir[0];
2311 double arg2 = tp2.
Pos[0] * tp1.
Dir[1] - tp2.
Pos[1] * tp1.
Dir[0];
2312 double arg3 = tp2.
Dir[0] * tp1.
Dir[1] - tp2.
Dir[1] * tp1.
Dir[0];
2313 if(arg3 == 0)
return;
2314 double s = (arg1 - arg2) / arg3;
2316 x = (float)(tp2.
Pos[0] + s * tp2.
Dir[0]);
2317 y = (float)(tp2.
Pos[1] + s * tp2.
Dir[1]);
2325 if(tjIDs.empty())
return 0;
2327 for(
auto tjid : tjIDs) {
2328 if(tjid < 1 || tjid > (
int)slc.
tjs.size())
continue;
2329 auto& tj = slc.
tjs[tjid - 1];
2330 float sep2 =
PosSep2(tj.Pts[tj.EndPt[0]].Pos, tj.Pts[tj.EndPt[1]].Pos);
2331 if(sep2 > maxLen) maxLen = sep2;
2333 return sqrt(maxLen);
2339 float len = 0, dx, dy;
2341 unsigned short prevPt = tj.
EndPt[0];
2342 for(ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1] + 1; ++ipt) {
2343 if(tj.
Pts[ipt].Chg == 0)
continue;
2344 dx = tj.
Pts[ipt].Pos[0] - tj.
Pts[prevPt].Pos[0];
2345 dy = tj.
Pts[ipt].Pos[1] - tj.
Pts[prevPt].Pos[1];
2346 len += sqrt(dx * dx + dy * dy);
2355 return sqrt(
PosSep2(pos1, pos2));
2362 float d0 = pos1[0] - pos2[0];
2363 float d1 = pos1[1] - pos2[1];
2371 float dx = tp1.
Pos[0] - tp2.
Pos[0];
2372 float dy = tp1.
Pos[1] - tp2.
Pos[1];
2373 return sqrt(dx * dx + dy * dy);
2383 float close2 = DOCA * DOCA;
2385 bool foundClose =
false;
2387 for(
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1] + 1; ++ipt) {
2388 if(tj.
Pts[ipt].Chg == 0)
continue;
2389 float dx = tj.
Pts[ipt].Pos[0] -
x;
2390 if(std::abs(dx) > DOCA)
continue;
2391 float dy = tj.
Pts[ipt].Pos[1] -
y;
2392 if(std::abs(dy) > DOCA)
continue;
2393 float sep2 = dx * dx + dy * dy;
2401 DOCA = sqrt(close2);
2410 float dw = tp2.
Pos[0] - tp1.
Pos[0];
2411 float dt = tp2.
Pos[1] - tp1.
Pos[1];
2412 return atan2(dw, dt);
2419 std::vector<unsigned int> hitVec;
2423 for(
auto& tp : tj.
Pts) hitVec.insert(hitVec.end(), tp.Hits.begin(), tp.Hits.end());
2428 hitVec.reserve(tj.
Pts.size());
2429 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2430 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
2431 unsigned int iht = tj.
Pts[ipt].Hits[ii];
2432 bool useit = (hitRequest ==
kAllHits);
2433 if(tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUsedHits) useit =
true;
2434 if(!tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUnusedHits) useit =
true;
2435 if(useit) hitVec.push_back(iht);
2449 if(tj.
Pts.size() > 10)
return;
2452 unsigned short nhm = 0;
2453 unsigned short npwc = 0;
2454 for(
auto& tp : tj.
Pts) {
2455 if(tp.Chg == 0)
continue;
2457 unsigned short nused = 0;
2458 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
2459 if(tp.UseHit[ii]) ++nused;
2461 if(nused > 3) ++nhm;
2473 for(
unsigned short ii = 0; ii < tjHits.size() - 1; ++ii) {
2474 for(
unsigned short jj = ii + 1; jj < tjHits.size(); ++jj) {
2475 if(tjHits[ii] == tjHits[jj]) {
2488 if(tp.
Dir[0] == 0)
return;
2489 float dw = wire - tp.
Pos[0];
2490 if(std::abs(dw) < 0.01)
return;
2492 tp.
Pos[1] += dw * tp.
Dir[1] / tp.
Dir[0];
2512 std::vector<unsigned int> closeHits;
2513 if(plane > slc.
firstWire.size() - 1)
return closeHits;
2515 int loWire = wireWindow[0];
2517 int hiWire = wireWindow[1];
2522 for(
int wire = loWire; wire <= hiWire; ++wire) {
2524 if(slc.
wireHitRange[plane][wire].first == -2) hitsNear =
true;
2526 unsigned int firstHit = (
unsigned int)slc.
wireHitRange[plane][wire].first;
2527 unsigned int lastHit = (
unsigned int)slc.
wireHitRange[plane][wire].second;
2528 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2531 if(
hit.PeakTime() < minTick)
continue;
2532 if(
hit.PeakTime() > maxTick)
break;
2535 if(
hit.StartTick() > hiLo) hiLo =
hit.StartTick();
2537 if(
hit.EndTick() < loHi) loHi =
hit.EndTick();
2538 if(loHi < hiLo)
continue;
2539 if(hiLo > loHi)
break;
2542 bool takeit = (hitRequest ==
kAllHits);
2543 if(hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) takeit =
true;
2545 if(takeit) closeHits.push_back(iht);
2564 unsigned short ipl = planeID.
Plane;
2565 if(tp.
Pos[0] < -0.4)
return false;
2566 unsigned int wire = std::nearbyint(tp.
Pos[0]);
2567 if(wire < slc.
firstWire[ipl])
return false;
2568 if(wire > slc.
lastWire[ipl]-1)
return false;
2577 if(slc.
wireHitRange[ipl][wire].first == -2)
return false;
2579 unsigned int firstHit = (
unsigned int)slc.
wireHitRange[ipl][wire].first;
2580 unsigned int lastHit = (
unsigned int)slc.
wireHitRange[ipl][wire].second;
2583 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2584 if((
unsigned int)slc.
slHits[iht].InTraj > slc.
tjs.size())
continue;
2585 bool useit = (hitRequest ==
kAllHits);
2586 if(hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
2588 if(!useit)
continue;
2592 if(delta < maxDelta) tp.
Hits.push_back(iht);
2594 if(tp.
Hits.size() > 16) {
2599 return (!tp.
Hits.empty());
2622 std::vector<int>
tmp;
2623 if(fromTp.
Pos[0] < -0.4 || toTp.
Pos[0] < -0.4)
return tmp;
2627 unsigned int firstWire, lastWire;
2628 if(toTp.
Pos[0] > fromTp.
Pos[0]) {
2630 firstWire = std::nearbyint(fromTp.
Pos[0]);
2631 lastWire = std::nearbyint(toTp.
Pos[0]);
2632 }
else if(toTp.
Pos[0] < fromTp.
Pos[0]) {
2634 firstWire = std::nearbyint(toTp.
Pos[0]);
2635 lastWire = std::nearbyint(fromTp.
Pos[0]);
2638 float tmp = fromTp.
Pos[0] - maxDelta;
2639 if(tmp < 0) tmp = 0;
2640 firstWire = std::nearbyint(tmp);
2641 tmp = fromTp.
Pos[0] + maxDelta;
2642 lastWire = std::nearbyint(tmp);
2646 unsigned short ipl = planeID.
Plane;
2653 for(
unsigned int wire = firstWire; wire <= lastWire; ++wire) {
2660 unsigned int firstHit = (
unsigned int)slc.
wireHitRange[ipl][wire].first;
2661 unsigned int lastHit = (
unsigned int)slc.
wireHitRange[ipl][wire].second;
2662 for(
unsigned int iht = firstHit; iht < lastHit; ++iht) {
2663 if(slc.
slHits[iht].InTraj <= 0)
continue;
2664 if((
unsigned int)slc.
slHits[iht].InTraj > slc.
tjs.size())
continue;
2666 if(
hit.PeakTime() < minTick)
continue;
2668 if(
hit.PeakTime() > maxTick)
break;
2669 if(std::find(tmp.begin(), tmp.end(), slc.
slHits[iht].InTraj) != tmp.end())
continue;
2670 tmp.push_back(slc.
slHits[iht].InTraj);
2685 unsigned short midPt = 0.5 * (tj.
EndPt[0] + tj.
EndPt[1]);
2686 double rms0 = 0, rms1 = 0;
2690 asym = std::abs(rms0 - rms1) / (rms0 + rms1);
2691 float chgFact = (tj.
ChgRMS - 0.1) * 5;
2692 float elh = 5 * asym * chgFact;
2693 if(elh > 1) elh = 1;
2702 if(tjIDs.empty())
return 0;
2703 std::array<int, 2> wireWindow;
2706 constexpr
float NNDelta = 5;
2707 wireWindow[0] = pos[0] - NNDelta;
2708 wireWindow[1] = pos[0] + NNDelta;
2709 timeWindow[0] = pos[1] - NNDelta;
2710 timeWindow[1] = pos[1] + NNDelta;
2712 for(
auto& tjID : tjIDs)
if(tjID <= 0 || tjID > (
int)slc.
tjs.size())
return 0;
2718 if(closeHits.empty())
return 0;
2723 for(
auto& iht : closeHits) {
2725 chg +=
hit.Integral();
2726 if(slc.
slHits[iht].InTraj == 0)
continue;
2727 if(std::find(tjIDs.begin(), tjIDs.end(), slc.
slHits[iht].InTraj) != tjIDs.end()) tchg +=
hit.Integral();
2729 if(chg == 0)
return 0;
2736 float delta, md = 0;
2739 for(
auto& tp : tj.
Pts) {
2740 for(ii = 0; ii < tp.Hits.size(); ++ii) {
2741 if(!tp.UseHit[ii])
continue;
2744 if(delta > md) md = delta;
2754 if(tj.
Pts.empty())
return;
2761 std::reverse(tj.
Pts.begin(), tj.
Pts.end());
2766 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2767 if(tj.
Pts[ipt].Dir[0] != 0) tj.
Pts[ipt].Dir[0] = -tj.
Pts[ipt].Dir[0];
2768 if(tj.
Pts[ipt].Dir[1] != 0) tj.
Pts[ipt].Dir[1] = -tj.
Pts[ipt].Dir[1];
2769 if(tj.
Pts[ipt].Ang > 0) {
2770 tj.
Pts[ipt].Ang -= M_PI;
2772 tj.
Pts[ipt].Ang += M_PI;
2789 unsigned short nvx = Envelope.size();
2790 double angleSum = 0;
2791 for(
unsigned short ii = 0; ii < Envelope.size(); ++ii) {
2792 p1[0] = Envelope[ii][0] - Point[0];
2793 p1[1] = Envelope[ii][1] - Point[1];
2794 p2[0] = Envelope[(ii+1)%nvx][0] - Point[0];
2795 p2[1] = Envelope[(ii+1)%nvx][1] - Point[1];
2798 if(abs(angleSum) < M_PI)
return false;
2807 double den = v1[0] * v1[0] + v1[1] * v1[1];
2808 if(den == 0)
return false;
2822 if(pos1[0] == pos2[0] && pos1[1] == pos2[1])
return;
2823 pos1[0] = pos2[0] - pos1[0];
2824 pos1[1] = pos2[1] - pos1[1];
2825 double sep = sqrt(pos1[0] * pos1[0] + pos1[1] * pos1[1]);
2826 if(sep < 1
E-6)
return;
2828 ptDir[0] = pos1[0] / sep;
2829 ptDir[1] = pos1[1] / sep;
2831 double costh =
DotProd(dir1, ptDir);
2832 if(costh > 1.0 || costh < -1.0)
return;
2833 alongTrans[0] = costh * sep;
2834 double sinth = sqrt(1 - costh * costh);
2835 alongTrans[1] = sinth * sep;
2842 double ang1 = atan2(p1[1], p1[0]);
2843 double ang2 = atan2(p2[1], p2[0]);
2850 constexpr
double twopi = 2 * M_PI;
2851 double dang = Ang1 - Ang2;
2852 while(dang > M_PI) dang -= twopi;
2853 while(dang < -M_PI) dang += twopi;
2860 return std::abs(std::remainder(Ang1 - Ang2, M_PI));
2872 if(tj.
Pts.size() == 0)
return;
2875 for(
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2876 if(tj.
Pts[ipt].Chg != 0) {
2881 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
2882 unsigned short ipt = tj.
Pts.size() - 1 - ii;
2883 if(tj.
Pts[ipt].Chg != 0) {
2895 unsigned short nUsed = 0;
2896 unsigned short nTotHits = 0;
2897 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
2899 nTotHits += tp.
Hits.size();
2900 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
2901 if(tp.
UseHit[ii]) ++nUsed;
2904 if(nTotHits == 0)
return false;
2905 float fracUsed = (float)nUsed / (
float)nTotHits;
2906 if(prt)
mf::LogVerbatim(
"TC")<<
"TrajIsClean: nTotHits "<<nTotHits<<
" nUsed "<<nUsed<<
" fracUsed "<<fracUsed;
2908 if(fracUsed > 0.9)
return true;
2917 if(tjIDs.empty())
return 0;
2920 for(
auto tjid : tjIDs) {
2921 auto& tj = slc.
tjs[tjid - 1];
2922 float npts = tj.EndPt[1] - tj.EndPt[0] + 1;
2923 summ += npts * tj.MCSMom;
2926 return (
short)(summ / suml);
2940 if(firstPt == lastPt)
return 0;
2941 if(firstPt > lastPt) std::swap(firstPt, lastPt);
2945 if(firstPt >= lastPt)
return 0;
2947 if(firstPt < tj.
EndPt[0])
return 0;
2948 if(lastPt > tj.
EndPt[1])
return 0;
2955 if(tjLen < 1)
return 0;
2957 double thetaRMS =
MCSThetaRMS(slc, tj, firstPt, lastPt);
2958 if(thetaRMS < 0.001)
return 999;
2959 double mom = 13.8 * sqrt(tjLen / 14) / thetaRMS;
2960 if(mom > 999) mom = 999;
2969 if(thePt > tj.
EndPt[1])
return thePt;
2970 if(tj.
Pts[thePt].Chg > 0)
return thePt;
2972 short endPt0 = tj.
EndPt[0];
2973 short endPt1 = tj.
EndPt[1];
2974 for(
short off = 1; off < 10; ++off) {
2975 short ipt = thePt + off;
2976 if(ipt <= endPt1 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
2978 if(ipt >= endPt0 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
2991 if(tps < 1)
return 1;
3003 if(firstPt < tj.
EndPt[0])
return 1;
3004 if(lastPt > tj.
EndPt[1])
return 1;
3008 if(firstPt >= lastPt)
return 1;
3012 TjDeltaRMS(slc, tj, firstPt, lastPt, sigmaS, cnt);
3013 if(sigmaS < 0)
return 1;
3022 if(tjLen < 1)
return 1;
3024 return (6.8 * sigmaS / tjLen);
3034 if(firstPt < tj.
EndPt[0])
return;
3035 if(lastPt > tj.
EndPt[1])
return;
3039 if(firstPt >= lastPt)
return;
3052 for(
unsigned short ipt = firstPt + 1; ipt < lastPt; ++ipt) {
3053 if(tj.
Pts[ipt].Chg == 0)
continue;
3060 rms = sqrt(dsum / (
double)cnt);
3085 unsigned short minpts = 4;
3086 if(prt)
mf::LogVerbatim(
"TC")<<
"TagDeltaRays: maxSep "<<maxSep<<
" maxMinSep "<<maxMinSep<<
" Mom range "<<minMom<<
" to "<<maxMom<<
" minpts "<<minpts;
3088 for(
unsigned short itj = 0; itj < slc.
tjs.size(); ++itj) {
3090 if(muTj.
CTP != inCTP)
continue;
3092 if(muTj.
PDGCode != 13)
continue;
3095 if(muTj.
EndPt[1] - muTj.
EndPt[0] < minMuonLength)
continue;
3096 auto& mtp0 = muTj.
Pts[muTj.
EndPt[0]];
3097 auto& mtp1 = muTj.
Pts[muTj.
EndPt[1]];
3099 for(
unsigned short jtj = 0; jtj < slc.
tjs.size(); ++jtj) {
3100 if(jtj == itj)
continue;
3103 if(dtj.
CTP != inCTP)
continue;
3104 if(dtj.
PDGCode == 13)
continue;
3106 if(dtj.
MCSMom < minMom)
continue;
3107 if(dtj.
MCSMom > maxMom)
continue;
3108 if(dtj.
EndPt[1] - dtj.
EndPt[0] < minpts)
continue;
3111 auto& dtp0 = dtj.
Pts[dtj.
EndPt[0]];
3112 auto& dtp1 = dtj.
Pts[dtj.
EndPt[1]];
3114 if(dtp0.Pos[0] < mtp0.Pos[0])
continue;
3115 if(dtp1.Pos[0] > mtp1.Pos[0])
continue;
3117 if(dtp0.Pos[0] > mtp0.Pos[0])
continue;
3118 if(dtp1.Pos[0] < mtp1.Pos[0])
continue;
3121 float doca = maxMinSep;
3122 unsigned short mpt = 0;
3123 unsigned short dpt = 0;
3125 if(doca == maxMinSep)
continue;
3126 auto& dTp = dtj.
Pts[dpt];
3134 bool closeDeltaRay = (doca < 2 && dtj.
MCSMom < 20);
3135 if(!closeDeltaRay && dang >
tcc.
kinkCuts[0])
continue;
3136 unsigned short oend = 0;
3139 if(dpt > 0.5 * (dtj.
EndPt[0] + dtj.
EndPt[1])) oend = 1;
3140 auto& farEndTP = dtj.
Pts[dtj.
EndPt[oend]];
3141 float farEndDelta =
PointTrajDOCA(slc, farEndTP.Pos[0], farEndTP.Pos[1], muTj.
Pts[mpt]);
3143 if(farEndDelta > maxSep)
continue;
3207 std::string fcnLabel = inFcnLabel +
".UpTjProp";
3210 for(
auto& tp : tj.
Pts) {
3211 if(tp.Chg <= 0)
continue;
3213 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
3214 if(tp.UseHit[ii])
continue;
3215 unsigned int iht = tp.Hits[ii];
3216 if(slc.
slHits[iht].InTraj == 0) {
3245 for(
unsigned short ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1]; ++ipt) {
3246 auto& tp = tj.
Pts[ipt];
3247 if(tp.Chg > bigChg) bigChg = tp.Chg;
3254 for(
unsigned short ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1]; ++ipt) {
3255 auto& tp = tj.
Pts[ipt];
3256 if(tp.Chg <= 0)
continue;
3258 if(tp.Chg == bigChg)
continue;
3263 bsum2 += tp.Chg * tp.Chg;
3264 if(tp.Chg > bigChg) bigChg = tp.Chg;
3270 for(
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
3271 if(!tp.UseHit[ii])
continue;
3272 unsigned int iht = tp.Hits[ii];
3276 vsum2 += tpchg * tpchg;
3279 if(bcnt == 0)
return;
3287 if(arg > 0) tj.
ChgRMS = sqrt(arg / (bcnt - 1));
3289 for(
auto& tp : tj.
Pts) tp.AveChg = tj.
AveChg;
3293 double nWires = tj.
EndPt[1] - tj.
EndPt[0] + 1;
3294 if(nWires < 2)
return;
3299 for(
unsigned short end = 0;
end < 2; ++
end) {
3303 int dw = std::abs(tp.Pos[0] - vx2.Pos[0]);
3315 if(arg > 0) rms = sqrt(arg / (vcnt - 1));
3318 if(rms < 0.1) rms = 0.1;
3322 double defFrac = 1 / vcnt;
3323 rms = defFrac * 0.5 + (1 - defFrac) * rms;
3331 for(
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
3332 auto& tp = tj.
Pts[ipt];
3333 if(tp.Chg <= 0)
continue;
3340 for(
auto& tp : tj.
Pts) tp.AveChg = tj.
AveChg;
3345 for(
auto& tp : tj.
Pts) tp.AveChg = 0;
3348 unsigned short minPt = tj.
EndPt[0] + nptsave;
3350 for(
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
3351 unsigned short ipt = tj.
EndPt[1] - ii;
3352 if(ipt < minPt)
break;
3355 for(
unsigned short iii = 0; iii < nptsave; ++iii) {
3356 unsigned short iipt = ipt - iii;
3358 if(iipt == tj.
EndPt[0])
break;
3359 auto& tp = tj.
Pts[iipt];
3360 if(tp.Chg <= 0)
continue;
3365 tj.
Pts[ipt].AveChg = sum / cnt;
3366 lastAve = tj.
Pts[ipt].AveChg;
3370 for(
unsigned short ii = tj.
EndPt[0]; ii <= tj.
EndPt[1]; ++ii) {
3371 unsigned short ipt = tj.
EndPt[1] - ii;
3372 auto& tp = tj.
Pts[ipt];
3373 if(tp.AveChg == 0) {
3374 tp.AveChg = lastAve;
3376 lastAve = tp.AveChg;
3390 if(vx2.
ID == 0)
return;
3393 std::string fcnLabel = inFcnLabel +
".UpVxProp";
3395 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" UpdateTjEnvironment check Tjs attached to vx2 "<<vx2.
ID;
3397 std::vector<int> tjlist;
3398 std::vector<unsigned short> tjends;
3399 if(vx2.
Pos[0] < -0.4)
return;
3400 unsigned int vxWire = std::nearbyint(vx2.
Pos[0]);
3401 unsigned int loWire = vxWire;
3402 unsigned int hiWire = vxWire;
3403 for(
auto& tj : slc.
tjs) {
3405 if(tj.CTP != vx2.
CTP)
continue;
3407 if(tj.AlgMod[
kPhoton])
continue;
3408 for(
unsigned short end = 0;
end < 2; ++
end) {
3409 if(tj.VtxID[
end] != vx2.
ID)
continue;
3410 tjlist.push_back(tj.ID);
3411 tjends.push_back(
end);
3412 if(tj.Pts[tj.EndPt[
end]].Pos[0] < -0.4)
return;
3413 unsigned int endWire = std::nearbyint(tj.Pts[tj.EndPt[
end]].Pos[0]);
3414 if(endWire < loWire) loWire = endWire;
3415 if(endWire > hiWire) hiWire = endWire;
3418 if(tjlist.size() < 2)
return;
3419 if(hiWire < loWire + 1)
return;
3420 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" check Tjs on wires in the range "<<loWire<<
" to "<<hiWire;
3424 std::vector<std::vector<TrajPoint>> wire_tjpt;
3426 std::vector<int> tjids;
3428 unsigned short nwires = hiWire - loWire + 1;
3429 for(
unsigned short itj = 0; itj < tjlist.size(); ++itj) {
3430 auto& tj = slc.
tjs[tjlist[itj] - 1];
3431 unsigned short end = tjends[itj];
3432 std::vector<TrajPoint> tjpt(nwires);
3434 for(
unsigned short ii = 0; ii < tj.Pts.size(); ++ii) {
3436 if(end == 0) { ipt = tj.EndPt[0] + ii; }
else { ipt = tj.EndPt[1] - ii; }
3437 if(ipt > tj.Pts.size() - 1)
break;
3439 auto tp = tj.Pts[ipt];
3440 if(tp.Chg <= 0)
continue;
3443 if(tp.Pos[0] < -0.4)
continue;
3444 unsigned int wire = std::nearbyint(tp.Pos[0]);
3445 unsigned short indx = wire - loWire;
3446 if(indx > nwires - 1)
break;
3456 if(ltp.
Dir[0] == 0)
continue;
3457 if(ltp.
Pos[0] < -0.4)
continue;
3458 unsigned int wire = std::nearbyint(ltp.
Pos[0]);
3460 unsigned short indx = wire - loWire;
3462 if(tjpt[indx].Chg == 0) tjpt[indx] = ltp;
3463 double stepSize = std::abs(1/ltp.
Dir[0]);
3464 for(
unsigned short ii = 0; ii < nwires; ++ii) {
3466 for(
unsigned short iwt = 0; iwt < 2; ++iwt) ltp.
Pos[iwt] += ltp.
Dir[iwt] * stepSize;
3467 if(ltp.
Pos[0] < -0.4)
break;
3468 wire = std::nearbyint(ltp.
Pos[0]);
3469 if(wire < loWire || wire > hiWire)
break;
3470 indx = wire - loWire;
3471 if(tjpt[indx].Chg > 0)
continue;
3476 myprt<<fcnLabel<<
" T"<<tj.ID;
3477 for(
auto& tp : tjpt) myprt<<
" "<<
PrintPos(slc, tp.Pos)<<
"_"<<tp.Step<<
"_"<<(int)tp.Chg;
3479 wire_tjpt.push_back(tjpt);
3480 tjids.push_back(tj.ID);
3484 for(
unsigned short indx = 0; indx < nwires; ++indx) {
3486 unsigned short npts = 0;
3488 unsigned short npwc = 0;
3489 for(
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
3490 if(wire_tjpt[itj][indx].Pos[0] == 0)
continue;
3493 if(wire_tjpt[itj][indx].Chg > 0) ++npwc;
3497 if(npts == 0)
continue;
3499 if(npwc == npts)
continue;
3501 for(
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
3502 if(wire_tjpt[itj][indx].Pos[0] == 0)
continue;
3503 if(wire_tjpt[itj][indx].Chg == 0)
continue;
3504 auto& tj = slc.
tjs[tjids[itj] - 1];
3505 unsigned short ipt = wire_tjpt[itj][indx].Step;
3507 tj.NeedsUpdate =
true;
3508 if(prt)
mf::LogVerbatim(
"TC")<<fcnLabel<<
" Set kEnvOverlap bit on T"<<tj.ID<<
" ipt "<<ipt;
3513 for(
auto tjid : tjids) {
3514 auto& tj = slc.
tjs[tjid - 1];
3515 if(!tj.NeedsUpdate)
continue;
3516 if(tj.CTP != vx2.
CTP)
continue;
3542 if(dir[0] == 0 && dir[1] == 0 && dir[2] == 0)
return tp;
3547 Point3_t pos3 = {{100 * dir[0], 100 * dir[1], 100 * dir[2]}};
3549 std::array<double, 2> ori2;
3550 std::array<double, 2> pos2;
3551 std::array<double, 2> dir2;
3559 dir2[0] = pos2[0] - ori2[0];
3560 dir2[1] = pos2[1] - ori2[1];
3562 double norm = sqrt(dir2[0] * dir2[0] + dir2[1] * dir2[1]);
3565 tp.
Ang = atan2(dir2[1], dir2[0]);
3566 tp.
Delta = norm / 100;
3574 norm = sqrt(cs * cs + sn * sn);
3583 if(fromHit > slc.
slHits.size() - 1)
return false;
3584 if(toHit > slc.
slHits.size() - 1)
return false;
3589 (float)thit.WireID().Wire, thit.PeakTime(), tCTP, tp);
3597 tp.
Pos[0] = fromWire;
3599 tp.
Dir[0] = toWire - fromWire;
3602 if(norm == 0)
return false;
3612 tpOut.
Pos = fromPos;
3622 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
3641 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
3649 if(tj.
ID == 0)
return 0;
3659 for(
unsigned short xyz = 0; xyz < 2; ++xyz) dir[xyz] = p2[xyz] - p1[xyz];
3660 if(dir[0] == 0 && dir[1] == 0)
return dir;
3661 double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
3678 if(tp.
Hits.empty())
return 0;
3679 float minVal = 9999;
3681 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
3682 bool useit = (hitRequest ==
kAllHits);
3685 if(!useit)
continue;
3686 unsigned int iht = tp.
Hits[ii];
3688 float cv =
hit.PeakTime();
3689 float rms =
hit.RMS();
3690 float arg = cv - rms;
3691 if(arg < minVal) minVal = arg;
3693 if(arg > maxVal) maxVal = arg;
3695 if(maxVal == 0)
return 0;
3696 return (maxVal - minVal) / 2;
3708 if(hitsInMultiplet.empty())
return 0;
3710 if(hitsInMultiplet.size() == 1) {
3715 float minVal = 9999;
3717 for(
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
3718 unsigned int iht = hitsInMultiplet[ii];
3719 bool useit = (hitRequest ==
kAllHits);
3720 if(hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
3722 if(!useit)
continue;
3724 float cv =
hit.PeakTime();
3725 float rms =
hit.RMS();
3726 float arg = cv - rms;
3727 if(arg < minVal) minVal = arg;
3729 if(arg > maxVal) maxVal = arg;
3731 if(maxVal == 0)
return 0;
3732 return (maxVal - minVal) / 2;
3747 for(
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
3748 unsigned int iht = hitsInMultiplet[ii];
3749 bool useit = (hitRequest ==
kAllHits);
3750 if(hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
3752 if(!useit)
continue;
3754 float chg =
hit.Integral();
3755 pos += chg *
hit.PeakTime();
3758 if(sum == 0)
return 0;
3766 if(tj.
Pts.empty())
return 0;
3767 unsigned short nhits = 0;
3768 for(
auto& tp : tj.
Pts) {
3769 for(
unsigned short ii = 0; ii < tp.Hits.size(); ++ii)
if(tp.UseHit[ii]) ++nhits;
3778 if(tp.
Hits.empty())
return 0;
3782 unsigned short nhits = 0;
3783 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
3785 if(tp.
UseHit[ii]) ++nhits;
3788 if(!tp.
UseHit[ii]) ++nhits;
3797 if(itj > slc.
tjs.size() - 1)
return;
3827 if(npwc > 500) isAMuon =
true;
3829 std::cout<<
"T"<<tj.
ID<<
" changing PDGCode from "<<tj.
PDGCode<<
" to 13. Is this wise?\n";
3886 unsigned short cstat = (*
evt.
allHits)[0].WireID().Cryostat;
3887 unsigned short tpc = (*
evt.
allHits)[0].WireID().TPC;
3891 std::vector<float> cnt(nplanes, 0);
3892 for(
unsigned short iht = 0; iht < (*
evt.
allHits).size(); ++iht) {
3894 unsigned short plane =
hit.WireID().Plane;
3895 if(plane > nplanes - 1) {
3896 std::cout<<
"AnalyzeHits found bad plane\n";
3899 if(cnt[plane] > 200)
continue;
3901 if(
hit.Multiplicity() != 1)
continue;
3903 if(
hit.GoodnessOfFit() < 0 ||
hit.GoodnessOfFit() > 500)
continue;
3905 if(
hit.PeakAmplitude() < 1)
continue;
3909 bool allDone =
true;
3910 for(
unsigned short plane = 0; plane < nplanes; ++plane)
if(cnt[plane] < 200) allDone =
false;
3916 for(
unsigned short plane = 0; plane < nplanes; ++plane) {
3917 if(cnt[plane] > 4) {
3926 std::cout<<
"Analyze hits aveHitRMS";
3927 std::cout<<std::fixed<<std::setprecision(1);
3955 std::cout<<
"FillWireHitRange: crazy nPlanes "<<nplanes<<
"\n";
3960 double local[3] = {0.,0.,0.};
3961 double world[3] = {0.,0.,0.};
3978 slc.
nWires.resize(nplanes);
3983 std::pair<int, int> flag;
3984 flag.first = -2; flag.second = -2;
3997 for(
unsigned short plane = 0; plane < nplanes; ++plane) {
4007 flag.first = -1; flag.second = -1;
4008 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
4009 for(
unsigned int wire = 0; wire < slc.
nWires[ipl]; ++wire) {
4011 if(!channelStatus.IsGood(chan)) slc.
wireHitRange[ipl][wire] = flag;
4015 unsigned int lastWire = 0, lastPlane = 0;
4016 for(
unsigned int iht = 0; iht < slc.
slHits.size(); ++iht) {
4018 if(
hit.WireID().Cryostat != cstat)
continue;
4019 if(
hit.WireID().TPC != tpc)
continue;
4020 unsigned short plane =
hit.WireID().Plane;
4021 unsigned int wire =
hit.WireID().Wire;
4022 if(wire > slc.
nWires[plane] - 1) {
4023 mf::LogWarning(
"TC")<<
"FillWireHitRange: Invalid wire number "<<wire<<
" > "<<slc.
nWires[plane] - 1<<
" in plane "<<plane<<
" Quitting";
4026 if(plane == lastPlane && wire < lastWire) {
4027 mf::LogWarning(
"TC")<<
"FillWireHitRange: Hits are not in increasing wire order. Quitting ";
4042 std::cout<<
"tpc "<<tpc<<
" tcc.unitsPerTick "<<std::setprecision(3)<<
tcc.
unitsPerTick<<
"\n";
4043 std::cout<<
"Active volume (";
4044 std::cout<<std::fixed<<std::setprecision(1)<<slc.
xLo<<
" < X < "<<slc.
xHi<<
") (";
4045 std::cout<<std::fixed<<std::setprecision(1)<<slc.
yLo<<
" < Y < "<<slc.
yHi<<
") (";
4046 std::cout<<std::fixed<<std::setprecision(1)<<slc.
zLo<<
" < Z < "<<slc.
zHi<<
")\n";
4102 if(itj1 > slc.
tjs.size() - 1)
return false;
4103 if(itj2 > slc.
tjs.size() - 1)
return false;
4113 if(pfp1 != USHRT_MAX || pfp2 != USHRT_MAX) {
4114 if(pfp1 != USHRT_MAX && pfp2 != USHRT_MAX) {
4119 if(pfp1 == USHRT_MAX) std::swap(itj1, itj2);
4140 std::swap(tj1, tj2);
4141 std::swap(tp1e0, tp2e0);
4142 std::swap(tp1e1, tp2e1);
4158 if(tp2e0[0] > tp1e0[0] && tp2e1[0] < tp1e1[0])
return false;
4162 if(tp1e0[0] > tp2e0[0] && tp1e1[0] < tp2e1[0])
return false;
4165 if(tp2e1[0] > tp1e1[0] && tp2e0[0] < tp1e0[0])
return false;
4166 if(tp1e1[0] > tp2e1[0] && tp1e0[0] < tp2e0[0])
return false;
4172 if(doPrt)
mf::LogVerbatim(
"TC")<<
"MergeAndStore: Found a good vertex between Tjs "<<tj1.
VtxID[1]<<
" No merging";
4178 if(doPrt)
mf::LogVerbatim(
"TC")<<
"MergeAndStore: You are merging the end of trajectory T"<<tj1.
ID<<
" with a Bragg peak. Not merging\n";
4189 float minSep = 1000;
4190 unsigned short tj2ClosePt = 0;
4195 if(tj2ClosePt > tj2.
EndPt[1])
return false;
4204 std::vector<unsigned int> tj1Hits;
4205 for(
unsigned short ii = 0; ii < tj1.
Pts.size(); ++ii) {
4208 unsigned short ipt = tj1.
Pts.size() - 1 - ii;
4209 tj1Hits.insert(tj1Hits.end(), tj1.
Pts[ipt].Hits.begin(), tj1.
Pts[ipt].Hits.end());
4213 bool bumpedPt =
true;
4216 for(
unsigned short ii = 0; ii < tj2.
Pts[tj2ClosePt].Hits.size(); ++ii) {
4217 unsigned int iht = tj2.
Pts[tj2ClosePt].Hits[ii];
4218 if(std::find(tj1Hits.begin(), tj1Hits.end(), iht) != tj1Hits.end()) bumpedPt =
true;
4220 if(bumpedPt && tj2ClosePt < tj2.
EndPt[1]) {
4229 tj1.
Pts.insert(tj1.
Pts.end(), tj2.
Pts.begin() + tj2ClosePt, tj2.
Pts.end());
4237 mf::LogVerbatim(
"TC")<<
"MergeAndStore found duplicate hits. Coding error";
4244 if(tj2.
VtxID[1] > 0) {
4264 int newTjID = slc.
tjs.size();
4273 for(
auto& tj : slc.
tjs)
if(tj.ParentID == tj1ID || tj.ParentID == tj2ID) tj.ParentID = newTjID;
4279 std::vector<int>
GetAssns(
TCSlice& slc, std::string type1Name,
int id, std::string type2Name)
4284 std::vector<int>
tmp;
4285 if(
id <= 0)
return tmp;
4286 unsigned int uid = id;
4288 if(type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"P") {
4290 for(
auto& pfp : slc.
pfps) {
4291 if(pfp.ID <= 0)
continue;
4292 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), id) != pfp.TjIDs.end()) tmp.push_back(pfp.ID);
4297 if(type1Name ==
"P" && uid <= slc.
pfps.size() && (type2Name ==
"2S" || type2Name ==
"3S")) {
4299 auto& pfp = slc.
pfps[uid - 1];
4301 std::vector<int> ssid;
4302 for(
auto&
ss : slc.
cots) {
4303 if(
ss.ID <= 0)
continue;
4305 if(!shared.empty() && std::find(ssid.begin(), ssid.end(),
ss.ID) == ssid.end()) ssid.push_back(
ss.ID);
4307 if(type2Name ==
"2S")
return ssid;
4308 for(
auto& ss3 : slc.
showers) {
4309 if(ss3.ID <= 0)
continue;
4311 if(!shared.empty() && std::find(tmp.begin(), tmp.end(), ss3.ID) == tmp.end()) tmp.push_back(ss3.ID);
4316 if(type1Name ==
"2V" && uid <= slc.
vtxs.size() && type2Name ==
"T" ) {
4318 for(
auto& tj : slc.
tjs) {
4320 for(
unsigned short end = 0;
end < 2; ++
end) {
4321 if(tj.VtxID[
end] !=
id)
continue;
4322 if(std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4328 if(type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"P") {
4329 for(
auto& pfp : slc.
pfps) {
4330 if(pfp.ID == 0)
continue;
4331 for(
unsigned short end = 0;
end < 2; ++
end) {
4332 if(pfp.Vx3ID[
end] !=
id)
continue;
4334 if(std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4340 if(type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"T") {
4342 for(
auto& tj : slc.
tjs) {
4344 for(
unsigned short end = 0;
end < 2; ++
end) {
4345 if(tj.VtxID[
end] > 0 && tj.VtxID[
end] <= slc.
vtxs.size()) {
4346 auto& vx2 = slc.
vtxs[tj.VtxID[
end] - 1];
4347 if(vx2.Vx3ID !=
id)
continue;
4348 if(std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4355 if(type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"2V") {
4357 for(
auto& vx2 : slc.
vtxs) {
4358 if(vx2.ID == 0)
continue;
4359 if(vx2.Vx3ID ==
id) tmp.push_back(vx2.ID);
4364 if(type1Name ==
"3S" && uid <= slc.
showers.size() && type2Name ==
"T") {
4366 auto& ss3 = slc.
showers[uid - 1];
4367 if(ss3.ID == 0)
return tmp;
4368 for(
auto cid : ss3.CotIDs) {
4369 auto&
ss = slc.
cots[cid - 1];
4370 if(
ss.ID == 0)
continue;
4371 tmp.insert(tmp.end(),
ss.TjIDs.begin(),
ss.TjIDs.end());
4377 if(type1Name ==
"2S" && uid <= slc.
cots.size() && type2Name ==
"T") {
4379 auto&
ss = slc.
cots[uid - 1];
4383 if(type1Name ==
"3S" && uid <= slc.
showers.size() && type2Name ==
"P") {
4385 auto& ss3 = slc.
showers[uid - 1];
4386 if(ss3.ID == 0)
return tmp;
4387 for(
auto cid : ss3.CotIDs) {
4388 auto&
ss = slc.
cots[cid - 1];
4389 if(
ss.ID == 0)
continue;
4390 for(
auto tid :
ss.TjIDs) {
4391 auto& tj = slc.
tjs[tid - 1];
4393 if(!tj.AlgMod[
kMat3D])
continue;
4394 for(
auto& pfp : slc.
pfps) {
4395 if(pfp.ID <= 0)
continue;
4396 if(std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tj.ID) == pfp.TjIDs.end())
continue;
4397 if(std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4404 if(type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"2S") {
4406 for(
auto&
ss : slc.
cots) {
4407 if(
ss.ID == 0)
continue;
4408 if(std::find(
ss.TjIDs.begin(),
ss.TjIDs.end(), id) !=
ss.TjIDs.end()) tmp.push_back(
ss.ID);
4413 if(type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"3S") {
4415 for(
auto&
ss : slc.
cots) {
4416 if(
ss.ID == 0)
continue;
4417 if(std::find(
ss.TjIDs.begin(),
ss.TjIDs.end(), id) ==
ss.TjIDs.end())
continue;
4418 if(
ss.SS3ID > 0) tmp.push_back(
ss.SS3ID);
4423 std::cout<<
"GetAssns doesn't know about "<<type1Name<<
" -> "<<type2Name<<
" assns, or id "<<
id<<
" is not valid.\n";
4437 float fromWire = fromHit.WireID().Wire;
4438 float fromTick = fromHit.PeakTime();
4439 float toWire = toHit.WireID().Wire;
4440 float toTick = toHit.PeakTime();
4442 bool success =
StartTraj(slc, tj, fromWire, fromTick, toWire, toTick, tCTP, pass);
4443 if(!success)
return false;
4447 auto& tp = tj.
Pts[0];
4448 mf::LogVerbatim(
"TC")<<
"StartTraj T"<<tj.
ID<<
" from "<<(int)fromWire<<
":"<<(
int)fromTick<<
" -> "<<(int)toWire<<
":"<<(
int)toTick<<
" StepDir "<<tj.
StepDir<<
" dir "<<tp.Dir[0]<<
" "<<tp.Dir[1]<<
" ang "<<tp.Ang<<
" AngleCode "<<tp.AngleCode<<
" angErr "<<tp.AngErr<<
" ExpectedHitsRMS "<<
ExpectedHitsRMS(slc, tp);
4465 int fWire = std::nearbyint(fromWire);
4466 int tWire = std::nearbyint(toWire);
4469 }
else if(tWire == fWire) {
4471 if(toTick < fromTick) stepdir = -1;
4481 if(!
MakeBareTrajPoint(slc, fromWire, fromTick, toWire, toTick, tCTP, tp))
return false;
4484 tj.
Pts.push_back(tp);
4488 auto& tp = tj.
Pts[0];
4496 std::pair<unsigned short, unsigned short>
GetSliceIndex(std::string typeName,
int uID)
4499 for(
unsigned short isl = 0; isl <
slices.size(); ++isl) {
4501 if(typeName ==
"T") {
4502 for(
unsigned short indx = 0; indx < slc.tjs.size(); ++indx) {
4503 if(slc.tjs[indx].UID == uID) {
return std::make_pair(isl, indx); }
4506 if(typeName ==
"P") {
4507 for(
unsigned short indx = 0; indx < slc.pfps.size(); ++indx) {
4508 if(slc.pfps[indx].UID == uID) {
return std::make_pair(isl, indx); }
4511 if(typeName ==
"2V") {
4512 for(
unsigned short indx = 0; indx < slc.vtxs.size(); ++indx) {
4513 if(slc.vtxs[indx].UID == uID) {
return std::make_pair(isl, indx); }
4516 if(typeName ==
"3V") {
4517 for(
unsigned short indx = 0; indx < slc.vtx3s.size(); ++indx) {
4518 if(slc.vtx3s[indx].UID == uID) {
return std::make_pair(isl, indx); }
4521 if(typeName ==
"2S") {
4522 for(
unsigned short indx = 0; indx < slc.cots.size(); ++indx) {
4523 if(slc.cots[indx].UID == uID) {
return std::make_pair(isl, indx); }
4526 if(typeName ==
"3S") {
4527 for(
unsigned short indx = 0; indx < slc.showers.size(); ++indx) {
4528 if(slc.showers[indx].UID == uID) {
return std::make_pair(isl, indx); }
4532 return std::make_pair(USHRT_MAX, USHRT_MAX);
4544 static double sum, sumx, sumy, sumx2, sumy2, sumxy;
4545 static unsigned short cnt;
4546 static std::vector<Point2_t> fitPts;
4547 static std::vector<double> fitWghts;
4552 sum = 0.; sumx = 0.; sumy = 0.;
4553 sumx2 = 0.; sumy2 = 0.; sumxy = 0;
4560 if(inPtErr <= 0.)
return false;
4562 double wght = 1 / (inPtErr * inPtErr);
4564 sumx += wght * inPt[0];
4565 sumx2 += wght * inPt[0] * inPt[0];
4566 sumy += wght * inPt[1];
4567 sumy2 += wght * inPt[1] * inPt[1];
4568 sumxy += wght * inPt[0] * inPt[1];
4569 if(mode == 1)
return true;
4570 fitPts.push_back(inPt);
4571 fitWghts.push_back(wght);
4575 if(cnt < 2)
return false;
4577 double delta = sum * sumx2 - sumx * sumx;
4578 if(delta == 0.)
return false;
4579 double A = (sumx2 * sumy - sumx * sumxy) / delta;
4580 double B = (sumxy * sum - sumx * sumy) / delta;
4584 if(cnt == 2 || fitPts.empty())
return true;
4587 if(fitPts.size() != cnt)
return false;
4588 double ndof = cnt - 2;
4589 double varnce = (sumy2 + A*A*sum + B*B*sumx2 - 2 * (A*sumy + B*sumxy - A*B*sumx)) / ndof;
4591 outVecErr[0] = sqrt(varnce * sumx2 / delta);
4592 outVecErr[1] = sqrt(varnce * sum / delta);
4599 for(
unsigned short ii = 0; ii < fitPts.size(); ++ii) {
4600 double arg = fitPts[ii][1] - A - B * fitPts[ii][0];
4601 sum += fitWghts[ii] * arg * arg;
4603 chiDOF = sum / ndof;
4616 if(strng ==
"instruct") {
4617 std::cout<<
"****** Unrecognized DebugConfig. Here are your options\n";
4618 std::cout<<
" 'C:T:P:W:Tick' where C = cryostat, T = TPC, W = wire, Tick (+/-5) to debug stepping (DUNE)\n";
4619 std::cout<<
" 'P:W:Tick' for single cryostat/TPC detectors (uB, LArIAT, etc)\n";
4620 std::cout<<
" 'WorkID <id> <slice index>' where <id> is a tj work ID (< 0) in slice <slice index> (default = 0)\n";
4621 std::cout<<
" 'Merge <CTP>' to debug trajectory merging\n";
4622 std::cout<<
" '2V <plane>' to debug 2D vertex finding in plane <plane>\n";
4623 std::cout<<
" '3V' to debug 3D vertex finding\n";
4624 std::cout<<
" 'VxMerge' to debug 2D vertex merging\n";
4625 std::cout<<
" 'JunkVx' to debug 2D junk vertex finder\n";
4626 std::cout<<
" 'PFP' to debug 3D matching and PFParticles\n";
4627 std::cout<<
" 'DeltaRay' to debug delta ray tagging\n";
4628 std::cout<<
" 'Muon' to debug muon tagging\n";
4629 std::cout<<
" '2S <plane>' to debug a 2D shower in plane <plane>\n";
4630 std::cout<<
" 'Reco <ID>' to reconstruct all sub-slices in the recob::Slice with the specified ID\n";
4631 std::cout<<
" 'SubSlice <sub-slice index>' where <slice index> restricts output to the specified sub-slice index\n";
4632 std::cout<<
" 'Stitch' to debug PFParticle stitching between TPCs\n";
4633 std::cout<<
" 'Sum' or 'Summary' to print a debug summary report\n";
4634 std::cout<<
" 'Dump <WorkID>' or 'Dump <UID>' to print all TPs in the trajectory to tcdump<UID>.csv\n";
4635 std::cout<<
" Note: Algs with debug printing include HamVx, HamVx2, SplitTjCVx, Comp3DVx, Comp3DVxIG, VtxHitsSwap\n";
4636 std::cout<<
" Set SkipAlgs: [\"bogusText\"] to print a list of algorithm names\n";
4651 std::vector<std::string> words;
4652 boost::split(words, strng, boost::is_any_of(
" :"), boost::token_compress_on);
4653 if(words.size() == 5) {
4666 if(words.size() == 2 && words[0] ==
"Dump") {
4673 if(words.size() > 1 && words[0] ==
"WorkID") {
4678 if(words.size() > 2)
debug.
Slice = std::stoi(words[2]);
4684 if(words.size() == 3) {
4695 if(words.size() == 2 && words[0] ==
"Merge") {
4701 if(words.size() == 2 && words[0] ==
"2V") {
4707 if(words.size() == 2 && words[0] ==
"2S") {
4714 if(words.size() == 2 && words[0] ==
"SubSlice") {
4718 if(words.size() == 2 && words[0] ==
"Reco") {
4720 std::cout<<
"Reconstructing Slice "<<
tcc.
recoSlice<<
"\n";
4734 for(
auto& slc :
slices) {
4735 for(
auto& tj : slc.tjs) {
4736 if(tj.AlgMod[
kKilled])
continue;
4739 std::ofstream outfile;
4741 outfile.open(fname,std::ios::out | std::ios::trunc);
4742 outfile<<
"Dump trajectory T"<<tj.UID<<
" WorkID "<<tj.WorkID;
4743 outfile<<
" ChgRMS "<<std::setprecision(2)<<tj.ChgRMS;
4745 outfile<<
"Wire, Chg T"<<tj.UID<<
", totChg, Tick, Delta, NTPsFit, Ang, TPErr\n";
4746 for(
unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
4747 auto& tp = tj.Pts[ipt];
4748 outfile<<std::fixed;
4749 outfile<<std::setprecision(0)<<std::nearbyint(tp.Pos[0]);
4750 outfile<<
","<<(int)tp.Chg;
4753 for(
auto iht : tp.Hits) {
4755 totChg +=
hit.Integral();
4757 outfile<<
","<<(int)totChg;
4758 outfile<<
","<<std::setprecision(0)<<std::nearbyint(tp.Pos[1]/
tcc.
unitsPerTick);
4759 outfile<<
","<<std::setprecision(2)<<tp.Delta;
4760 outfile<<
","<<tp.NTPsFit;
4761 outfile<<
","<<std::setprecision(2)<<tp.Ang;
4762 outfile<<
","<<std::setprecision(2)<<sqrt(tp.HitPosErr2);
4766 std::cout<<
"Points on T"<<tj.UID<<
" dumped to "<<fname<<
"\n";
4774 void PrintAll(std::string someText,
const std::vector<simb::MCParticle*>& mcpList)
4783 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4786 if(!slc.vtx3s.empty()) prt3V =
true;
4787 if(!slc.vtxs.empty()) prt2V =
true;
4788 if(!slc.tjs.empty()) prtT =
true;
4789 if(!slc.pfps.empty()) prtP =
true;
4790 if(!slc.showers.empty()) prtS3 =
true;
4794 myprt<<
"Debug report from caller "<<someText<<
"\n";
4795 if(!mcpList.empty()) {
4797 myprt<<
"************ "<<mcpList.size()<<
" MCParticles (> 10 MeV) ************\n";
4798 myprt<<
" mcpindx PDG KE eveIndx Process\n";
4799 for(
unsigned int imcp = 0; imcp < mcpList.size(); ++imcp) {
4800 auto& mcp = mcpList[imcp];
4801 int pdg = abs(mcp->PdgCode());
4802 if(pdg > 3000)
continue;
4803 float TMeV = 1000 * (mcp->E() - mcp->Mass());
4804 if(TMeV < 10)
continue;
4805 myprt<<std::setw(8)<<imcp;
4806 myprt<<std::setw(5)<<pdg;
4807 myprt<<std::setw(6)<<(int)TMeV;
4810 for(
unsigned int jmcp = 0; jmcp < mcpList.size(); ++jmcp) {
4811 if(mcpList[jmcp]->TrackId() == eveID) {
4816 myprt<<std::setw(8)<<eveIndx;
4817 myprt<<
" "<<mcp->Process();
4821 myprt<<
" 'prodID' = <sliceID>:<subSliceIndex>:<productID>/<productUID>\n";
4823 myprt<<
"************ Showers ************\n";
4824 myprt<<
" prodID Vtx parUID ___ChgPos____ ______Dir_____ ____posInPln____ ___projInPln____ 2D shower UIDs\n";
4825 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4828 if(slc.showers.empty())
continue;
4829 for(
auto& ss3 : slc.showers)
Print3S(someText, myprt, ss3);
4833 bool printHeader =
true;
4834 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4837 if(slc.pfps.empty())
continue;
4838 for(
auto& pfp : slc.pfps)
PrintP(someText, myprt, pfp, printHeader);
4843 myprt<<
"****** 3D vertices ******************************************__2DVtx_UID__*******\n";
4844 myprt<<
" prodID Cstat TPC X Y Z XEr YEr ZEr pln0 pln1 pln2 Wire score Prim? Nu? nTru";
4845 myprt<<
" ___________2D_Pos____________ _____Tj UIDs________\n";
4846 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4849 if(slc.vtx3s.empty())
continue;
4850 for(
auto& vx3 : slc.vtx3s)
Print3V(someText, myprt, vx3);
4855 myprt<<
"************ 2D vertices ************\n";
4856 myprt<<
" prodID CTP wire err tick err ChiDOF NTj Pass Topo ChgFrac Score v3D Tj UIDs\n";
4857 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4860 if(slc.vtxs.empty())
continue;
4861 for(
auto& vx2 : slc.vtxs)
Print2V(someText, myprt, vx2);
4865 bool printHeader =
true;
4866 for(
size_t isl = 0; isl <
slices.size(); ++isl) {
4869 if(slc.tjs.empty())
continue;
4870 for(
auto& tj : slc.tjs)
PrintT(someText, myprt, tj, printHeader);
4878 if(pfp.
ID <= 0)
return;
4880 myprt<<
"************ PFParticles ************\n";
4881 myprt<<
" prodID sVx _____sPos____ CS _______sDir______ ____sdEdx_____ eVx _____ePos____ CS _______eDir______ ____edEdx_____ MCS Len nTp3 SLk? PDG mcpIndx Par E*P\n";
4882 printHeader =
false;
4885 if(sIndx.first == USHRT_MAX)
return;
4886 auto& slc =
slices[sIndx.first];
4890 myprt<<std::setw(12)<<str;
4892 for(
unsigned short startend = 0; startend < 2; ++startend) {
4895 myprt<<std::setw(6)<<str;
4896 myprt<<std::fixed<<
std::right<<std::setprecision(0);
4897 myprt<<std::setw(5)<<pfp.
XYZ[startend][0];
4898 myprt<<std::setw(5)<<pfp.
XYZ[startend][1];
4899 myprt<<std::setw(5)<<pfp.
XYZ[startend][2];
4906 myprt<<std::fixed<<
std::right<<std::setprecision(2);
4907 myprt<<std::setw(6)<<pfp.
Dir[startend][0];
4908 myprt<<std::setw(6)<<pfp.
Dir[startend][1];
4909 myprt<<std::setw(6)<<pfp.
Dir[startend][2];
4910 for(
auto& dedx : pfp.
dEdx[startend]) {
4912 myprt<<std::setw(5)<<std::setprecision(1)<<dedx;
4914 myprt<<std::setw(5)<<std::setprecision(0)<<dedx;
4917 if (pfp.
dEdx[startend].size()<3){
4918 for(
size_t i = 0; i<3-pfp.
dEdx[startend].size(); ++i){
4919 myprt<<std::setw(6)<<
' ';
4927 myprt<<std::setw(5)<<std::setprecision(1)<<
length;
4929 myprt<<std::setw(5)<<std::setprecision(0)<<
length;
4931 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
Tp3s.size();
4933 myprt<<std::setw(5)<<pfp.
PDGCode;
4941 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
EffPur;
4942 if(!pfp.
TjIDs.empty()) {
4945 for(
auto tjid : pfp.
TjIDs) myprt<<
" T"<<slc.tjs[tjid - 1].UID;
4948 for(
auto tjuid : pfp.
TjUIDs) myprt<<
" T"<<tjuid;
4953 for(
auto dtruid : pfp.
DtrUIDs) myprt<<
" P"<<dtruid;
4962 if(vx3.
ID <= 0)
return;
4964 if(sIndx.first == USHRT_MAX)
return;
4965 auto& slc =
slices[sIndx.first];
4969 myprt<<
std::right<<std::setw(12)<<std::fixed<<str;
4970 myprt<<std::setprecision(1);
4979 for(
auto vx2id : vx3.
Vx2ID) {
4988 unsigned short nTruMatch = 0;
4989 for(
unsigned short ipl = 0; ipl < slc.nPlanes; ++ipl) {
4990 if(vx3.
Vx2ID[ipl] == 0)
continue;
4991 unsigned short iv2 = vx3.
Vx2ID[ipl] - 1;
4995 myprt<<std::setw(6)<<vx3.
Primary;
4999 for(
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5003 if(vx3.
Wire == -2) {
5005 for(
unsigned short end = 0;
end < 2; ++
end) {
5006 for(
auto& pfp : slc.pfps) {
5007 if(pfp.Vx3ID[
end] == vx3.
ID) {
5008 for(
auto tjID : pfp.TjIDs) {
5009 auto& tj = slc.tjs[tjID - 1];
5010 myprt<<
" T"<<tj.UID;
5016 auto vxtjs =
GetAssns(slc,
"3V", vx3.
ID,
"T");
5017 for(
auto tjid : vxtjs) {
5018 auto& tj = slc.tjs[tjid - 1];
5019 myprt<<
" T"<<tj.UID;
5029 if(vx2.
ID <= 0)
return;
5032 if(sIndx.first == USHRT_MAX)
return;
5033 auto& slc =
slices[sIndx.first];
5037 myprt<<
std::right<<std::setw(12)<<std::fixed<<str;
5039 myprt<<
std::right<<std::setw(8)<<std::setprecision(0)<<std::nearbyint(vx2.
Pos[0]);
5050 if(vx2.
Vx3ID > 0) v3id = slc.vtx3s[vx2.
Vx3ID - 1].UID;
5054 for(
unsigned short ii = 0; ii < slc.tjs.size(); ++ii) {
5055 auto const& tj = slc.tjs[ii];
5056 if(tj.AlgMod[
kKilled])
continue;
5057 for(
unsigned short end = 0;
end < 2; ++
end) {
5058 if(tj.VtxID[
end] != (
short)vx2.
ID)
continue;
5071 if(ss3.
ID <= 0)
return;
5073 if(sIndx.first == USHRT_MAX)
return;
5074 auto& slc =
slices[sIndx.first];
5078 myprt<<std::fixed<<std::setw(12)<<str;
5081 myprt<<std::setw(6)<<str;
5082 for(
unsigned short xyz = 0; xyz < 3; ++xyz) myprt<<std::setprecision(0)<<std::setw(5)<<ss3.
ChgPos[xyz];
5083 for(
unsigned short xyz = 0; xyz < 3; ++xyz) myprt<<std::setprecision(2)<<std::setw(5)<<ss3.
Dir[xyz];
5084 std::vector<float> projInPlane(slc.nPlanes);
5085 for(
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5089 projInPlane[plane] = tp.Delta;
5091 for(
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5092 myprt<<std::setprecision(2)<<std::setw(5)<<projInPlane[plane];
5094 for(
auto cid : ss3.
CotIDs) {
5095 auto&
ss = slc.cots[cid - 1];
5097 myprt<<std::setw(5)<<str;
5112 if(tj.
ID <= 0)
return;
5116 myprt<<
"************ Trajectories ************\n";
5117 myprt<<
" prodID CTP Pass Pts W:T Ang CS AveQ W:T Ang CS AveQ Chg(k) chgRMS Mom SDr __Vtx__ PDG DirFOM Par Pri NuPar E*P mcpIndex WorkID \n";
5118 printHeader =
false;
5121 if(sIndx.first == USHRT_MAX)
return;
5122 auto& slc =
slices[sIndx.first];
5126 myprt<<std::fixed<<std::setw(12)<<str;
5127 myprt<<std::setw(6)<<tj.
CTP;
5128 myprt<<std::setw(5)<<tj.
Pass;
5130 myprt<<std::setw(5)<<tj.
EndPt[1] - tj.
EndPt[0] + 1;
5131 unsigned short endPt0 = tj.
EndPt[0];
5132 auto& tp0 = tj.
Pts[endPt0];
5134 if(itick < 0) itick = 0;
5135 myprt<<std::setw(6)<<(int)(tp0.Pos[0]+0.5)<<
":"<<itick;
5136 if(itick < 10) { myprt<<
" "; }
5137 if(itick < 100) { myprt<<
" "; }
5138 if(itick < 1000) { myprt<<
" "; }
5139 myprt<<std::setw(6)<<std::setprecision(2)<<tp0.Ang;
5140 myprt<<std::setw(2)<<tp0.AngleCode;
5152 myprt<<std::setw(5)<<(int)tp0.AveChg;
5153 unsigned short endPt1 = tj.
EndPt[1];
5154 auto& tp1 = tj.
Pts[endPt1];
5156 myprt<<std::setw(6)<<(int)(tp1.Pos[0]+0.5)<<
":"<<itick;
5157 if(itick < 10) { myprt<<
" "; }
5158 if(itick < 100) { myprt<<
" "; }
5159 if(itick < 1000) { myprt<<
" "; }
5160 myprt<<std::setw(6)<<std::setprecision(2)<<tp1.Ang;
5161 myprt<<std::setw(2)<<tp1.AngleCode;
5169 myprt<<std::setw(5)<<(int)tp1.AveChg;
5170 myprt<<std::setw(7)<<std::setprecision(1)<<tj.
TotChg/1000;
5171 myprt<<std::setw(7)<<std::setprecision(2)<<tj.
ChgRMS;
5172 myprt<<std::setw(5)<<tj.
MCSMom;
5173 myprt<<std::setw(4)<<tj.
StepDir;
5175 if(tj.
VtxID[0] > 0) vxid = slc.vtxs[tj.
VtxID[0]-1].UID;
5176 myprt<<std::setw(4)<<vxid;
5178 if(tj.
VtxID[1] > 0) vxid = slc.vtxs[tj.
VtxID[1]-1].UID;
5179 myprt<<std::setw(4)<<vxid;
5180 myprt<<std::setw(5)<<tj.
PDGCode;
5181 myprt<<std::setw(7)<<std::setprecision(1)<<tj.
DirFOM;
5183 myprt<<std::setw(5)<<
PrimaryID(slc, tj);
5185 myprt<<std::setw(6)<<std::setprecision(2)<<tj.
EffPur;
5191 myprt<<std::setw(7)<<tj.
WorkID;
5203 if(!slc.
vtx3s.empty()) {
5205 myprt<<someText<<
"****** 3D vertices ******************************************__2DVtx_ID__*******\n";
5206 myprt<<someText<<
" Vtx Cstat TPC X Y Z XEr YEr ZEr pln0 pln1 pln2 Wire score Prim? Nu? nTru";
5207 myprt<<
" ___________2D_Pos____________ _____Tjs________\n";
5208 for(
unsigned short iv = 0; iv < slc.
vtx3s.size(); ++iv) {
5209 if(slc.
vtx3s[iv].ID == 0)
continue;
5213 myprt<<
std::right<<std::setw(5)<<std::fixed<<vid;
5214 myprt<<std::setprecision(1);
5227 unsigned short nTruMatch = 0;
5228 for(
unsigned short ipl = 0; ipl < slc.
nPlanes; ++ipl) {
5229 if(vx3.
Vx2ID[ipl] == 0)
continue;
5230 unsigned short iv2 = vx3.
Vx2ID[ipl] - 1;
5234 myprt<<std::setw(6)<<vx3.
Primary;
5238 for(
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
5242 if(vx3.
Wire == -2) {
5244 for(
auto& pfp : slc.
pfps) {
5245 if(pfp.Vx3ID[0] == slc.
vtx3s[iv].ID) {
5246 for(
auto& tjID : pfp.TjIDs) myprt<<
" t"<<tjID;
5248 if(pfp.Vx3ID[1] == slc.
vtx3s[iv].ID) {
5249 for(
auto& tjID : pfp.TjIDs) myprt<<
" t"<<tjID;
5253 auto vxtjs =
GetAssns(slc,
"3V", vx3.
ID,
"T");
5254 for(
auto tjid : vxtjs) myprt<<
" t"<<tjid;
5259 if(!slc.
vtxs.empty()) {
5260 bool foundOne =
false;
5261 for(
unsigned short iv = 0; iv < slc.
vtxs.size(); ++iv) {
5262 auto& vx2 = slc.
vtxs[iv];
5264 if(vx2.NTraj == 0)
continue;
5269 myprt<<someText<<
"************ 2D vertices ************\n";
5270 myprt<<someText<<
" ID CTP wire err tick err ChiDOF NTj Pass Topo ChgFrac Score v3D TjIDs\n";
5271 for(
auto& vx2 : slc.
vtxs) {
5272 if(vx2.ID == 0)
continue;
5276 myprt<<
std::right<<std::setw(5)<<std::fixed<<vid;
5278 myprt<<
std::right<<std::setw(8)<<std::setprecision(0)<<std::nearbyint(vx2.Pos[0]);
5279 myprt<<
std::right<<std::setw(5)<<std::setprecision(1)<<vx2.PosErr[0];
5286 myprt<<
std::right<<std::setw(9)<<std::setprecision(2)<<vx2.TjChgFrac;
5287 myprt<<
std::right<<std::setw(6)<<std::setprecision(1)<<vx2.Score;
5291 for(
unsigned short ii = 0; ii < slc.
tjs.size(); ++ii) {
5292 auto const& aTj = slc.
tjs[ii];
5294 if(aTj.AlgMod[
kKilled])
continue;
5295 for(
unsigned short end = 0;
end < 2; ++
end) {
5296 if(aTj.VtxID[
end] != (
short)vx2.ID)
continue;
5309 if(slc.
tjs.empty()) {
5316 if(itj == USHRT_MAX) {
5318 std::vector<unsigned int>
tmp;
5320 myprt<<someText<<
" UID 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";
5321 for(
unsigned short ii = 0; ii < slc.
tjs.size(); ++ii) {
5322 auto& aTj = slc.
tjs[ii];
5324 myprt<<someText<<
" ";
5327 myprt<<std::fixed<<std::setw(5)<<tid;
5328 myprt<<std::setw(6)<<aTj.CTP;
5329 myprt<<std::setw(5)<<aTj.Pass;
5331 myprt<<std::setw(5)<<aTj.EndPt[1] - aTj.EndPt[0] + 1;
5332 unsigned short endPt0 = aTj.EndPt[0];
5333 auto& tp0 = aTj.Pts[endPt0];
5335 if(itick < 0) itick = 0;
5336 myprt<<std::setw(6)<<(int)(tp0.Pos[0]+0.5)<<
":"<<itick;
5337 if(itick < 10) { myprt<<
" "; }
5338 if(itick < 100) { myprt<<
" "; }
5339 if(itick < 1000) { myprt<<
" "; }
5340 myprt<<std::setw(6)<<std::setprecision(2)<<tp0.Ang;
5341 myprt<<std::setw(2)<<tp0.AngleCode;
5342 if(aTj.StopFlag[0][
kBragg]) {
5344 }
else if(aTj.StopFlag[0][
kAtVtx]) {
5346 }
else if(aTj.StopFlag[0][
kAtKink]) {
5348 }
else if(aTj.StopFlag[0][
kAtTj]) {
5353 myprt<<std::setw(5)<<(int)tp0.AveChg;
5357 unsigned short midPt = 0.5 * (aTj.EndPt[0] + aTj.EndPt[1]);
5358 for(
unsigned short ipt = aTj.EndPt[0]; ipt < midPt; ++ipt) {
5359 auto& tp = aTj.Pts[ipt];
5364 if(cnt > 0) frac /= cnt;
5365 myprt<<std::setw(5)<<std::setprecision(1)<<frac;
5371 unsigned short endPt1 = aTj.EndPt[1];
5372 auto& tp1 = aTj.Pts[endPt1];
5374 myprt<<std::setw(6)<<(int)(tp1.Pos[0]+0.5)<<
":"<<itick;
5375 if(itick < 10) { myprt<<
" "; }
5376 if(itick < 100) { myprt<<
" "; }
5377 if(itick < 1000) { myprt<<
" "; }
5378 myprt<<std::setw(6)<<std::setprecision(2)<<tp1.Ang;
5379 myprt<<std::setw(2)<<tp1.AngleCode;
5380 if(aTj.StopFlag[1][
kBragg]) {
5382 }
else if(aTj.StopFlag[1][
kAtVtx]) {
5387 myprt<<std::setw(5)<<(int)tp1.AveChg;
5391 for(
unsigned short ipt = midPt; ipt <= aTj.EndPt[1]; ++ipt) {
5392 auto& tp = aTj.Pts[ipt];
5397 if(cnt > 0) frac /= cnt;
5398 myprt<<std::setw(5)<<std::setprecision(1)<<frac;
5404 myprt<<std::setw(7)<<std::setprecision(1)<<aTj.TotChg/1000;
5405 myprt<<std::setw(7)<<std::setprecision(2)<<aTj.ChgRMS;
5406 myprt<<std::setw(5)<<aTj.MCSMom;
5407 myprt<<std::setw(4)<<aTj.StepDir;
5408 myprt<<std::setw(4)<<aTj.VtxID[0];
5409 myprt<<std::setw(4)<<aTj.VtxID[1];
5410 myprt<<std::setw(5)<<aTj.PDGCode;
5411 myprt<<std::setw(7)<<std::setprecision(1)<<aTj.DirFOM;
5412 myprt<<std::setw(5)<<aTj.ParentID;
5413 myprt<<std::setw(5)<<
PrimaryID(slc, aTj);
5424 myprt<<std::setw(6)<<pdg;
5425 myprt<<std::setw(6)<<std::setprecision(2)<<aTj.EffPur;
5426 myprt<<std::setw(5)<<truKE;
5427 myprt<<std::setw(7)<<aTj.WorkID;
5428 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(aTj.AlgMod[ib]) myprt<<
" "<<
AlgBitNames[ib];
5434 if(itj > slc.
tjs.size()-1)
return;
5436 auto const& aTj = slc.
tjs[itj];
5438 mf::LogVerbatim(
"TC")<<
"Print slc.tjs["<<itj<<
"] Vtx[0] "<<aTj.VtxID[0]<<
" Vtx[1] "<<aTj.VtxID[1];
5440 for(
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
if(aTj.AlgMod[ib]) myprt<<
" "<<
AlgBitNames[ib];
5444 if(ipt == USHRT_MAX) {
5446 for(
unsigned short ii = 0; ii < aTj.Pts.size(); ++ii)
PrintTrajPoint(someText, slc, ii, aTj.StepDir, aTj.Pass, aTj.Pts[ii]);
5449 PrintTrajPoint(someText, slc, ipt, aTj.StepDir, aTj.Pass, aTj.Pts[ipt]);
5462 if(tPoint == USHRT_MAX) {
5465 myprt<<someText<<
" ";
5466 myprt<<
"Work: UID "<<tj.
UID<<
" CTP "<<tj.
CTP<<
" StepDir "<<tj.
StepDir<<
" PDG "<<tj.
PDGCode<<
" TruPDG "<<trupdg<<
" slc.vtxs "<<tj.
VtxID[0]<<
" "<<tj.
VtxID[1]<<
" nPts "<<tj.
Pts.size()<<
" EndPts "<<tj.
EndPt[0]<<
" "<<tj.
EndPt[1];
5467 myprt<<
" MCSMom "<<tj.
MCSMom;
5469 myprt<<
" AlgMod names:";
5473 myprt<<someText<<
" ";
5474 myprt<<
"slc.tjs: UID "<<tj.
UID<<
" WorkID "<<tj.
WorkID<<
" StepDir "<<tj.
StepDir<<
" PDG "<<tj.
PDGCode<<
" TruPDG "<<trupdg<<
" slc.vtxs "<<tj.
VtxID[0]<<
" "<<tj.
VtxID[1]<<
" nPts "<<tj.
Pts.size()<<
" EndPts "<<tj.
EndPt[0]<<
" "<<tj.
EndPt[1];
5475 myprt<<
" MCSMom "<<tj.
MCSMom;
5477 myprt<<
" AlgMod names:";
5484 for(
unsigned short ic = 0; ic < slc.
cots.size(); ++ic) {
5485 if(slc.
cots[ic].TjIDs.empty())
continue;
5487 if(slc.
cots[ic].ShowerTjID != tj.
ID)
continue;
5490 myprt<<
"cots index "<<ic<<
" ";
5491 myprt<<someText<<
" Envelope";
5497 myprt<<
" Energy "<<(int)ss.
Energy;
5499 myprt<<
"\nInShower TjIDs";
5500 for(
auto& tjID : ss.
TjIDs) {
5511 myprt<<
"Angle "<<std::fixed<<std::setprecision(2)<<ss.
Angle<<
" +/- "<<ss.
AngleErr;
5512 myprt<<
" AspectRatio "<<std::fixed<<std::setprecision(2)<<ss.
AspectRatio;
5513 myprt<<
" DirectionFOM "<<std::fixed<<std::setprecision(2)<<ss.
DirectionFOM;
5517 myprt<<
" No parent";
5520 if(ss.
NeedsUpdate) myprt<<
"*********** This shower needs to be updated ***********";
5521 myprt<<
"................................................";
5526 if(tPoint > tj.
Pts.size() -1) {
5527 mf::LogVerbatim(
"TC")<<
"Can't print non-existent traj point "<<tPoint;
5537 mf::LogVerbatim(
"TC")<<someText<<
" TRP CTP Ind Stp W:Tick Delta RMS Ang C Err Dir0 Dir1 Q AveQ Pull FitChi NTPF Hits ";
5544 myprt<<someText<<
" TRP"<<std::fixed;
5546 if(dir > 0) { myprt<<
"+"; }
else { myprt<<
"-"; }
5547 myprt<<std::setw(6)<<tp.
CTP;
5548 myprt<<std::setw(5)<<ipt;
5549 myprt<<std::setw(5)<<tp.
Step;
5551 if(tp.
Pos[1] < 10) { myprt<<
" "; }
5552 if(tp.
Pos[1] < 100) { myprt<<
" "; }
5553 if(tp.
Pos[1] < 1000) { myprt<<
" "; }
5554 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Delta;
5555 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
DeltaRMS;
5556 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Ang;
5558 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
AngErr;
5559 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Dir[0];
5560 myprt<<std::setw(6)<<std::setprecision(2)<<tp.
Dir[1];
5561 myprt<<std::setw(7)<<(int)tp.
Chg;
5562 myprt<<std::setw(8)<<(int)tp.
AveChg;
5563 myprt<<std::setw(6)<<std::setprecision(1)<<tp.
ChgPull;
5564 myprt<<std::setw(7)<<tp.
FitChi;
5565 myprt<<std::setw(6)<<tp.
NTPsFit;
5567 if(tp.
Hits.size() > 16) {
5569 myprt<<
" "<<tp.
Hits.size()<<
" shower hits";
5571 for(
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
5572 unsigned int iht = tp.
Hits[ii];
5574 myprt<<
" "<<
hit.WireID().Wire<<
":"<<(int)
hit.PeakTime();
5581 myprt<<slc.
slHits[iht].InTraj;
5592 myprt<<
" PFP sVx ________sPos_______ CS _______sDir______ ____sdEdx_____ eVx ________ePos_______ CS _______eDir______ ____edEdx____ Len nTp3 MCSMom ShLike? PDG mcpIndx Par Prim E*P\n";
5596 myprt<<std::setw(5)<<pid;
5598 for(
unsigned short startend = 0; startend < 2; ++startend) {
5599 myprt<<std::setw(4)<<pfp.
Vx3ID[startend];
5600 myprt<<std::fixed<<
std::right<<std::setprecision(1);
5601 myprt<<std::setw(7)<<pfp.
XYZ[startend][0];
5602 myprt<<std::setw(7)<<pfp.
XYZ[startend][1];
5603 myprt<<std::setw(7)<<pfp.
XYZ[startend][2];
5611 myprt<<std::fixed<<
std::right<<std::setprecision(2);
5612 myprt<<std::setw(6)<<pfp.
Dir[startend][0];
5613 myprt<<std::setw(6)<<pfp.
Dir[startend][1];
5614 myprt<<std::setw(6)<<pfp.
Dir[startend][2];
5615 for(
auto& dedx : pfp.
dEdx[startend]) {
5617 myprt<<std::setw(5)<<std::setprecision(1)<<dedx;
5619 myprt<<std::setw(5)<<std::setprecision(0)<<dedx;
5622 if (pfp.
dEdx[startend].size()<3){
5623 for(
size_t i = 0; i<3-pfp.
dEdx[startend].size(); ++i){
5624 myprt<<std::setw(6)<<
' ';
5632 myprt<<std::setw(5)<<std::setprecision(1)<<
length;
5634 myprt<<std::setw(5)<<std::setprecision(0)<<
length;
5636 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
Tp3s.size();
5639 myprt<<std::setw(5)<<pfp.
PDGCode;
5650 myprt<<std::setw(5)<<std::setprecision(2)<<pfp.
EffPur;
5651 if(!pfp.
TjIDs.empty()) {
5652 for(
auto& tjID : pfp.
TjIDs) myprt<<
" T"<<tjID;
5656 for(
auto& dtrUID : pfp.
DtrUIDs) myprt<<
" P"<<dtrUID;
5663 if(slc.
pfps.empty())
return;
5667 myprt<<
" PFP sVx ________sPos_______ ______sDir______ ______sdEdx_____ eVx ________ePos_______ ______eDir______ ______edEdx_____ BstPln PDG TruPDG Par Prim E*P\n";
5668 bool printHeader =
true;
5669 for(
auto& pfp : slc.
pfps) {
5670 PrintPFP(someText, slc, pfp, printHeader);
5671 printHeader =
false;
5679 if(end > 1)
return "Invalid end";
5682 for(
unsigned short ib = 0; ib <
StopFlagNames.size(); ++ib) {
5720 unsigned int wire = 0;
5721 if(pos[0] > -0.4) wire = std::nearbyint(pos[0]);
Expect tracks entering from the front face. Don't create neutrino PFParticles.
void PrintTrajectory(std::string someText, TCSlice &slc, const Trajectory &tj, unsigned short tPoint)
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 HitsRMSTime(TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
void CheckTrajBeginChg(TCSlice &slc, unsigned short itj)
float AveChg
Calculated using ALL hits.
void ReleaseHits(TCSlice &slc, Trajectory &tj)
float HitsRMSTick(TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< Trajectory > tjs
vector of all trajectories in each plane
std::vector< Vtx3Store > vtx3s
3D vertices
Point2_t dEdx
dE/dx for 3D matched trajectories
bool dbgStitch
debug PFParticle stitching
int PDGCodeVote(TCSlice &slc, std::vector< int > &tjIDs, bool prt)
void SetEndPoints(Trajectory &tj)
std::array< std::vector< float >, 2 > dEdxErr
Functions to help with numbers.
bool MakeVertexObsolete(std::string fcnLabel, TCSlice &slc, VtxStore &vx2, bool forceKill)
std::vector< float > kinkCuts
kink angle, nPts fit, (alternate) kink angle significance
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
bool InTrajOK(TCSlice &slc, std::string someText)
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
float TjDirFOM(TCSlice &slc, const Trajectory &tj, bool prt)
void ChgSlope(TCSlice &slc, Trajectory &tj, unsigned short fromPt, unsigned short toPt, float &slope, float &slopeErr, float &chiDOF)
struct of temporary 2D vertices (end points)
std::vector< int > GetAssns(TCSlice &slc, std::string type1Name, int id, std::string type2Name)
void TrajPointTrajDOCA(TCSlice &slc, TrajPoint const &tp, Trajectory const &tj, unsigned short &closePt, float &minSep)
const std::vector< std::string > AlgBitNames
std::vector< ShowerStruct > cots
CTP_t CTP
Cryostat, TPC, Plane code.
std::vector< float > maxPos0
bool InsideTPC(const Point3_t &pos, geo::TPCID &inTPCID)
std::vector< int > NearTjIDs
std::array< double, 3 > Point3_t
std::vector< ShowerStruct3D > showers
float PosSep(const Point2_t &pos1, const Point2_t &pos2)
std::vector< Point2_t > Envelope
void PrintPFP(std::string someText, TCSlice &slc, const PFPStruct &pfp, bool printHeader)
std::vector< unsigned int > PutTrajHitsInVector(Trajectory const &tj, HitStatus_t hitRequest)
bool TrajTrajDOCA(TCSlice &slc, const Trajectory &tj1, const Trajectory &tj2, unsigned short &ipt1, unsigned short &ipt2, float &minSep, bool considerDeadWires)
vertex position fixed manually - no fitting done
int NeutrinoPrimaryTjID(TCSlice &slc, const Trajectory &tj)
std::array< std::bitset< 8 >, 2 > StopFlag
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
bool WireHitRangeOK(TCSlice &slc, const CTP_t &inCTP)
void UnsetUsedHits(TCSlice &slc, TrajPoint &tp)
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
void TjDeltaRMS(TCSlice &slc, Trajectory &tj, unsigned short firstPt, unsigned short lastPt, double &rms, unsigned short &cnt)
void PrintT(std::string someText, mf::LogVerbatim &myprt, Trajectory &tj, bool &printHeader)
bool StoreTraj(TCSlice &slc, Trajectory &tj)
float TotChg
Total including an estimate for dead wires.
void FindAlongTrans(Point2_t pos1, Vector2_t dir1, Point2_t pos2, Point2_t &alongTrans)
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
void ChkChgAsymmetry(TCSlice &slc, Trajectory &tj, bool prt)
CryostatID_t Cryostat
Index of cryostat.
float ExpectedHitsRMS(TCSlice &slc, const TrajPoint &tp)
void PrintAllTraj(std::string someText, TCSlice &slc, unsigned short itj, unsigned short ipt, bool prtVtx)
bool TrajClosestApproach(Trajectory const &tj, float x, float y, unsigned short &closePt, float &DOCA)
unsigned short MatchVecIndex(TCSlice &slc, int tjID)
float TrajPointSeparation(TrajPoint &tp1, TrajPoint &tp2)
void SetAngleCode(TrajPoint &tp)
void PrintP(std::string someText, mf::LogVerbatim &myprt, PFPStruct &pfp, bool &printHeader)
void Print3V(std::string someText, mf::LogVerbatim &myprt, Vtx3Store &vx3)
void TagDeltaRays(TCSlice &slc, const CTP_t &inCTP)
bool SetMag(Vector2_t &v1, double mag)
bool dbgSlc
debug only in the user-defined slice? default is all slices
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
bool SignalBetween(TCSlice &slc, TrajPoint tp, float toPos0, const float &MinWireSignalFraction)
int EveId(const int trackID) const
std::vector< unsigned int > lastWire
the last wire with a hit
float GoodnessOfFit() const
Degrees of freedom in the determination of the hit signal shape (-1 by default)
bool LongPulseHit(const recob::Hit &hit)
std::array< int, 2 > Vx3ID
short int Multiplicity() const
How many hits could this one be shared with.
bool IsShowerLike(TCSlice &slc, const std::vector< int > TjIDs)
float PointTrajDOCA(TCSlice &slc, float wire, float time, TrajPoint const &tp)
std::vector< int > CotIDs
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
bool StoreVertex(TCSlice &slc, VtxStore &vx)
void PrintPFPs(std::string someText, TCSlice &slc)
std::vector< TrajPoint3 > Tp3s
void SetPDGCode(TCSlice &slc, Trajectory &tj, bool tjDone)
std::string PrintPos(TCSlice &slc, const Point2_t &pos)
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.
bool MergeTjIntoPFP(TCSlice &slc, int mtjid, PFPStruct &pfp, bool prt)
int PrimaryID(TCSlice &slc, const Trajectory &tj)
double DeltaAngle2(double Ang1, double Ang2)
std::vector< T > SetIntersection(const std::vector< T > &set1, const std::vector< T > &set2)
std::vector< float > angleRanges
list of max angles for each angle range
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
unsigned short Pass
the pass on which it was created
bool dbg3V
debug 3D vertex finding
float DeadWireCount(TCSlice &slc, const float &inWirePos1, const float &inWirePos2, CTP_t tCTP)
void Reverse3DMatchTjs(TCSlice &slc, PFPStruct &pfp, bool prt)
void UpdateVxEnvironment(std::string inFcnLabel, TCSlice &slc, VtxStore &vx2, bool prt)
float HitsPosTick(TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
TrajPoint MakeBareTP(TCSlice &slc, Point3_t &pos, Vector3_t &dir, CTP_t inCTP)
std::string PrintHitShort(const TCHit &tch)
unsigned int mcpListIndex
std::vector< std::vector< std::pair< int, int > > > wireHitRange
unsigned short NumDeltaRays(TCSlice &slc, std::vector< int > &tjIDs)
tagged as a vertex between Tjs that are matched to MC truth neutrino interaction particles ...
unsigned int Hit
set to the hit index in evt.allHits if a Plane:Wire:Tick match is found
std::vector< int > TjUIDs
float MaxTjLen(TCSlice &slc, std::vector< int > &tjIDs)
int Cryostat
Select Cryostat.
struct of temporary 3D vertices
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
short nPtsAve
dump trajectory points
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
bool dbgStp
debug stepping using debug.Cryostat, debug.TPC, etc
int Wire
Select hit Wire for debugging.
unsigned int mcpListIndex
std::array< float, 2 > Point2_t
std::vector< float > maxPos1
float ChgFracBetween(TCSlice &slc, TrajPoint tp, float toPos0)
float unitsPerTick
scale factor from Tick to WSE equivalent units
std::array< Point3_t, 2 > XYZ
const detinfo::DetectorProperties * detprop
unsigned short NearestPtWithChg(TCSlice &slc, Trajectory &tj, unsigned short thePt)
bool TrajIsClean(TCSlice &slc, Trajectory &tj, bool prt)
int WorkID
Select the StartWorkID for debugging.
void DefineHitPos(TCSlice &slc, TrajPoint &tp)
void Print2V(std::string someText, mf::LogVerbatim &myprt, VtxStore &vx2)
CTP_t CTP
Cryostat, TPC, Plane code.
std::array< Vector3_t, 2 > DirErr
bool MergeShowerTjsAndStore(TCSlice &slc, unsigned short istj, unsigned short jstj, bool prt)
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
bool dbg2V
debug 2D vertex finding
const std::vector< std::string > StopFlagNames
bool TrajHitsOK(TCSlice &slc, const unsigned int iht, const unsigned int jht)
std::vector< float > aveHitRMS
average RMS of an isolated hit
std::vector< TrajPoint > Pts
Trajectory points.
virtual double Temperature() const =0
unsigned short GetPFPIndex(TCSlice &slc, int tjID)
std::array< Vector3_t, 2 > Dir
std::vector< int > FindCloseTjs(TCSlice &slc, const TrajPoint &fromTp, const TrajPoint &toTp, const float &maxDelta)
float EffPur
Efficiency * Purity.
float TrajLength(Trajectory &tj)
void MakeHaloTj(TCSlice &slc, Trajectory &muTj, bool prt)
float PointTrajDOCA2(TCSlice &slc, float wire, float time, TrajPoint const &tp)
void FitTraj(TCSlice &slc, Trajectory &tj, unsigned short originPt, unsigned short npts, short fitDir, TrajPoint &tpFit)
double MCSThetaRMS(TCSlice &slc, Trajectory &tj, unsigned short firstPt, unsigned short lastPt)
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 SignalAtTp(TCSlice &slc, const TrajPoint &tp)
bool PointInsideEnvelope(const Point2_t &Point, const std::vector< Point2_t > &Envelope)
std::vector< float > match3DCuts
3D matching cuts
void TagJunkTj(TCSlice &slc, Trajectory &tj, bool prt)
void UpdateMatchStructs(TCSlice &slc, int oldTj, int newTj)
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
void MakeTrajectoryObsolete(TCSlice &slc, unsigned int itj)
short StartEnd
The starting end (-1 = don't know)
unsigned short CloseEnd(TCSlice &slc, const Trajectory &tj, const Point2_t &pos)
std::string PrintHit(const TCHit &tch)
bool Fit2D(short mode, Point2_t inPt, float &inPtErr, Vector2_t &outVec, Vector2_t &outVecErr, float &chiDOF)
bool StartTraj(TCSlice &slc, Trajectory &tj, float fromWire, float fromTick, float toWire, float toTick, CTP_t &tCTP, unsigned short pass)
const geo::GeometryCore * geom
bool SplitTraj(TCSlice &slc, unsigned short itj, unsigned short pos, unsigned short ivx, bool prt)
float TpSumHitChg(TCSlice &slc, TrajPoint const &tp)
virtual unsigned int NumberTimeSamples() const =0
int UID
a unique ID for all slices
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
float MaxChargeAsymmetry(TCSlice &slc, std::vector< int > &tjIDs)
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
void ReverseTraj(TCSlice &slc, Trajectory &tj)
unsigned short NumHitsInTP(const TrajPoint &tp, HitStatus_t hitRequest)
void TrimEndPts(std::string fcnLabel, TCSlice &slc, Trajectory &tj, const std::vector< float > &fQualityCuts, bool prt)
void DefineTjParents(TCSlice &slc, bool prt)
std::vector< unsigned int > firstWire
the first wire with a hit
float TPHitsRMSTime(TCSlice &slc, TrajPoint &tp, HitStatus_t hitRequest)
int ID
ID that is local to one slice.
std::vector< TCSlice > slices
std::array< unsigned short, 2 > VtxID
ID of 2D vertex.
Detector simulation of raw signals on wires.
void PrintAll(std::string someText, const std::vector< simb::MCParticle * > &mcpList)
void UpdateTjChgProperties(std::string inFcnLabel, TCSlice &slc, Trajectory &tj, bool prt)
float PosSep2(const Point2_t &pos1, const Point2_t &pos2)
bool FindCloseHits(TCSlice &slc, TrajPoint &tp, float const &maxDelta, HitStatus_t hitRequest)
bool CompatibleMerge(TCSlice &slc, const Trajectory &tj1, const Trajectory &tj2, bool prt)
std::bitset< 16 > modes
number of points to find AveChg
std::vector< TCHit > slHits
float TwoTPAngle(TrajPoint &tp1, TrajPoint &tp2)
bool MergeAndStore(TCSlice &slc, unsigned int itj1, unsigned int itj2, bool doPrt)
void RestoreObsoleteTrajectory(TCSlice &slc, unsigned int itj)
bool aveHitRMSValid
set true when the average hit RMS is well-known
unsigned short NumPtsWithCharge(TCSlice &slc, const Trajectory &tj, bool includeDeadWires, unsigned short firstPt, unsigned short lastPt)
std::bitset< 16 > Stat
Vertex status bits using kVtxBit_t.
unsigned short FarEnd(TCSlice &slc, const Trajectory &tj, const Point2_t &pos)
float ChgFracNearPos(TCSlice &slc, const Point2_t &pos, const std::vector< int > &tjIDs)
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
bool InsideFV(TCSlice &slc, PFPStruct &pfp, unsigned short end)
double DotProd(const Vector3_t &v1, const Vector3_t &v2)
float ElectronLikelihood(TCSlice &slc, Trajectory &tj, float &asym)
bool DecodeDebugString(std::string strng)
bool MakeBareTrajPoint(TCSlice &slc, const TrajPoint &tpIn1, const TrajPoint &tpIn2, TrajPoint &tpOut)
std::bitset< 128 > useAlg
Max hit separation for making junk trajectories. < 0 to turn off.
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
bool HasDuplicateHits(TCSlice &slc, Trajectory const &tj, bool prt)
std::vector< short > deltaRayTag
min length, min MCSMom and min separation (WSE) for a delta ray tag
PFPStruct CreatePFP(TCSlice &slc)
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
std::vector< VtxStore > vtxs
2D vertices
short StepDir
-1 = going US (-> small wire#), 1 = going DS (-> large wire#)
float MaxHitDelta(TCSlice &slc, Trajectory &tj)
std::bitset< 128 > AlgMod
Bit set if algorithm AlgBit_t modifed the trajectory.
std::vector< short > muonTag
min length and min MCSMom for a muon tag
unsigned short NumUsedHitsInTj(TCSlice &slc, const Trajectory &tj)
geo::PlaneID DecodeCTP(CTP_t CTP)
unsigned short AngleRange(float angle)
Vector2_t PointDirection(const Point2_t p1, const Point2_t p2)
void Print3S(std::string someText, mf::LogVerbatim &myprt, ShowerStruct3D &ss3)
std::vector< int > GetVtxTjIDs(const TCSlice &slc, const VtxStore &vx2)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::bitset< 128 > dbgAlg
Allow user to turn on debug printing in algorithms (that print...)
unsigned short PDGCodeIndex(int PDGCode)
std::bitset< 8 > Environment
std::vector< recob::Hit > const * allHits
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
std::pair< unsigned short, unsigned short > GetSliceIndex(std::string typeName, int uID)
float HitSep2(TCSlice &slc, unsigned int iht, unsigned int jht)
float OverlapFraction(TCSlice &slc, const Trajectory &tj1, const Trajectory &tj2)
float TPHitsRMSTick(TCSlice &slc, TrajPoint &tp, HitStatus_t hitRequest)
std::vector< unsigned int > nWires
float HitsPosTime(TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
use the stiff electron strategy
float PointTrajSep2(float wire, float time, TrajPoint const &tp)
std::array< double, 3 > Vector3_t
int ID
ID of the recob::Slice (not the sub-slice)
bool FillWireHitRange(TCSlice &slc)
std::array< std::vector< float >, 2 > dEdx
void SetVx2Score(TCSlice &slc)
std::string PrintStopFlag(const Trajectory &tj, unsigned short end)
const sim::ParticleList & ParticleList()
std::vector< float > vtx2DCuts
Max position pull, max Position error rms.
std::bitset< 8 > Strategy
std::vector< MatchStruct > matchVec
3D matching vector
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
std::vector< PFPStruct > pfps
2D representation of charge deposited in the TDC/wire plane
void MoveTPToWire(TrajPoint &tp, float wire)
void PosInPlane(const TCSlice &slc, const Vtx3Store &vx3, unsigned short plane, Point2_t &pos)
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
void MergeGhostTjs(TCSlice &slc, CTP_t inCTP)
unsigned int ChannelID_t
Type representing the ID of a readout channel.
unsigned int allHitsIndex
TPCID_t TPC
Index of the TPC within its cryostat.
void TrajIntersection(TrajPoint const &tp1, TrajPoint const &tp2, float &x, float &y)
bool StorePFP(TCSlice &slc, PFPStruct &pfp)
bool valIncreasing(SortEntry c1, SortEntry c2)
short MCSMom(TCSlice &slc, Trajectory &tj, unsigned short firstPt, unsigned short lastPt)
short recoSlice
only reconstruct the slice with ID (0 = all)
double DeltaAngle(double Ang1, double Ang2)
void PrintHeader(std::string someText)
float TjChgFrac
Fraction of charge near the vertex that is from hits on the vertex Tjs.
bool dbgSummary
print a summary report
bool NeedsUpdate
Set true when the Tj needs to be updated.
master switch for turning on debug mode
void PrintTrajPoint(std::string someText, TCSlice &slc, unsigned short ipt, short dir, unsigned short pass, TrajPoint const &tp)
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
bool valDecreasing(SortEntry c1, SortEntry c2)
CTP_t CTP
set to an invalid CTP
int PrimaryUID(TCSlice &slc, const PFPStruct &pfp)
std::vector< int > DtrUIDs
constexpr Point origin()
Returns a origin position with a point of the specified type.
use the stiff muon strategy
float DirFOM
Normalized RMS using ALL hits. Assume it is 50% to start.