4 #include <boost/algorithm/string/classification.hpp>
5 #include <boost/algorithm/string/split.hpp>
7 #include "art/Framework/Services/Registry/ServiceHandle.h"
23 #include "nusimdata/SimulationBase/MCParticle.h"
43 using namespace detail;
60 std::vector<int> dtrs;
61 for (
auto& dtj : slc.
tjs) {
62 if (dtj.AlgMod[
kKilled])
continue;
63 if (dtj.ParentID != muTj.
ID)
continue;
64 dtrs.push_back(dtj.ID);
66 if (prt) mf::LogVerbatim(
"TC") <<
"MakeHaloTj: Killing delta-ray T" << dtj.ID;
70 if (pfpIndex == USHRT_MAX) {
71 if (prt) mf::LogVerbatim(
"TC") <<
" No PFP found for 3D-matched delta-ray";
74 auto& pfp = slc.
pfps[pfpIndex];
75 if (prt) mf::LogVerbatim(
"TC") <<
" Killing delta-ray PFParticle P" << pfp.UID;
78 if (pfp.ParentUID > 0) {
80 if (parentIndx.first != USHRT_MAX) {
81 auto& parent =
slices[parentIndx.first].pfps[parentIndx.second];
82 std::vector<int> newDtrUIDs;
83 for (
auto uid : parent.DtrUIDs)
84 if (uid != dtj.UID) newDtrUIDs.push_back(uid);
85 parent.DtrUIDs = newDtrUIDs;
97 tj.
ID = slc.
tjs.size() + 1;
113 std::vector<int> closeTjs;
114 for (
unsigned short ipt = muTj.
EndPt[0]; ipt <= muTj.
EndPt[1]; ++ipt) {
115 auto tp = muTj.
Pts[ipt];
126 if (tp.Dir[0] != 0) window *=
std::abs(1 / tp.Dir[0]);
129 bool hitsAdded =
false;
130 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
131 unsigned int iht = tp.Hits[ii];
132 auto inTraj = slc.
slHits[iht].InTraj;
133 if (inTraj < 0)
continue;
135 tp.UseHit[ii] =
true;
141 if (inTraj != muTj.
ID &&
142 std::find(closeTjs.begin(), closeTjs.end(), inTraj) == closeTjs.end())
143 closeTjs.push_back(inTraj);
148 tp.Delta =
PointTrajDOCA(slc, tp.HitPos[0], tp.HitPos[1], tp);
150 tj.
Pts.push_back(tp);
153 if (tj.
Pts.empty())
return;
156 mf::LogVerbatim myprt(
"TC");
157 myprt <<
"MHTj: T" << muTj.
ID <<
" npts " << tj.
Pts.size() <<
" close";
158 for (
auto tid : closeTjs)
159 myprt <<
" T" << tid;
163 slc.
tjs.push_back(tj);
201 for (
auto& tj : slc.
tjs) {
202 if (tj.AlgMod[
kKilled])
continue;
209 std::vector<int> temp;
210 for (
auto& vx3 : slc.
vtx3s) {
211 if (vx3.ID == 0)
continue;
214 temp.push_back(vx3.ID);
216 if (temp.empty())
return;
219 std::vector<int> masterlist;
220 for (
auto vx3id : temp) {
221 auto& vx3 = slc.
vtx3s[vx3id - 1];
224 for (
auto tjid : tjlist) {
225 auto& tj = slc.
tjs[tjid - 1];
226 if (tj.ParentID != 0) tj.ParentID = 0;
227 if (std::find(masterlist.begin(), masterlist.end(), tjid) == masterlist.end())
228 masterlist.push_back(tjid);
232 mf::LogVerbatim myprt(
"TC");
233 myprt <<
"DTP: masterlist Tjs";
234 for (
auto tjid : masterlist)
235 myprt <<
" " << tjid;
239 std::vector<SortEntry> sortVec(temp.size());
240 for (
unsigned short indx = 0; indx < temp.size(); ++indx) {
241 auto& vx3 = slc.
vtx3s[temp[indx] - 1];
242 sortVec[indx].index = indx;
243 sortVec[indx].val = vx3.Score;
245 if (sortVec.size() > 1) std::sort(sortVec.begin(), sortVec.end(),
valsDecreasing);
248 for (
unsigned short indx = 0; indx < temp.size(); ++indx)
249 vlist[indx] = temp[sortVec[indx].index];
253 auto& vx3 = slc.
vtx3s[vlist[0] - 1];
259 auto& sf = neutrinoPFP.SectionFits[0];
265 neutrinoPFP.PDGCode = 14;
266 neutrinoPFP.Vx3ID[1] = vx3.ID;
267 neutrinoPFP.Vx3ID[0] = vx3.ID;
270 if (!
StorePFP(slc, neutrinoPFP))
return;
274 std::vector<bool> lookedAt3(slc.
vtx3s.size() + 1,
false);
275 std::vector<bool> lookedAt2(slc.
vtxs.size() + 1,
false);
277 std::vector<std::pair<int, int>> pardtr;
279 for (
unsigned short indx = 0; indx < vlist.size(); ++indx) {
280 auto& vx3 = slc.
vtx3s[vlist[indx] - 1];
281 if (lookedAt3[vx3.ID])
continue;
283 lookedAt3[vx3.ID] =
true;
287 if (primTjList.empty())
continue;
289 for (
auto primTjID : primTjList) {
290 auto& primTj = slc.
tjs[primTjID - 1];
292 if (primTj.ParentID != -1)
continue;
293 if (prt) mf::LogVerbatim(
"TC") <<
"Vx3 " << vx3.ID <<
" Primary tj " << primTj.ID;
298 for (
unsigned short end = 0;
end < 2; ++
end) {
299 if (primTj.VtxID[
end] == 0)
continue;
300 auto& vx2 = slc.
vtxs[primTj.VtxID[
end] - 1];
301 if (vx2.Vx3ID == vx3.ID)
continue;
304 for (
auto dtrID : dtrList) {
306 if (dtrID == primTjID)
continue;
307 auto& dtj = slc.
tjs[dtrID - 1];
308 if (dtj.ParentID != -1)
continue;
309 pardtr.push_back(std::make_pair(primTjID, dtrID));
310 if (prt) mf::LogVerbatim(
"TC") <<
" primTj " << primTjID <<
" dtrID " << dtrID;
314 for (
unsigned short end = 0;
end < 2; ++
end) {
315 if (primTj.VtxID[
end] == 0)
continue;
316 auto& vx2 = slc.
vtxs[primTj.VtxID[
end] - 1];
320 if (pardtr.empty())
continue;
322 mf::LogVerbatim myprt(
"TC");
324 for (
auto pdtr : pardtr)
325 myprt <<
" " << pdtr.first <<
"_" << pdtr.second;
329 for (
unsigned short nit = 0; nit < 100; ++nit) {
330 auto lastPair = pardtr[pardtr.size() - 1];
331 auto& dtj = slc.
tjs[lastPair.second - 1];
332 dtj.ParentID = lastPair.first;
335 unsigned short dpt = 0, ppt = 0;
336 auto& ptj = slc.
tjs[lastPair.first - 1];
340 if (prt) mf::LogVerbatim(
"TC") <<
"Set parent " << ptj.ID <<
" dtr " << dtj.ID;
344 for (
unsigned short end = 0;
end < 2; ++
end) {
345 if (dtj.VtxID[
end] == 0)
continue;
346 auto& vx2 = slc.
vtxs[dtj.VtxID[
end] - 1];
347 if (lookedAt2[vx2.ID])
continue;
348 lookedAt2[vx2.ID] =
true;
350 for (
auto tjid : tjlist) {
351 if (tjid == dtj.ID || tjid == ptj.ID)
continue;
352 pardtr.push_back(std::make_pair(dtj.ID, tjid));
354 mf::LogVerbatim myprt(
"TC");
355 myprt <<
" add par_dtr";
356 for (
auto pdtr : pardtr)
357 myprt <<
" " << pdtr.first <<
"_" << pdtr.second;
361 if (pardtr.empty())
break;
365 for (
auto tjid : masterlist) {
366 auto& tj = slc.
tjs[tjid - 1];
367 if (tj.ParentID < 0) tj.ParentID = tj.ID;
377 if (tjIDs.size() < 2)
return 1;
378 std::vector<float> plnchg(slc.
nPlanes);
379 for (
auto tjid : tjIDs) {
380 if (tjid <= 0 || tjid > (
int)slc.
tjs.size())
return 1;
381 auto& tj = slc.
tjs[tjid - 1];
384 plnchg[plane] += tj.TotChg;
388 for (
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
389 if (plnchg[plane] == 0)
continue;
390 aveChg += plnchg[plane];
393 if (cnt < 2)
return 1;
396 for (
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
398 if (plnchg[plane] == 0)
continue;
399 float asym =
std::abs(plnchg[plane] - aveChg) / (plnchg[plane] + aveChg);
400 if (asym > maxAsym) maxAsym = asym;
416 std::array<int, 5> codeList = {{0, 11, 13, 111, 211}};
417 unsigned short codeIndex = 0;
418 if (tjIDs.empty())
return codeList[codeIndex];
420 std::array<unsigned short, 5> cnts;
423 for (
auto tjid : tjIDs) {
424 if (tjid <= 0 || tjid > (
int)slc.
tjs.size())
continue;
425 auto& tj = slc.
tjs[tjid - 1];
426 for (
unsigned short ii = 0; ii < 5; ++ii)
427 if (tj.PDGCode == codeList[ii]) ++cnts[ii];
429 if (len > maxLen) maxLen = len;
433 for (
unsigned short ii = 1; ii < 5; ++ii) {
434 if (cnts[ii] > maxCnt) {
439 return codeList[codeIndex];
451 if (primID <= 0 || primID > (
int)slc.
tjs.size())
return -1;
454 auto& ptj = slc.
tjs[primID - 1];
455 for (
unsigned short end = 0;
end < 2; ++
end) {
456 if (ptj.VtxID[
end] == 0)
continue;
457 auto& vx2 = slc.
vtxs[ptj.VtxID[
end] - 1];
458 if (vx2.Vx3ID == 0)
continue;
459 auto& vx3 = slc.
vtx3s[vx2.Vx3ID - 1];
460 if (vx3.Neutrino)
return primID;
475 for (
unsigned short nit = 0; nit < 10; ++nit) {
476 if (parid < 1 || parid > (
int)slc.
tjs.size())
break;
477 auto& tj = slc.
tjs[parid - 1];
493 int dtruid = pfp.
UID;
494 unsigned short nit = 0;
497 auto& parent =
slices[slcIndx.first].pfps[slcIndx.second];
499 if (parent.PDGCode == 14 || parent.PDGCode == 12)
return dtruid;
501 if (parent.ParentUID == 0)
return parent.UID;
502 if (
int(parent.ParentUID) == parent.UID)
return parent.UID;
504 paruid = parent.ParentUID;
505 if (paruid < 0)
return 0;
507 if (nit == 10)
return 0;
516 if (mtjid > (
int)slc.
tjs.size())
return false;
517 auto& mtj = slc.
tjs[mtjid - 1];
520 for (
auto tjid : pfp.
TjIDs) {
521 auto& otj = slc.
tjs[tjid - 1];
522 if (otj.CTP == mtj.CTP) {
527 if (otjid == 0)
return false;
529 int newtjid = slc.
tjs.size();
531 mf::LogVerbatim(
"TC") <<
"MergeTjIntoPFP: merged T" << otjid <<
" with T" << mtjid
532 <<
" -> T" << newtjid;
533 std::replace(pfp.
TjIDs.begin(), pfp.
TjIDs.begin(), otjid, newtjid);
538 mf::LogVerbatim(
"TC") <<
"MergeTjIntoPFP: merge T" << otjid <<
" with T" << mtjid
551 if (tj.
AveChg <= 0)
return 100;
553 unsigned short closePt = USHRT_MAX;
555 for (
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
556 auto& tp = tj.
Pts[ipt];
557 float sep2 =
PosSep2(pos, tp.Pos);
558 if (sep2 > close)
continue;
562 if (closePt == USHRT_MAX)
return 100;
564 auto& tp = tj.
Pts[closePt];
567 float posErr = tp.DeltaRMS;
568 if (tp.AngErr > 0 && close > 10) posErr += sqrt(tp.AngErr * sqrt(close));
569 if (posErr < 0.1) posErr = 0.1;
570 float posPull = delta / posErr;
572 if (chgErr < 0.15) chgErr = 0.15;
575 return 0.5 * (posPull + chgPull);
594 if (tjIDs.size() < 2)
return false;
595 unsigned short lasttj = tjIDs[tjIDs.size() - 1] - 1;
596 auto& mtj = slc.
tjs[lasttj];
597 bool mtjIsShort = (mtj.Pts.size() < 5);
599 std::array<float, 2> minsep2{{1000, 1000}};
601 std::array<int, 2> minsepTj{{0, 0}};
603 std::array<unsigned short, 2> minsepPt;
606 std::array<unsigned short, 2> minsepEnd;
607 for (
auto tjid : tjIDs) {
608 auto& tj = slc.
tjs[tjid - 1];
609 if (tj.CTP != mtj.CTP)
continue;
610 if (tj.ID == mtj.ID)
continue;
611 for (
unsigned short mend = 0; mend < 2; ++mend) {
612 Point2_t mendPos = mtj.Pts[mtj.EndPt[mend]].Pos;
613 float sep2 = minsep2[mend];
614 unsigned short closePt = 0;
616 minsep2[mend] = sep2;
617 minsepTj[mend] = tjid;
618 minsepPt[mend] = closePt;
621 short dend0 =
abs((
short)closePt - tj.EndPt[0]);
622 short dend1 =
abs((
short)closePt - tj.EndPt[1]);
623 if (dend0 < dend1 && dend0 < 3) minsepEnd[mend] = 0;
624 if (dend1 < dend0 && dend1 < 3) minsepEnd[mend] = 1;
630 bool isCompatible = (minsepEnd[0] != 2 && minsepEnd[1] != 2);
632 if (isCompatible && mtjIsShort) {
633 float minminsep = minsep2[0];
634 if (minsep2[1] < minminsep) minminsep = minsep2[1];
636 isCompatible = minminsep < 5;
639 mf::LogVerbatim myprt(
"TC");
640 myprt <<
"CompatibleMerge: T" << mtj.ID <<
" end";
641 for (
unsigned short end = 0;
end < 2; ++
end)
642 myprt <<
" T" << minsepTj[
end] <<
"_I" << minsepPt[
end] <<
"_E" << minsepEnd[
end]
643 <<
" minsep " << sqrt(minsep2[
end]);
644 myprt <<
" Compatible? " << isCompatible;
658 if (tj1.
CTP != tj2.
CTP)
return false;
659 unsigned short end1 = -1, end2 = 0;
662 if (len2 < minLen) minLen = len2;
664 if (minLen > 10) minLen = 10;
665 for (
unsigned short e1 = 0;
e1 < 2; ++
e1) {
667 for (
unsigned short e2 = 0; e2 < 2; ++e2) {
669 float sep =
PosSep(tp1.Pos, tp2.Pos);
677 if (end1 < 0)
return false;
679 if (end2 != 1 - end1)
return false;
682 if (overlapFraction > 0.25) {
684 mf::LogVerbatim(
"TC") <<
"CM: " << tj1.
ID <<
" " << tj2.
ID <<
" overlapFraction "
685 << overlapFraction <<
" > 0.25 ";
689 auto& tp1 = tj1.
Pts[tj1.
EndPt[end1]];
690 auto& tp2 = tj2.
Pts[tj2.
EndPt[end2]];
691 float doca1 =
PointTrajDOCA(slc, tp1.Pos[0], tp1.Pos[1], tp2);
692 float doca2 =
PointTrajDOCA(slc, tp2.Pos[0], tp2.Pos[1], tp1);
693 if (doca1 > 2 && doca2 > 2) {
695 mf::LogVerbatim(
"TC") <<
"CM: " << tj1.
ID <<
" " << tj2.
ID <<
" Both docas > 2 " << doca1
703 mf::LogVerbatim(
"TC") <<
"CM: " << tj1.
ID <<
" " << tj2.
ID <<
" dang " << dang <<
" > "
717 float maxWire = -1E6;
720 for (
auto& tp : tj1.
Pts) {
721 if (tp.Chg == 0)
continue;
722 if (tp.Pos[0] < 0)
continue;
723 if (tp.Pos[0] < minWire) minWire = tp.Pos[0];
724 if (tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
727 if (cnt1 == 0)
return 0;
729 for (
auto& tp : tj2.
Pts) {
730 if (tp.Chg == 0)
continue;
731 if (tp.Pos[0] < 0)
continue;
732 if (tp.Pos[0] < minWire) minWire = tp.Pos[0];
733 if (tp.Pos[0] > maxWire) maxWire = tp.Pos[0];
736 if (cnt2 == 0)
return 0;
737 int span = maxWire - minWire;
738 if (span <= 0)
return 0;
739 std::vector<unsigned short> wcnt(span);
740 for (
auto& tp : tj1.
Pts) {
741 if (tp.Chg == 0)
continue;
742 if (tp.Pos[0] < -0.4)
continue;
743 int indx = std::nearbyint(tp.Pos[0] - minWire);
744 if (indx < 0 || indx > span - 1)
continue;
747 for (
auto& tp : tj2.
Pts) {
748 if (tp.Chg == 0)
continue;
749 if (tp.Pos[0] < -0.4)
continue;
750 int indx = std::nearbyint(tp.Pos[0] - minWire);
751 if (indx < 0 || indx > span - 1)
continue;
754 float cntOverlap = 0;
755 for (
auto cnt : wcnt)
756 if (cnt > 1) ++cntOverlap;
757 if (cnt1 < cnt2) {
return cntOverlap / cnt1; }
759 return cntOverlap / cnt2;
796 if (angle > M_PI) angle = M_PI;
797 if (angle < -M_PI) angle = M_PI;
798 if (angle < 0) angle = -
angle;
799 if (angle > M_PI / 2) angle = M_PI -
angle;
811 unsigned short originPt = tj.
EndPt[1];
812 unsigned short npts = tj.
Pts[originPt].NTPsFit;
814 unsigned short fitDir = -1;
815 FitTraj(slc, tj, originPt, npts, fitDir, tpFit);
816 tj.
Pts[originPt] = tpFit;
824 unsigned short originPt,
844 if (originPt > tj.
Pts.size() - 1) {
845 mf::LogWarning(
"TC") <<
"FitTraj: Requesting fit of invalid TP " << originPt;
850 tpFit = tj.
Pts[originPt];
853 if (fitDir < -1 || fitDir > 1)
return;
855 std::vector<double>
x,
y;
858 if (tj.
Pts[originPt].Chg == 0) origin = tj.
Pts[originPt].Pos;
862 for (
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1]; ++ipt) {
863 if (tj.
Pts[ipt].Chg <= 0)
continue;
864 double xx = tj.
Pts[ipt].HitPos[0] - origin[0];
865 double yy = tj.
Pts[ipt].HitPos[1] - origin[1];
869 if (x.size() != 2)
return;
872 tpFit.
Ang = M_PI / 2;
873 if (y[1] < y[0]) tpFit.
Ang = -tpFit.
Ang;
876 double dx = x[1] - x[0];
877 double dy = y[1] - y[0];
878 tpFit.
Ang = atan2(dy, dx);
880 tpFit.
Dir[0] = cos(tpFit.
Ang);
881 tpFit.
Dir[1] = sin(tpFit.
Ang);
882 tpFit.
Pos[0] += origin[0];
883 tpFit.
Pos[1] += origin[1];
890 std::vector<double>
w,
q;
891 std::array<double, 2>
dir;
892 double xx, yy, xr, yr;
897 double rotAngle = tj.
Pts[originPt].Ang;
898 double cs = cos(-rotAngle);
899 double sn = sin(-rotAngle);
902 if (tj.
Pts[originPt].Chg > 0) {
903 xx = tj.
Pts[originPt].HitPos[0] - origin[0];
904 yy = tj.
Pts[originPt].HitPos[1] - origin[1];
905 xr = cs * xx - sn * yy;
906 yr = sn * xx + cs * yy;
909 chgWt = tj.
Pts[originPt].ChgPull;
910 if (chgWt < 1) chgWt = 1;
912 w.push_back(chgWt * tj.
Pts[originPt].HitPosErr2);
916 if (fitDir != 0) --npts;
920 unsigned short cnt = 0;
921 for (
unsigned short ipt = originPt + 1; ipt < tj.
Pts.size(); ++ipt) {
922 if (tj.
Pts[ipt].Chg <= 0)
continue;
923 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
924 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
925 xr = cs * xx - sn * yy;
926 yr = sn * xx + cs * yy;
929 chgWt = tj.
Pts[ipt].ChgPull;
930 if (chgWt < 1) chgWt = 1;
932 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
934 if (cnt == npts)
break;
939 if (fitDir != 1 && originPt > 0) {
940 unsigned short cnt = 0;
941 for (
unsigned short ii = 1; ii < tj.
Pts.size(); ++ii) {
942 unsigned short ipt = originPt - ii;
943 if (ipt > tj.
Pts.size() - 1)
continue;
944 if (tj.
Pts[ipt].Chg == 0)
continue;
945 xx = tj.
Pts[ipt].HitPos[0] - origin[0];
946 yy = tj.
Pts[ipt].HitPos[1] - origin[1];
947 xr = cs * xx - sn * yy;
948 yr = sn * xx + cs * yy;
951 chgWt = tj.
Pts[ipt].ChgPull;
952 if (chgWt < 1) chgWt = 1;
954 w.push_back(chgWt * tj.
Pts[ipt].HitPosErr2);
956 if (cnt == npts)
break;
962 if (x.size() < 2)
return;
973 for (
unsigned short ipt = 0; ipt < x.size(); ++ipt) {
974 if (w[ipt] < 0.00001) w[ipt] = 0.00001;
977 sumx += wght * x[ipt];
978 sumy += wght * y[ipt];
979 sumx2 += wght * x[ipt] * x[ipt];
980 sumy2 += wght * y[ipt] * y[ipt];
981 sumxy += wght * x[ipt] * y[ipt];
984 double delta = sum * sumx2 - sumx * sumx;
985 if (delta == 0)
return;
987 double A = (sumx2 * sumy - sumx * sumxy) / delta;
989 double B = (sumxy * sum - sumx * sumy) / delta;
994 double newang = atan(B);
995 dir[0] = cos(newang);
996 dir[1] = sin(newang);
1000 tpFit.
Dir[0] = cs * dir[0] - sn * dir[1];
1001 tpFit.
Dir[1] = sn * dir[0] + cs * dir[1];
1003 bool flipDir =
false;
1005 flipDir = std::signbit(tpFit.
Dir[1]) != std::signbit(tj.
Pts[originPt].Dir[1]);
1008 flipDir = std::signbit(tpFit.
Dir[0]) != std::signbit(tj.
Pts[originPt].Dir[0]);
1011 tpFit.
Dir[0] = -tpFit.
Dir[0];
1012 tpFit.
Dir[1] = -tpFit.
Dir[1];
1014 tpFit.
Ang = atan2(tpFit.
Dir[1], tpFit.
Dir[0]);
1018 tpFit.
Pos[0] = -sn * A + origin[0];
1019 tpFit.
Pos[1] = cs * A + origin[1];
1023 if (x.size() < 3)
return;
1026 double ndof = x.size() - 2;
1028 (sumy2 + A * A * sum + B * B * sumx2 - 2 * (A * sumy + B * sumxy - A * B * sumx)) / ndof;
1032 double slopeError = sqrt(varnce * sum / delta);
1041 for (
unsigned short ii = 0; ii < y.size(); ++ii) {
1042 arg = y[ii] - A - B * x[ii];
1043 sum += arg * arg / w[ii];
1045 tpFit.
FitChi = sum / ndof;
1052 if (slc.
pfps.empty())
return USHRT_MAX;
1053 for (
unsigned int ipfp = 0; ipfp < slc.
pfps.size(); ++ipfp) {
1054 const auto& pfp = slc.
pfps[ipfp];
1055 if (std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tjID) != pfp.TjIDs.end())
return ipfp;
1065 for (
auto& tp : tj.
Pts) {
1066 for (
auto iht : tp.Hits) {
1078 for (
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
1093 for (
auto& tp : tj.
Pts) {
1094 if (tp.Hits.size() > 16)
return false;
1107 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0] + 1;
1108 if (npts < 2)
return false;
1110 auto& endTp0 = tj.
Pts[tj.
EndPt[0]];
1111 auto& endTp1 = tj.
Pts[tj.
EndPt[1]];
1115 if (endTp0.AngErr == 0.1 && endTp1.AngErr != 0.1) { endTp0.AngErr = endTp1.AngErr; }
1116 else if (endTp0.AngErr != 0.1 && endTp1.AngErr == 0.1) {
1117 endTp1.AngErr = endTp0.AngErr;
1123 if (endTp0.AveChg <= 0) {
1124 unsigned short cnt = 0;
1126 for (
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1127 if (tj.
Pts[ipt].Chg == 0)
continue;
1128 sum += tj.
Pts[ipt].Chg;
1130 if (cnt == 4)
break;
1132 tj.
Pts[tj.
EndPt[0]].AveChg = sum / (float)cnt;
1134 if (endTp1.AveChg <= 0 && npts < 5) endTp1.AveChg = endTp0.AveChg;
1135 if (endTp1.AveChg <= 0) {
1137 unsigned short cnt = 0;
1138 for (
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
1139 short ipt = tj.
EndPt[1] - ii;
1141 if (tj.
Pts[ipt].Chg == 0)
continue;
1142 sum += tj.
Pts[ipt].Chg;
1144 if (cnt == 4)
break;
1145 if (ipt == 0)
break;
1147 tj.
Pts[tj.
EndPt[1]].AveChg = sum / (float)cnt;
1154 if (npts > 2 * nPtsFit) {
1155 for (
unsigned short ipt = tj.
EndPt[0] + nPtsFit; ipt < tj.
EndPt[1] - nPtsFit; ++ipt) {
1156 auto& tp = tj.
Pts[ipt];
1157 if (tp.KinkSig < 0) tp.KinkSig =
KinkSignificance(slc, tj, ipt, nPtsFit, useChg,
false);
1164 int trID = slc.
tjs.size() + 1;
1166 for (
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
1167 for (
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1168 if (tj.
Pts[ipt].UseHit[ii]) {
1169 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1170 if (iht > slc.
slHits.size() - 1) {
1174 if (slc.
slHits[iht].InTraj > 0) {
1178 slc.
slHits[iht].InTraj = trID;
1184 for (
unsigned int iht = 0; iht < slc.
slHits.size(); ++iht) {
1185 if (slc.
slHits[iht].InTraj == tj.
ID) {
1186 mf::LogWarning(
"TC") <<
"StoreTraj: Hit " <<
PrintHit(slc.
slHits[iht])
1187 <<
" thinks it belongs to T" << tj.
ID <<
" but it isn't in the Tj\n";
1199 slc.
tjs.push_back(tj);
1202 for (
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
1203 for (
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
1204 unsigned int iht = tj.
Pts[ipt].Hits[ii];
1206 std::cout <<
"Debug hit appears in trajectory w WorkID " << tj.
WorkID <<
" UseHit "
1207 << tj.
Pts[ipt].UseHit[ii] <<
"\n";
1221 unsigned short originPt,
1222 unsigned short npts,
1225 unsigned short usePar)
1232 if (originPt > tj.
Pts.size() - 1)
return;
1233 if (fitDir != 1 && fitDir != -1)
return;
1237 Fit2D(0, inPt, pErr, outVec, outVecErr, chiDOF);
1238 unsigned short cnt = 0;
1239 for (
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
1240 unsigned short ipt = originPt + ii * fitDir;
1241 if (ipt < tj.
EndPt[0] || ipt > tj.
EndPt[1])
break;
1242 auto& tp = tj.
Pts[ipt];
1243 if (tp.Chg <= 0)
continue;
1245 inPt[0] =
std::abs(tp.Pos[0] - tj.
Pts[originPt].Pos[0]);
1246 float parVal = tp.Chg;
1248 pErr = 0.1 * parVal;
1252 pErr = sqrt(tp.HitPosErr2);
1256 if (!
Fit2D(2, inPt, pErr, outVec, outVecErr, chiDOF))
break;
1258 if (cnt == npts)
break;
1260 if (cnt < npts)
return;
1262 if (!
Fit2D(-1, inPt, pErr, outVec, outVecErr, chiDOF))
return;
1263 pFit.
Pos = tj.
Pts[originPt].Pos;
1264 pFit.
Par0 = outVec[0];
1265 pFit.
AvePar /= (float)cnt;
1266 pFit.
ParErr = outVecErr[0];
1267 pFit.
Pos = tj.
Pts[originPt].Pos;
1282 unsigned short itj = 0;
1283 std::vector<unsigned int> tHits;
1284 std::vector<unsigned int> atHits;
1285 for (
auto& tj : slc.
tjs) {
1287 if (tj.AlgMod[
kKilled])
continue;
1290 if (tHits.size() < 2)
continue;
1291 std::sort(tHits.begin(), tHits.end());
1293 for (iht = 0; iht < slc.
slHits.size(); ++iht) {
1294 if (slc.
slHits[iht].InTraj == tID) atHits.push_back(iht);
1296 if (atHits.size() < 2)
continue;
1297 if (!
std::equal(tHits.begin(), tHits.end(), atHits.begin())) {
1298 mf::LogVerbatim myprt(
"TC");
1299 myprt << someText <<
" ChkInTraj failed: inTraj - UseHit mis-match for T" << tID
1300 <<
" tj.WorkID " << tj.WorkID <<
" atHits size " << atHits.size() <<
" tHits size "
1301 << tHits.size() <<
" in CTP " << tj.CTP <<
"\n";
1302 myprt <<
"AlgMods: ";
1303 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
1304 if (tj.AlgMod[ib]) myprt <<
" " <<
AlgBitNames[ib];
1306 myprt <<
"index inTraj UseHit \n";
1307 for (iht = 0; iht < atHits.size(); ++iht) {
1308 myprt <<
"iht " << iht <<
" " <<
PrintHit(slc.
slHits[atHits[iht]]);
1309 if (iht < tHits.size()) myprt <<
" " <<
PrintHit(slc.
slHits[tHits[iht]]);
1310 if (atHits[iht] != tHits[iht]) myprt <<
" <<< " << atHits[iht] <<
" != " << tHits[iht];
1313 if (tHits.size() > atHits.size()) {
1314 for (iht = atHits.size(); iht < atHits.size(); ++iht) {
1315 myprt <<
"atHits " << iht <<
" " <<
PrintHit(slc.
slHits[atHits[iht]]) <<
"\n";
1322 for (
unsigned short end = 0;
end < 2; ++
end) {
1323 if (tj.VtxID[
end] > slc.
vtxs.size()) {
1324 mf::LogVerbatim(
"TC") << someText <<
" ChkInTraj: Bad VtxID " << tj.ID;
1349 if (itj > slc.
tjs.size() - 1)
return;
1350 auto& tj = slc.
tjs[itj];
1353 if (tj.EndFlag[0][
kBragg])
return;
1356 if (tj.Pts.size() < 20)
return;
1361 float chg2 = tj.Pts[tj.EndPt[0] + 2].AveChg;
1363 float chg15 = tj.Pts[tj.EndPt[0] + 15].AveChg;
1364 if (chg2 < 3 * chg15)
return;
1367 float midChg = 0.5 * (chg2 + chg15);
1369 unsigned short breakPt = USHRT_MAX;
1370 for (
unsigned short ipt = tj.EndPt[0] + 3; ipt < 15; ++ipt) {
1371 float chgm2 = tj.Pts[ipt - 2].Chg;
1372 if (chgm2 == 0)
continue;
1373 float chgm1 = tj.Pts[ipt - 1].Chg;
1374 if (chgm1 == 0)
continue;
1375 float chgp1 = tj.Pts[ipt + 1].Chg;
1376 if (chgp1 == 0)
continue;
1377 float chgp2 = tj.Pts[ipt + 2].Chg;
1378 if (chgp2 == 0)
continue;
1379 if (chgm2 > midChg && chgm1 > midChg && chgp1 < midChg && chgp2 < midChg) {
1384 if (breakPt == USHRT_MAX)
return;
1386 std::array<double, 2> cnt, sum, sum2;
1387 for (
unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
1388 auto& tp = tj.Pts[ipt];
1389 if (tp.Chg <= 0)
continue;
1390 unsigned short end = 0;
1391 if (ipt > breakPt) end = 1;
1394 sum2[
end] += tp.Chg * tp.Chg;
1396 for (
unsigned short end = 0;
end < 2; ++
end) {
1397 if (cnt[
end] < 3)
return;
1398 double ave = sum[
end] / cnt[
end];
1399 double arg = sum2[
end] - cnt[
end] * ave * ave;
1400 if (arg <= 0)
return;
1401 sum2[
end] = sqrt(arg / (cnt[
end] - 1));
1405 bool doSplit =
true;
1408 if (tj.ChgRMS > 0.5 && sum2[0] > 0.3 && sum2[1] > 0.3) doSplit =
false;
1410 mf::LogVerbatim myprt(
"TC");
1411 myprt <<
"CTBC: T" << tj.ID <<
" chgRMS " << tj.ChgRMS;
1412 myprt <<
" AveChg before split point " << (int)sum[0] <<
" rms " << sum2[0];
1413 myprt <<
" after " << (int)sum[1] <<
" rms " << sum2[1] <<
" doSplit? " << doSplit;
1415 if (!doSplit)
return;
1418 aVtx.
Pos = tj.Pts[breakPt].Pos;
1420 aVtx.
Pass = tj.Pass;
1424 aVtx.
ID = slc.
vtxs.size() + 1;
1426 unsigned short ivx = slc.
vtxs.size();
1428 if (!
SplitTraj(slc, itj, breakPt, ivx, prt)) {
1429 if (prt) mf::LogVerbatim(
"TC") <<
"CTBC: Failed to split trajectory";
1437 mf::LogVerbatim(
"TC") <<
"CTBC: Split T" << tj.ID <<
" at "
1438 <<
PrintPos(slc, tj.Pts[breakPt].Pos) <<
"\n";
1448 if (itj > slc.
tjs.size() - 1)
return false;
1452 auto& tj = slc.
tjs[itj];
1454 if (npwc < 4)
return false;
1455 if (npwc < nPtsToCheck) nPtsToCheck = npwc;
1458 unsigned short maxPullPt = USHRT_MAX;
1459 for (
unsigned short ipt = tj.EndPt[0]; ipt < tj.EndPt[1]; ++ipt) {
1460 auto& tp = tj.Pts[ipt];
1461 if (tp.ChgPull < maxPull)
continue;
1462 maxPull = tp.ChgPull;
1465 if (maxPullPt == USHRT_MAX)
return false;
1467 if (maxPullPt < 0.5 * (tj.EndPt[0] + tj.EndPt[1])) { dpt = maxPullPt - tj.EndPt[0]; }
1469 dpt = tj.EndPt[1] - maxPullPt;
1471 if (dpt < 3)
return false;
1474 mf::LogVerbatim(
"TC") <<
"BS: T" << tj.ID <<
" maxPull " << maxPull <<
" at "
1475 <<
PrintPos(slc, tj.Pts[maxPullPt]) <<
" dpt " << dpt;
1476 unsigned short breakPt = USHRT_MAX;
1478 unsigned short bestBragg = 0;
1482 for (
unsigned short ipt = maxPullPt - 2; ipt <= maxPullPt + 2; ++ipt) {
1483 FitTraj(slc, tj, ipt - 1, nPtsFit, -1, tp1);
1484 if (tp1.
FitChi > 10)
continue;
1485 FitTraj(slc, tj, ipt + 1, nPtsFit, 1, tp2);
1486 if (tp2.
FitChi > 10)
continue;
1488 FitPar(slc, tj, ipt - 1, nPtsToCheck, -1, chgFit1, 1);
1489 if (chgFit1.
ChiDOF > 100)
continue;
1491 FitPar(slc, tj, ipt + 1, nPtsToCheck, 1, chgFit2, 1);
1492 if (chgFit2.
ChiDOF > 100)
continue;
1497 unsigned short bragg = 1;
1498 float bchi = chgFit1.
ChiDOF;
1505 if (bchi < 1) bchi = 1;
1506 float fom = 10 * dang * chgAsym * slpAsym / bchi;
1508 mf::LogVerbatim myprt(
"TC");
1509 myprt <<
"pt " <<
PrintPos(slc, tj.Pts[ipt]) <<
" " << std::setprecision(2) << dang;
1510 myprt <<
" chg1 " << (int)chgFit1.
Par0 <<
" slp " << chgFit1.
ParSlp <<
" chi "
1512 myprt <<
" chg2 " << (
int)chgFit2.
Par0 <<
" slp " << chgFit2.
ParSlp <<
" chi "
1514 myprt <<
" chgAsym " << chgAsym;
1515 myprt <<
" slpAsym " << slpAsym;
1516 myprt <<
" fom " << fom;
1517 myprt <<
" bragg " << bragg;
1519 if (fom < bestFOM)
continue;
1524 if (breakPt == USHRT_MAX)
return false;
1526 mf::LogVerbatim(
"TC") <<
" breakPt " <<
PrintPos(slc, tj.Pts[breakPt]) <<
" bragg "
1530 aVtx.
Pos = tj.Pts[breakPt].Pos;
1532 aVtx.
Pass = tj.Pass;
1536 aVtx.
ID = slc.
vtxs.size() + 1;
1538 unsigned short ivx = slc.
vtxs.size();
1540 if (!
SplitTraj(slc, itj, breakPt, ivx, prt)) {
1541 if (prt) mf::LogVerbatim(
"TC") <<
"BS: Failed to split trajectory";
1547 unsigned short otj = slc.
tjs.size() - 1;
1548 if (bestBragg == 2) std::swap(itj, otj);
1549 slc.
tjs[itj].PDGCode = 211;
1551 slc.
tjs[otj].PDGCode = 13;
1562 if (tj.
PDGCode == 111)
return;
1565 if (npwc < 50)
return;
1571 if (nPtsMax > 8) nPtsMax = 8;
1576 unsigned short firstBad = USHRT_MAX;
1577 for (
unsigned short ii = 0; ii < nPtsMax; ++ii) {
1578 unsigned short ipt = tj.
EndPt[1] - nPtsMax + ii;
1579 auto& tp = tj.
Pts[ipt];
1580 if (tp.Chg <= 0)
continue;
1581 if (tp.ChgPull < 3)
continue;
1583 if (firstBad == USHRT_MAX) firstBad = ipt;
1585 if (firstBad == USHRT_MAX)
return;
1587 float cntTot = tj.
EndPt[1] - firstBad;
1589 float fracBad = cntBad / cntTot;
1590 if (fracBad < 0.5)
return;
1592 mf::LogVerbatim(
"TC") <<
"THCEP: Trim points starting at " <<
PrintPos(slc, tj.
Pts[firstBad]);
1593 for (
unsigned short ipt = firstBad; ipt <= tj.
EndPt[1]; ++ipt)
1603 const std::vector<float>& fQualityCuts,
1616 if (tj.
PDGCode == 111)
return;
1620 short minPts = fQualityCuts[1];
1621 if (minPts < 1)
return;
1622 if (npwc < minPts)
return;
1624 if (npwc < 8)
return;
1627 if (npwc == minPts + 1) {
1628 unsigned short endPt1 = tj.
EndPt[1];
1629 auto& tp = tj.
Pts[endPt1];
1630 auto& ptp = tj.
Pts[endPt1 - 1];
1633 float dwire =
std::abs(ptp.Pos[0] - tp.Pos[0]);
1634 if (ptp.Chg == 0 || dwire > 1.1) {
1644 for (lastPt = tj.
EndPt[1]; lastPt >= minPts; --lastPt) {
1646 if (lastPt == 1)
break;
1647 if (tj.
Pts[lastPt].Chg == 0)
continue;
1649 unsigned short nadj = 0;
1650 unsigned short npwc = 0;
1651 for (
short ipt = lastPt - minPts; ipt < lastPt; ++ipt) {
1654 auto& tp = tj.
Pts[ipt];
1656 auto& ptp = tj.
Pts[ipt - 1];
1657 if (tp.Chg > 0 && ptp.Chg > 0) {
1659 if (
std::abs(tp.Pos[0] - ptp.Pos[0]) < 1.5) ++nadj;
1664 float hitFrac = ntpwc / nwires;
1666 mf::LogVerbatim(
"TC") << fcnLabel <<
"-TEP: T" << tj.
ID <<
" lastPt " << lastPt <<
" npwc "
1667 << npwc <<
" ntpwc " << ntpwc <<
" nadj " << nadj <<
" hitFrac "
1669 if (hitFrac > fQualityCuts[0] && npwc == minPts && nadj >= minPts - 1)
break;
1672 if (prt) mf::LogVerbatim(
"TC") <<
" lastPt " << lastPt <<
" " << tj.
EndPt[1] <<
"\n";
1674 if (tj.
Pts[lastPt].Pos[0] > -0.4) {
1675 unsigned int prevWire = std::nearbyint(tj.
Pts[lastPt].Pos[0]);
1676 if (tj.
StepDir > 0) { --prevWire; }
1681 mf::LogVerbatim(
"TC") << fcnLabel <<
"-TEP: is prevWire " << prevWire <<
" dead? ";
1688 if (lastPt == tj.
EndPt[1]) {
1689 if (prt) mf::LogVerbatim(
"TC") << fcnLabel <<
"-TEPo: Tj is OK";
1694 for (
unsigned short ipt = lastPt + 1; ipt <= tj.
EndPt[1]; ++ipt)
1699 fcnLabel +=
"-TEPo";
1711 if (tj.
PDGCode == 111)
return;
1714 if (prt) mf::LogVerbatim(
"TC") <<
"CEK: Inside ChkEndKinks T" << tj.
ID <<
" ";
1717 unsigned short withNptsFit = 0;
1720 for (
unsigned short nptsf = 3; nptsf < nPtsFit; ++nptsf) {
1721 unsigned short ipt = tj.
EndPt[1] - nptsf;
1725 withNptsFit = nptsf;
1728 if (withNptsFit > 0) {
1729 unsigned short ipt = tj.
EndPt[1] - withNptsFit;
1732 auto& tp = tj.
Pts[ipt];
1733 std::cout <<
" " <<
PrintPos(slc, tp) <<
" withNptsFit " << withNptsFit <<
" ks " << ks
1748 if (tj.
PDGCode == 111)
return;
1749 unsigned short npts = tj.
EndPt[1] - tj.
EndPt[0];
1750 if (prt) mf::LogVerbatim(
"TC") <<
" Inside ChkChgAsymmetry T" << tj.
ID;
1752 if (npts > 50)
return;
1754 if (npts < 8)
return;
1757 unsigned short atPt = 0;
1759 for (
unsigned short ipt = tj.
EndPt[0] + 2; ipt <= tj.
EndPt[1] - 2; ++ipt) {
1760 auto& tp = tj.
Pts[ipt];
1761 if (tp.ChgPull > bigPull) {
1762 bigPull = tp.ChgPull;
1766 if (atPt == 0)
return;
1768 if ((atPt - tj.
EndPt[0]) < 0.5 * npts)
return;
1770 mf::LogVerbatim(
"TC") <<
"CCA: T" << tj.
ID <<
" Large Chg point at " << atPt
1771 <<
". Check charge asymmetry around it.";
1772 unsigned short nchk = 0;
1773 unsigned short npos = 0;
1774 unsigned short nneg = 0;
1775 for (
short ii = 1; ii < 5; ++ii) {
1776 short iplu = atPt + ii;
1777 if (iplu > tj.
EndPt[1])
break;
1778 short ineg = atPt - ii;
1779 if (ineg < tj.
EndPt[0])
break;
1780 if (tj.
Pts[iplu].Chg == 0)
continue;
1781 if (tj.
Pts[ineg].Chg == 0)
continue;
1782 float asym = (tj.
Pts[iplu].Chg - tj.
Pts[ineg].Chg) / (tj.
Pts[iplu].Chg + tj.
Pts[ineg].Chg);
1784 if (asym > 0.5) ++npos;
1785 if (asym < -0.5) ++nneg;
1787 mf::LogVerbatim(
"TC") <<
" ineg " << ineg <<
" iplu " << iplu <<
" asym " << asym
1788 <<
" nchk " << nchk;
1790 if (nchk < 3)
return;
1793 bool doTrim = (nneg > nchk) || (npos > nchk);
1794 if (!doTrim)
return;
1796 auto& prevTP = tj.
Pts[atPt - 1];
1797 if (
std::abs(prevTP.ChgPull) > 2) --atPt;
1798 for (
unsigned short ipt = atPt; ipt <= tj.
EndPt[1]; ++ipt)
1810 const float& MinWireSignalFraction)
1813 if (MinWireSignalFraction == 0)
return true;
1815 if (tp1.
Pos[0] < -0.4 || tp2.
Pos[0] < -0.4)
return false;
1816 int fromWire = std::nearbyint(tp1.
Pos[0]);
1817 int toWire = std::nearbyint(tp2.
Pos[0]);
1819 if (fromWire == toWire) {
1822 tp.
Pos[1] = 0.5 * (tp1.
Pos[1] + tp2.
Pos[1]);
1828 return SignalBetween(slc, tp, toWire, MinWireSignalFraction);
1846 if (tp.
Pos[0] < -0.4 || toPos0 < -0.4)
return 0;
1847 int fromWire = std::nearbyint(tp.
Pos[0]);
1848 int toWire = std::nearbyint(toPos0);
1850 if (fromWire == toWire)
return SignalAtTp(tp);
1852 int nWires =
abs(toWire - fromWire) + 1;
1857 if (toWire > fromWire && tp.
Dir[0] < 0) stepSize = -stepSize;
1858 if (toWire < fromWire && tp.
Dir[0] > 0) stepSize = -stepSize;
1861 for (
unsigned short cnt = 0; cnt < nWires; ++cnt) {
1864 tp.
Pos[0] += tp.
Dir[0] * stepSize;
1865 tp.
Pos[1] += tp.
Dir[1] * stepSize;
1867 float sigFrac = nsig / num;
1874 const std::vector<unsigned int>& iHitsInMultiplet,
1875 const std::vector<unsigned int>& jHitsInMultiplet)
1879 if (iHitsInMultiplet.empty() || jHitsInMultiplet.empty())
return false;
1883 if (cvI < 0)
return false;
1886 for (
auto& iht : iHitsInMultiplet) {
1888 float cv =
hit.PeakTime();
1889 float rms =
hit.RMS();
1890 float arg = cv - 3.1 * rms;
1891 if (arg < minI) minI = arg;
1892 arg = cv + 3.1 * rms;
1893 if (arg > maxI) maxI = arg;
1897 if (cvJ < 0)
return false;
1900 for (
auto& jht : jHitsInMultiplet) {
1902 float cv =
hit.PeakTime();
1903 float rms =
hit.RMS();
1904 float arg = cv - 3.1 * rms;
1905 if (arg < minJ) minJ = arg;
1906 arg = cv + 3.1 * rms;
1907 if (arg > maxJ) maxJ = arg;
1911 if (maxI > minJ)
return true;
1914 if (minI < maxJ)
return true;
1924 if (iht > slc.
slHits.size() - 1)
return false;
1925 if (jht > slc.
slHits.size() - 1)
return false;
1929 int iwire = ihit.WireID().Wire;
1930 int jwire = jhit.WireID().Wire;
1931 if (
std::abs(iwire - jwire) > 1)
return false;
1932 if (ihit.PeakTime() > jhit.PeakTime()) {
1933 float minISignal = ihit.PeakTime() - 3 * ihit.RMS();
1934 float maxJSignal = jhit.PeakTime() + 3 * ihit.RMS();
1935 if (maxJSignal > minISignal)
return true;
1938 float maxISignal = ihit.PeakTime() + 3 * ihit.RMS();
1939 float minJSignal = jhit.PeakTime() - 3 * ihit.RMS();
1940 if (minJSignal > maxISignal)
return true;
1966 if (tp.
Pos[0] < -0.4)
return false;
1968 unsigned short pln = planeID.
Plane;
1969 unsigned int wire = std::nearbyint(tp.
Pos[0]);
1970 if (wire >
evt.
goodWire[pln].size() - 1)
return false;
1974 if (slc.
wireHitRange[pln][wire].first == UINT_MAX)
return false;
1977 float tickRange = 0;
1981 if (tickRange > 40) tickRange = 40;
1983 float loTpTick = projTick - tickRange;
1984 float hiTpTick = projTick + tickRange;
1985 for (
unsigned int iht = slc.
wireHitRange[pln][wire].first;
1988 unsigned int ahi = slc.
slHits[iht].allHitsIndex;
1990 if (projTick <
hit.PeakTime()) {
1991 float loHitTick =
hit.PeakTime() - 3 *
hit.RMS();
1992 if (hiTpTick > loHitTick)
return true;
1995 float hiHitTick =
hit.PeakTime() + 3 *
hit.RMS();
1996 if (loTpTick < hiHitTick)
return true;
2017 if (tp.
Pos[0] < -0.4)
return false;
2019 unsigned short pln = planeID.
Plane;
2020 unsigned int wire = std::nearbyint(tp.
Pos[0]);
2021 if (wire >
evt.
goodWire[pln].size() - 1)
return false;
2027 float tickRange = 0;
2031 if (tickRange > 40) tickRange = 40;
2033 float loTpTick = projTick - tickRange;
2034 float hiTpTick = projTick + tickRange;
2044 const auto& wid =
hit.WireID();
2045 if (wid.Cryostat != planeID.
Cryostat)
continue;
2046 if (wid.TPC != planeID.
TPC)
continue;
2047 if (wid.Plane != planeID.
Plane)
continue;
2048 if (projTick <
hit.PeakTime()) {
2049 float loHitTick =
hit.PeakTime() - 3 *
hit.RMS();
2050 if (hiTpTick > loHitTick)
return true;
2053 float hiHitTick =
hit.PeakTime() + 3 *
hit.RMS();
2054 if (loTpTick < hiHitTick)
return true;
2076 unsigned int pln = plnID.
Plane;
2077 if (pln == 2)
return false;
2079 unsigned int cstat = plnID.
Cryostat;
2080 unsigned int tpc = plnID.
TPC;
2085 float atTick = 0.5 * (loTick + hiTick);
2089 if (
hit.Channel() != chan)
continue;
2090 if (atTick <
hit.PeakTime()) {
2091 float loHitTick =
hit.PeakTime() - 3 *
hit.RMS();
2092 if (hiTick > loHitTick)
return true;
2095 float hiHitTick =
hit.PeakTime() + 3 *
hit.RMS();
2096 if (loTick < hiHitTick)
return true;
2107 for (
size_t i = 0; i < tp.
Hits.size(); ++i) {
2108 if (!tp.
UseHit[i])
continue;
2118 unsigned short firstPt = tj.
EndPt[0];
2119 unsigned short lastPt = tj.
EndPt[1];
2127 bool includeDeadWires,
2128 unsigned short firstPt,
2129 unsigned short lastPt)
2131 unsigned short ntp = 0;
2132 for (
unsigned short ipt = firstPt; ipt <= lastPt; ++ipt)
2133 if (tj.
Pts[ipt].Chg > 0) ++ntp;
2150 if (inWirePos1 < -0.4 || inWirePos2 < -0.4)
return 0;
2151 unsigned int inWire1 = std::nearbyint(inWirePos1);
2152 unsigned int inWire2 = std::nearbyint(inWirePos2);
2154 unsigned short plane = planeID.
Plane;
2155 if (inWire1 > slc.
nWires[plane] || inWire2 > slc.
nWires[plane])
return 0;
2156 if (inWire1 > inWire2) {
2158 unsigned int tmp = inWire1;
2163 unsigned int wire, ndead = 0;
2164 for (wire = inWire1; wire < inWire2; ++wire)
2173 unsigned short pdg =
abs(PDGCode);
2174 if (pdg == 11)
return 0;
2175 if (pdg == 13)
return 1;
2176 if (pdg == 211)
return 2;
2177 if (pdg == 321)
return 3;
2178 if (pdg == 2212)
return 4;
2188 if (itj > slc.
tjs.size() - 1)
return;
2189 int killTjID = slc.
tjs[itj].ID;
2191 if (
hit.InTraj == killTjID)
hit.InTraj = 0;
2199 if (itj > slc.
tjs.size() - 1)
return;
2201 mf::LogWarning(
"TC")
2202 <<
"RestoreObsoleteTrajectory: Trying to restore not-obsolete trajectory "
2207 for (
auto& tp : slc.
tjs[itj].Pts) {
2208 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
2209 if (tp.UseHit[ii]) {
2211 if (slc.
slHits[iht].InTraj == 0) { slc.
slHits[iht].InTraj = slc.
tjs[itj].ID; }
2225 for (
auto& shortTj : slc.
tjs) {
2226 if (shortTj.AlgMod[
kKilled] || shortTj.AlgMod[
kHaloTj])
continue;
2227 if (shortTj.CTP != inCTP)
continue;
2228 unsigned short spts = shortTj.EndPt[1] - shortTj.EndPt[0];
2229 if (spts > 20)
continue;
2231 if (shortTj.PDGCode == 11)
continue;
2233 if (shortTj.SSID > 0)
continue;
2235 if (tjhits.empty())
continue;
2236 std::vector<int> tids;
2237 std::vector<unsigned short> tcnt;
2238 for (
auto iht : tjhits) {
2240 if (
hit.InTraj <= 0)
continue;
2241 if ((
unsigned int)
hit.InTraj > slc.
tjs.size())
continue;
2242 if (
hit.InTraj == shortTj.ID)
continue;
2243 unsigned short indx = 0;
2244 for (indx = 0; indx < tids.size(); ++indx)
2245 if (
hit.InTraj == tids[indx])
break;
2246 if (indx == tids.size()) {
2247 tids.push_back(
hit.InTraj);
2254 if (tids.empty())
continue;
2256 unsigned short maxcnt = 0;
2257 for (
unsigned short indx = 0; indx < tids.size(); ++indx) {
2258 if (tcnt[indx] > maxcnt) {
2259 auto& ltj = slc.
tjs[tids[indx] - 1];
2260 unsigned short lpts = ltj.EndPt[1] - ltj.EndPt[0];
2261 if (lpts < spts)
continue;
2262 maxcnt = tcnt[indx];
2265 float hitFrac = (float)maxcnt / (
float)tjhits.size();
2266 if (hitFrac < 0.1)
continue;
2281 if (itj > slc.
tjs.size() - 1)
return false;
2283 auto& tj = slc.
tjs[itj];
2286 unsigned short atPt = USHRT_MAX;
2287 for (
unsigned short ipt = tj.EndPt[0] + 1; ipt <= tj.EndPt[1]; ++ipt) {
2288 if (tj.Pts[ipt].Pos[1] > tj.Pts[ipt - 1].Pos[1]) {
2290 if (tj.Pts[ipt - 1].Pos[1] < atPos1 && tj.Pts[ipt].Pos[1] >= atPos1) {
2297 if (tj.Pts[ipt - 1].Pos[1] >= atPos1 && tj.Pts[ipt].Pos[1] < atPos1) {
2303 if (atPt == USHRT_MAX)
return false;
2304 unsigned short vx2Index = USHRT_MAX;
2307 newVx2.
CTP = tj.CTP;
2308 newVx2.
Pos[0] = 0.5 * (tj.Pts[atPt - 1].Pos[0] + tj.Pts[atPt].Pos[0]);
2309 newVx2.
Pos[1] = 0.5 * (tj.Pts[atPt - 1].Pos[1] + tj.Pts[atPt].Pos[1]);
2314 return SplitTraj(slc, itj, atPt, vx2Index, prt);
2326 if (itj > slc.
tjs.size() - 1)
return false;
2327 if (pos < slc.
tjs[itj].EndPt[0] + 1 || pos > slc.
tjs[itj].EndPt[1] - 1)
return false;
2328 if (ivx != USHRT_MAX && ivx > slc.
vtxs.size() - 1)
return false;
2333 bool splittingMuon = (tj.
PDGCode == 13);
2334 if (splittingMuon) tj.
PDGCode = 0;
2337 mf::LogVerbatim myprt(
"TC");
2338 myprt <<
"SplitTraj: Split T" << tj.
ID <<
" at point " <<
PrintPos(slc, tj.
Pts[pos]);
2339 if (ivx < slc.
vtxs.size()) myprt <<
" with Vtx 2V" << slc.
vtxs[ivx].ID;
2343 unsigned short ntp = 0;
2344 for (
unsigned short ipt = 0; ipt <= pos; ++ipt) {
2345 if (tj.
Pts[ipt].Chg > 0) ++ntp;
2349 if (prt) mf::LogVerbatim(
"TC") <<
" Split point to small at begin " << ntp <<
" pos " << pos;
2353 for (
unsigned short ipt = pos + 1; ipt <= tj.
EndPt[1]; ++ipt) {
2354 if (tj.
Pts[ipt].Chg > 0) ++ntp;
2359 mf::LogVerbatim(
"TC") <<
" Split point too small at end " << ntp <<
" pos " << pos
2360 <<
" EndPt " << tj.
EndPt[1];
2366 newTj.
ID = slc.
tjs.size() + 1;
2375 for (
unsigned short ipt = pos + 1; ipt <= tj.
EndPt[1]; ++ipt) {
2376 tj.
Pts[ipt].Chg = 0;
2377 for (
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
2378 if (!tj.
Pts[ipt].UseHit[ii])
continue;
2379 iht = tj.
Pts[ipt].Hits[ii];
2381 if (slc.
slHits[iht].InTraj != tj.
ID)
continue;
2383 tj.
Pts[ipt].UseHit[ii] =
false;
2395 unsigned short eraseSize = pos - 2;
2396 if (eraseSize > newTj.
Pts.size() - 1) {
2404 mf::LogVerbatim(
"TC") <<
" Splitting T" << tj.
ID <<
" new EndPts " << tj.
EndPt[0] <<
" to "
2409 newTj.
Pts.erase(newTj.
Pts.begin(), newTj.
Pts.begin() + eraseSize);
2411 for (
unsigned short ipt = 0; ipt < 3; ++ipt) {
2412 for (
unsigned short ii = 0; ii < newTj.
Pts[ipt].Hits.size(); ++ii)
2413 newTj.
Pts[ipt].UseHit[ii] =
false;
2414 newTj.
Pts[ipt].Chg = 0;
2420 if (ivx < slc.
vtxs.size()) newTj.
VtxID[0] = slc.
vtxs[ivx].ID;
2423 slc.
tjs.push_back(newTj);
2426 mf::LogVerbatim(
"TC") <<
" newTj T" << newTj.
ID <<
" EndPts " << newTj.
EndPt[0] <<
" to "
2438 unsigned short& closePt,
2442 float best = minSep * minSep;
2443 closePt = USHRT_MAX;
2446 for (ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
2447 dw = tj.
Pts[ipt].Pos[0] - tp.
Pos[0];
2448 dt = tj.
Pts[ipt].Pos[1] - tp.
Pos[1];
2449 dp2 = dw * dw + dt * dt;
2455 minSep = sqrt(best);
2463 unsigned short& ipt1,
2464 unsigned short& ipt2,
2467 return TrajTrajDOCA(slc, tj1, tj2, ipt1, ipt2, minSep,
false);
2475 unsigned short& ipt1,
2476 unsigned short& ipt2,
2478 bool considerDeadWires)
2483 for (
unsigned short iwt = 0; iwt < 2; ++iwt) {
2486 float wt0 = tj1.
Pts[tj1.
EndPt[0]].Pos[iwt];
2487 float wt1 = tj1.
Pts[tj1.
EndPt[1]].Pos[iwt];
2495 wt0 = tj2.
Pts[tj2.
EndPt[0]].Pos[iwt];
2496 wt1 = tj2.
Pts[tj2.
EndPt[1]].Pos[iwt];
2506 if (lowt2 > hiwt1 + minSep)
return false;
2508 if (lowt1 > hiwt2 + minSep)
return false;
2511 float best = minSep * minSep;
2515 bool isClose =
false;
2516 for (
unsigned short i1 = tj1.
EndPt[0]; i1 < tj1.
EndPt[1] + 1; ++i1) {
2517 for (
unsigned short i2 = tj2.
EndPt[0]; i2 < tj2.
EndPt[1] + 1; ++i2) {
2519 float dw = tj1.
Pts[i1].Pos[0] - tj2.
Pts[i2].Pos[0] - dwc;
2520 if (
std::abs(dw) > minSep)
continue;
2521 float dt = tj1.
Pts[i1].Pos[1] - tj2.
Pts[i2].Pos[1];
2522 if (
std::abs(dt) > minSep)
continue;
2523 float dp2 = dw * dw + dt * dt;
2532 minSep = sqrt(best);
2541 if (iht > slc.
slHits.size() - 1 || jht > slc.
slHits.size() - 1)
return 1E6;
2544 float dw = (float)ihit.WireID().Wire - (float)jhit.WireID().Wire;
2546 return dw * dw + dt * dt;
2553 unsigned short endPt = tj.
EndPt[0];
2554 auto& tp0 = tj.
Pts[endPt];
2555 endPt = tj.
EndPt[1];
2556 auto& tp1 = tj.
Pts[endPt];
2565 float dw = wire - tp.
Pos[0];
2566 float dt = time - tp.
Pos[1];
2567 return dw * dw + dt * dt;
2574 if (iht > slc.
slHits.size() - 1)
return 1E6;
2576 float wire =
hit.WireID().Wire;
2595 double t = (double)(wire - tp.
Pos[0]) * tp.
Dir[0] + (double)(time - tp.
Pos[1]) * tp.
Dir[1];
2596 double dw = tp.
Pos[0] + t * tp.
Dir[0] - wire;
2597 double dt = tp.
Pos[1] + t * tp.
Dir[1] - time;
2598 return (
float)(dw * dw + dt * dt);
2617 double arg1 = tp1.
Pos[0] * tp1.
Dir[1] - tp1.
Pos[1] * tp1.
Dir[0];
2618 double arg2 = tp2.
Pos[0] * tp1.
Dir[1] - tp2.
Pos[1] * tp1.
Dir[0];
2619 double arg3 = tp2.
Dir[0] * tp1.
Dir[1] - tp2.
Dir[1] * tp1.
Dir[0];
2620 if (arg3 == 0)
return;
2621 double s = (arg1 - arg2) / arg3;
2623 x = (float)(tp2.
Pos[0] + s * tp2.
Dir[0]);
2624 y = (float)(tp2.
Pos[1] + s * tp2.
Dir[1]);
2633 if (tjIDs.empty())
return 0;
2635 for (
auto tjid : tjIDs) {
2636 if (tjid < 1 || tjid > (
int)slc.
tjs.size())
continue;
2637 auto& tj = slc.
tjs[tjid - 1];
2638 float sep2 =
PosSep2(tj.Pts[tj.EndPt[0]].Pos, tj.Pts[tj.EndPt[1]].Pos);
2639 if (sep2 > maxLen) maxLen = sep2;
2641 return sqrt(maxLen);
2648 float len = 0, dx, dy;
2650 unsigned short prevPt = tj.
EndPt[0];
2651 for (ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1] + 1; ++ipt) {
2652 if (tj.
Pts[ipt].Chg == 0)
continue;
2653 dx = tj.
Pts[ipt].Pos[0] - tj.
Pts[prevPt].Pos[0];
2654 dy = tj.
Pts[ipt].Pos[1] - tj.
Pts[prevPt].Pos[1];
2655 len += sqrt(dx * dx + dy * dy);
2665 return sqrt(
PosSep2(pos1, pos2));
2673 float d0 = pos1[0] - pos2[0];
2674 float d1 = pos1[1] - pos2[1];
2675 return d0 * d0 + d1 * d1;
2683 float dx = tp1.
Pos[0] - tp2.
Pos[0];
2684 float dy = tp1.
Pos[1] - tp2.
Pos[1];
2685 return sqrt(dx * dx + dy * dy);
2696 float close2 = DOCA * DOCA;
2698 bool foundClose =
false;
2700 for (
unsigned short ipt = tj.
EndPt[0]; ipt < tj.
EndPt[1] + 1; ++ipt) {
2701 if (tj.
Pts[ipt].Chg == 0)
continue;
2702 float dx = tj.
Pts[ipt].Pos[0] -
x;
2704 float dy = tj.
Pts[ipt].Pos[1] -
y;
2706 float sep2 = dx * dx + dy * dy;
2707 if (sep2 < close2) {
2714 DOCA = sqrt(close2);
2724 float dw = tp2.
Pos[0] - tp1.
Pos[0];
2725 float dt = tp2.
Pos[1] - tp1.
Pos[1];
2726 return atan2(dw, dt);
2730 std::vector<unsigned int>
2734 std::vector<unsigned int> hitVec;
2735 if (pfp.
TP3Ds.empty())
return hitVec;
2737 for (
auto& tp3d : pfp.
TP3Ds) {
2738 if (tp3d.Flags[
kTP3DBad])
continue;
2739 if (tp3d.TjID <= 0)
continue;
2740 auto& tp = slc.
tjs[tp3d.TjID - 1].Pts[tp3d.TPIndex];
2741 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
2742 unsigned int iht = tp.Hits[ii];
2743 bool useit = (hitRequest ==
kAllHits);
2744 if (tp.UseHit[ii] && hitRequest ==
kUsedHits) useit =
true;
2745 if (!tp.UseHit[ii] && hitRequest ==
kUnusedHits) useit =
true;
2746 if (useit) hitVec.push_back(iht);
2753 std::vector<unsigned int>
2757 std::vector<unsigned int> hitVec;
2761 for (
auto& tp : tj.
Pts)
2762 hitVec.insert(hitVec.end(), tp.Hits.begin(), tp.Hits.end());
2767 hitVec.reserve(tj.
Pts.size());
2768 for (
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
2769 for (
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
2770 unsigned int iht = tj.
Pts[ipt].Hits[ii];
2771 bool useit = (hitRequest ==
kAllHits);
2772 if (tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUsedHits) useit =
true;
2773 if (!tj.
Pts[ipt].UseHit[ii] && hitRequest ==
kUnusedHits) useit =
true;
2774 if (useit) hitVec.push_back(iht);
2789 if (tj.
Pts.size() > 10)
return;
2790 if (tj.
PDGCode == 111)
return;
2792 unsigned short nhm = 0;
2793 unsigned short npwc = 0;
2794 for (
auto& tp : tj.
Pts) {
2795 if (tp.Chg == 0)
continue;
2797 unsigned short nused = 0;
2798 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
2799 if (tp.UseHit[ii]) ++nused;
2801 if (nused > 3) ++nhm;
2806 mf::LogVerbatim(
"TC") <<
"TGT: T" << tj.
ID <<
" npwc " << npwc <<
" nhm " << nhm <<
" junk? "
2816 for (
unsigned short ii = 0; ii < tjHits.size() - 1; ++ii) {
2817 for (
unsigned short jj = ii + 1; jj < tjHits.size(); ++jj) {
2818 if (tjHits[ii] == tjHits[jj]) {
2820 mf::LogVerbatim(
"TC") <<
"HDH: Hit " <<
PrintHit(slc.
slHits[ii]) <<
" is a duplicate "
2834 if (tp.
Dir[0] == 0)
return;
2835 float dw = wire - tp.
Pos[0];
2838 tp.
Pos[1] += dw * tp.
Dir[1] / tp.
Dir[0];
2842 std::vector<unsigned int>
2844 std::array<int, 2>
const& wireWindow,
2846 const unsigned short plane,
2865 std::vector<unsigned int> closeHits;
2866 if (plane > slc.
firstWire.size() - 1)
return closeHits;
2868 int loWire = wireWindow[0];
2870 int hiWire = wireWindow[1];
2875 for (
int wire = loWire; wire <= hiWire; ++wire) {
2878 if (slc.
wireHitRange[plane][wire].first == UINT_MAX)
continue;
2879 unsigned int firstHit = slc.
wireHitRange[plane][wire].first;
2880 unsigned int lastHit = slc.
wireHitRange[plane][wire].second;
2881 for (
unsigned int iht = firstHit; iht <= lastHit; ++iht) {
2884 if (
hit.PeakTime() < minTick)
continue;
2885 if (
hit.PeakTime() > maxTick)
break;
2889 if (
hit.StartTick() > hiLo) hiLo =
hit.StartTick();
2891 if (
hit.EndTick() < loHi) loHi =
hit.EndTick();
2892 if (loHi < hiLo)
continue;
2893 if (hiLo > loHi)
break;
2896 bool takeit = (hitRequest ==
kAllHits);
2897 if (hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) takeit =
true;
2899 if (takeit) closeHits.push_back(iht);
2917 if (tp.
Pos[0] < -0.4)
return false;
2919 unsigned int wire = std::nearbyint(tp.
Pos[0]);
2920 if (wire < slc.
firstWire[plane])
return false;
2921 if (wire > slc.
lastWire[plane] - 1)
return false;
2930 if (slc.
wireHitRange[plane][wire].first == UINT_MAX)
return false;
2932 unsigned int firstHit = slc.
wireHitRange[plane][wire].first;
2933 unsigned int lastHit = slc.
wireHitRange[plane][wire].second;
2936 for (
unsigned int iht = firstHit; iht <= lastHit; ++iht) {
2937 if ((
unsigned int)slc.
slHits[iht].InTraj > slc.
tjs.size())
continue;
2938 bool useit = (hitRequest ==
kAllHits);
2939 if (hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
2941 if (!useit)
continue;
2945 if (delta < maxDelta) tp.
Hits.push_back(iht);
2947 if (tp.
Hits.size() > 16) { tp.
Hits.resize(16); }
2950 return (!tp.
Hits.empty());
2963 if (end > 1)
return USHRT_MAX;
2965 if (end == 1) dir = -1;
2966 for (
short ii = 0; ii < (short)tj.
Pts.size(); ++ii) {
2967 short ipt = tj.
EndPt[
end] + dir * ii;
2968 if (ipt < 0 || ipt >= (
short)tj.
Pts.size())
return USHRT_MAX;
2969 auto& tp = tj.
Pts[ipt];
2980 const float& maxDelta)
2998 std::vector<int> tmp;
2999 if (fromTp.
Pos[0] < -0.4 || toTp.
Pos[0] < -0.4)
return tmp;
3003 unsigned int firstWire, lastWire;
3004 if (toTp.
Pos[0] > fromTp.
Pos[0]) {
3006 firstWire = std::nearbyint(fromTp.
Pos[0]);
3007 lastWire = std::nearbyint(toTp.
Pos[0]);
3009 else if (toTp.
Pos[0] < fromTp.
Pos[0]) {
3011 firstWire = std::nearbyint(toTp.
Pos[0]);
3012 lastWire = std::nearbyint(fromTp.
Pos[0]);
3016 float tmp = fromTp.
Pos[0] - maxDelta;
3017 if (tmp < 0) tmp = 0;
3018 firstWire = std::nearbyint(tmp);
3019 tmp = fromTp.
Pos[0] + maxDelta;
3020 lastWire = std::nearbyint(tmp);
3026 if (firstWire > slc.
lastWire[plane] - 1)
return tmp;
3027 if (lastWire < slc.
firstWire[plane])
return tmp;
3028 if (lastWire > slc.
lastWire[plane] - 1) lastWire = slc.
lastWire[plane] - 1;
3030 for (
unsigned int wire = firstWire; wire <= lastWire; ++wire) {
3031 if (slc.
wireHitRange[plane][wire].first == UINT_MAX)
continue;
3036 unsigned int firstHit = slc.
wireHitRange[plane][wire].first;
3037 unsigned int lastHit = slc.
wireHitRange[plane][wire].second;
3038 for (
unsigned int iht = firstHit; iht <= lastHit; ++iht) {
3039 if (slc.
slHits[iht].InTraj <= 0)
continue;
3040 if ((
unsigned int)slc.
slHits[iht].InTraj > slc.
tjs.size())
continue;
3042 if (
hit.PeakTime() < minTick)
continue;
3044 if (
hit.PeakTime() > maxTick)
break;
3045 if (std::find(tmp.begin(), tmp.end(), slc.
slHits[iht].InTraj) != tmp.end())
continue;
3046 tmp.push_back(slc.
slHits[iht].InTraj);
3058 unsigned short end1,
3060 unsigned short end2,
3061 unsigned short nPtsFit,
3068 if (tj1.
CTP != tj2.
CTP)
return -1;
3069 if (end1 > 1 || end2 > 1)
return -1;
3077 if (end1 == 1) dir = -1;
3078 unsigned short cnt = 0;
3080 for (
short ii = 0; ii < (short)tj1.
Pts.size(); ++ii) {
3081 short ipt = tj1.
EndPt[end1] + dir * ii;
3083 if (ipt >= (
short)tj1.
Pts.size())
break;
3084 auto& tp = tj1.
Pts[ipt];
3085 if (tp.Chg <= 0)
continue;
3086 tj.
Pts.push_back(tp);
3088 if (cnt == nPtsFit + 1)
break;
3090 if (cnt < nPtsFit)
return -1;
3093 if (end2 == 1) dir = -1;
3095 for (
short ii = 0; ii < (short)tj2.
Pts.size(); ++ii) {
3096 short ipt = tj2.
EndPt[end2] + dir * ii;
3098 if (ipt >= (
short)tj2.
Pts.size())
break;
3099 auto& tp = tj2.
Pts[ipt];
3100 if (tp.Chg <= 0)
continue;
3101 tj.
Pts.push_back(tp);
3103 if (cnt == nPtsFit + 1)
break;
3114 unsigned short kinkPt,
3115 unsigned short nPtsFit,
3124 if (kinkPt < tj.
EndPt[0] + 2)
return -1;
3125 if (kinkPt > tj.
EndPt[1] - 2)
return -1;
3128 if (nPtsFit < 3)
return -1;
3131 if (npwc < 2 * nPtsFit + 1)
return -1;
3136 double chgRMS = 0.07;
3140 double tFactor = 1 + 0.3 / double(nPtsFit - 2);
3146 FitTraj(slc, tj, kinkPt, nPtsFit, fitDir, tpPos);
3147 if (tpPos.
FitChi > 900)
return -1;
3151 FitTraj(slc, tj, kinkPt, nPtsFit, fitDir, tpNeg);
3152 if (tpNeg.
FitChi > 900)
return -1;
3153 double angErr = tpNeg.
AngErr;
3157 double dangSig = dang / angErr;
3164 unsigned short cntNeg = 0;
3165 for (
unsigned short ipt = kinkPt - 1; ipt >= tj.
EndPt[0]; --ipt) {
3166 auto& tp = tj.
Pts[ipt];
3167 if (tp.Chg <= 0)
continue;
3170 if (cntNeg == nPtsFit)
break;
3171 if (ipt == 0)
break;
3173 if (cntNeg != nPtsFit) {
3174 if (prt) mf::LogVerbatim(
"TC") <<
" KL: Bad cntNeg " << cntNeg <<
" != " << nPtsFit;
3179 unsigned short cntPos = 0;
3180 for (
unsigned short ipt = kinkPt + 1; ipt <= tj.
EndPt[1]; ++ipt) {
3181 auto& tp = tj.
Pts[ipt];
3182 if (tp.Chg <= 0)
continue;
3185 if (cntPos == nPtsFit)
break;
3187 if (cntPos != nPtsFit) {
3188 if (prt) mf::LogVerbatim(
"TC") <<
" KL: Bad cntPos " << cntPos <<
" != " << nPtsFit;
3191 chgNeg /= (float)nPtsFit;
3192 chgPos /= (float)nPtsFit;
3194 chgAsym =
std::abs(chgPos - chgNeg) / (chgPos + chgNeg);
3196 chgSig = chgAsym / chgRMS;
3198 double kinkSig = sqrt(dangSig * dangSig + chgSig * chgSig);
3201 mf::LogVerbatim myprt(
"TC");
3202 myprt <<
"KL: T" << tj.
ID <<
" kinkPt " <<
PrintPos(slc, tj.
Pts[kinkPt]);
3203 myprt <<
" nPtsFit " << nPtsFit;
3204 myprt <<
" dang " << std::fixed << std::setprecision(3) << dang;
3205 myprt << std::fixed << std::setprecision(3) <<
" angErr " << angErr;
3206 myprt << std::setprecision(2) <<
" sig " << dangSig;
3207 myprt <<
" chgAsym " << chgAsym;
3208 myprt <<
" chgSig " << chgSig;
3209 myprt <<
" kinkSig " << kinkSig;
3211 return (
float)kinkSig;
3222 unsigned short midPt = 0.5 * (tj.
EndPt[0] + tj.
EndPt[1]);
3223 double rms0 = 0, rms1 = 0;
3227 float asym =
std::abs(rms0 - rms1) / (rms0 + rms1);
3228 float chgFact = (tj.
ChgRMS - 0.1) * 5;
3229 float elh = 5 * asym * chgFact;
3230 if (elh > 1) elh = 1;
3240 if (tjIDs.empty())
return 0;
3241 std::array<int, 2> wireWindow;
3244 constexpr
float NNDelta = 5;
3245 wireWindow[0] = pos[0] - NNDelta;
3246 wireWindow[1] = pos[0] + NNDelta;
3247 timeWindow[0] = pos[1] - NNDelta;
3248 timeWindow[1] = pos[1] + NNDelta;
3250 for (
auto& tjID : tjIDs)
3251 if (tjID <= 0 || tjID > (
int)slc.
tjs.size())
return 0;
3256 std::vector<unsigned int> closeHits =
3258 if (closeHits.empty())
return 0;
3263 for (
auto& iht : closeHits) {
3265 chg +=
hit.Integral();
3266 if (slc.
slHits[iht].InTraj == 0)
continue;
3267 if (std::find(tjIDs.begin(), tjIDs.end(), slc.
slHits[iht].InTraj) != tjIDs.end())
3268 tchg +=
hit.Integral();
3270 if (chg == 0)
return 0;
3278 float delta,
md = 0;
3281 for (
auto& tp : tj.
Pts) {
3282 for (ii = 0; ii < tp.Hits.size(); ++ii) {
3283 if (!tp.UseHit[ii])
continue;
3286 if (delta > md) md = delta;
3297 if (tj.
Pts.empty())
return;
3303 std::reverse(tj.
Pts.begin(), tj.
Pts.end());
3308 for (
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
3309 if (tj.
Pts[ipt].Dir[0] != 0) tj.
Pts[ipt].Dir[0] = -tj.
Pts[ipt].Dir[0];
3310 if (tj.
Pts[ipt].Dir[1] != 0) tj.
Pts[ipt].Dir[1] = -tj.
Pts[ipt].Dir[1];
3311 if (tj.
Pts[ipt].Ang > 0) { tj.
Pts[ipt].Ang -= M_PI; }
3313 tj.
Pts[ipt].Ang += M_PI;
3331 unsigned short nvx = Envelope.size();
3332 double angleSum = 0;
3333 for (
unsigned short ii = 0; ii < Envelope.size(); ++ii) {
3334 p1[0] = Envelope[ii][0] - Point[0];
3335 p1[1] = Envelope[ii][1] - Point[1];
3336 p2[0] = Envelope[(ii + 1) % nvx][0] - Point[0];
3337 p2[1] = Envelope[(ii + 1) % nvx][1] - Point[1];
3340 if (
abs(angleSum) < M_PI)
return false;
3349 double den = v1[0] * v1[0] + v1[1] * v1[1];
3350 if (den == 0)
return false;
3365 if (pos1[0] == pos2[0] && pos1[1] == pos2[1])
return;
3366 pos1[0] = pos2[0] - pos1[0];
3367 pos1[1] = pos2[1] - pos1[1];
3368 double sep = sqrt(pos1[0] * pos1[0] + pos1[1] * pos1[1]);
3369 if (sep < 1
E-6)
return;
3371 ptDir[0] = pos1[0] / sep;
3372 ptDir[1] = pos1[1] / sep;
3374 double costh =
DotProd(dir1, ptDir);
3375 if (costh > 1.0 || costh < -1.0)
return;
3376 alongTrans[0] = costh * sep;
3377 double sinth = sqrt(1 - costh * costh);
3378 alongTrans[1] = sinth * sep;
3386 double ang1 = atan2(p1[1], p1[0]);
3387 double ang2 = atan2(p2[1], p2[0]);
3395 constexpr
double twopi = 2 * M_PI;
3396 double dang = Ang1 - Ang2;
3399 while (dang < -M_PI)
3408 return std::abs(std::remainder(Ang1 - Ang2, M_PI));
3422 if (tj.
Pts.size() == 0)
return;
3425 for (
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt) {
3426 if (tj.
Pts[ipt].Chg != 0) {
3431 for (
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
3432 unsigned short ipt = tj.
Pts.size() - 1 - ii;
3433 if (tj.
Pts[ipt].Chg != 0) {
3446 unsigned short nUsed = 0;
3447 unsigned short nTotHits = 0;
3448 for (
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
3450 nTotHits += tp.
Hits.size();
3451 for (
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
3452 if (tp.
UseHit[ii]) ++nUsed;
3455 if (nTotHits == 0)
return false;
3456 float fracUsed = (float)nUsed / (
float)nTotHits;
3458 mf::LogVerbatim(
"TC") <<
"TrajIsClean: nTotHits " << nTotHits <<
" nUsed " << nUsed
3459 <<
" fracUsed " << fracUsed;
3461 if (fracUsed > 0.9)
return true;
3471 if (tjIDs.empty())
return 0;
3474 for (
auto tjid : tjIDs) {
3475 auto& tj = slc.
tjs[tjid - 1];
3476 float npts = tj.EndPt[1] - tj.EndPt[0] + 1;
3477 summ += npts * tj.MCSMom;
3480 return (
short)(summ / suml);
3496 if (firstPt == lastPt)
return 0;
3497 if (firstPt > lastPt) std::swap(firstPt, lastPt);
3501 if (firstPt >= lastPt)
return 0;
3503 if (firstPt < tj.
EndPt[0])
return 0;
3504 if (lastPt > tj.
EndPt[1])
return 0;
3511 if (tjLen < 1)
return 0;
3513 double thetaRMS =
MCSThetaRMS(slc, tj, firstPt, lastPt);
3514 if (thetaRMS < 0.001)
return 999;
3515 double mom = 13.8 * sqrt(tjLen / 14) / thetaRMS;
3516 if (mom > 999) mom = 999;
3525 if (thePt > tj.
EndPt[1])
return thePt;
3526 if (tj.
Pts[thePt].Chg > 0)
return thePt;
3528 short endPt0 = tj.
EndPt[0];
3529 short endPt1 = tj.
EndPt[1];
3530 for (
short off = 1; off < 10; ++off) {
3531 short ipt = thePt + off;
3532 if (ipt <= endPt1 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
3534 if (ipt >= endPt0 && tj.
Pts[ipt].Chg > 0)
return (
unsigned short)ipt;
3548 if (tps < 1)
return 1;
3558 unsigned short firstPt,
3559 unsigned short lastPt)
3564 if (firstPt < tj.
EndPt[0])
return 1;
3565 if (lastPt > tj.
EndPt[1])
return 1;
3569 if (firstPt >= lastPt)
return 1;
3573 TjDeltaRMS(slc, tj, firstPt, lastPt, sigmaS, cnt);
3574 if (sigmaS < 0)
return 1;
3576 if (tjLen < 1)
return 1;
3578 return (6.8 * sigmaS / tjLen);
3586 unsigned short firstPt,
3587 unsigned short lastPt,
3589 unsigned short& cnt)
3594 if (firstPt < tj.
EndPt[0])
return;
3595 if (lastPt > tj.
EndPt[1])
return;
3599 if (firstPt >= lastPt)
return;
3612 for (
unsigned short ipt = firstPt + 1; ipt < lastPt; ++ipt) {
3613 if (tj.
Pts[ipt].Chg == 0)
continue;
3615 if (tj.
Pts[ipt].HitPosErr2 > 4)
continue;
3619 if (cnt < 2)
return;
3620 rms = sqrt(dsum / (
double)cnt);
3632 std::array<int, 2> wireWindow;
3638 for (
auto& mutj : slc.
tjs) {
3639 if (mutj.AlgMod[
kKilled])
continue;
3640 if (mutj.CTP != inCTP)
continue;
3641 if (mutj.PDGCode != 13)
continue;
3642 unsigned short nnear = 0;
3643 for (
unsigned short ipt = mutj.EndPt[0]; ipt <= mutj.EndPt[1]; ++ipt) {
3644 auto& tp = mutj.Pts[ipt];
3645 wireWindow[0] = tp.Pos[0];
3646 wireWindow[1] = tp.Pos[0];
3647 timeWindow[0] = tp.Pos[1] - delta;
3648 timeWindow[1] = tp.Pos[1] + delta;
3653 if (closeHits.empty())
continue;
3654 for (
auto iht : closeHits) {
3655 auto inTraj = slc.
slHits[iht].InTraj;
3656 if (inTraj <= 0)
continue;
3657 if (inTraj == mutj.ID)
continue;
3658 auto& dtj = slc.
tjs[inTraj - 1];
3659 if (dtj.PDGCode == 13)
continue;
3660 for (
unsigned short jpt = dtj.EndPt[0]; jpt <= dtj.EndPt[1]; ++jpt) {
3661 auto& dtp = dtj.Pts[jpt];
3662 if (std::find(dtp.Hits.begin(), dtp.Hits.end(), iht) == dtp.Hits.end())
continue;
3682 for (
auto& tp : tj.
Pts) {
3683 if (tp.Chg <= 0)
continue;
3685 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
3686 if (tp.UseHit[ii])
continue;
3687 unsigned int iht = tp.Hits[ii];
3713 for (
unsigned short ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1]; ++ipt) {
3714 auto& tp = tj.
Pts[ipt];
3715 if (tp.Chg > bigChg) bigChg = tp.Chg;
3722 for (
unsigned short ipt = tj.
EndPt[0] + 1; ipt < tj.
EndPt[1]; ++ipt) {
3723 auto& tp = tj.
Pts[ipt];
3724 if (tp.Chg <= 0)
continue;
3726 if (tp.Chg == bigChg)
continue;
3731 bsum2 += tp.Chg * tp.Chg;
3732 if (tp.Chg > bigChg) bigChg = tp.Chg;
3738 for (
unsigned short ii = 0; ii < tj.
Pts[ipt].Hits.size(); ++ii) {
3739 if (!tp.UseHit[ii])
continue;
3740 unsigned int iht = tp.Hits[ii];
3744 vsum2 += tpchg * tpchg;
3747 if (bcnt == 0)
return;
3755 if (arg > 0) tj.
ChgRMS = sqrt(arg / (bcnt - 1));
3757 for (
auto& tp : tj.
Pts)
3760 mf::LogVerbatim(
"TC") << inFcnLabel <<
".UpdateTjChgProperties: backup sum Set tj.AveChg "
3765 double nWires = tj.
EndPt[1] - tj.
EndPt[0] + 1;
3766 if (nWires < 2)
return;
3771 for (
unsigned short end = 0;
end < 2; ++
end) {
3775 int dw =
std::abs(tp.Pos[0] - vx2.Pos[0]);
3787 if (arg > 0) rms = sqrt(arg / (vcnt - 1));
3790 if (rms < 0.1) rms = 0.1;
3794 double defFrac = 1 / vcnt;
3795 rms = defFrac * 0.5 + (1 - defFrac) * rms;
3799 mf::LogVerbatim(
"TC") << inFcnLabel <<
".UpdateTjChgProperties: Set tj.AveChg "
3806 for (
unsigned short ipt = tj.
EndPt[0]; ipt <= tj.
EndPt[1]; ++ipt) {
3807 auto& tp = tj.
Pts[ipt];
3808 if (tp.Chg <= 0)
continue;
3815 for (
auto& tp : tj.
Pts)
3821 for (
auto& tp : tj.
Pts)
3825 unsigned short minPt = tj.
EndPt[0] + nptsave;
3827 for (
unsigned short ii = 0; ii < tj.
Pts.size(); ++ii) {
3828 unsigned short ipt = tj.
EndPt[1] - ii;
3829 if (ipt < minPt)
break;
3832 for (
unsigned short iii = 0; iii < nptsave; ++iii) {
3833 unsigned short iipt = ipt - iii;
3835 if (iipt == tj.
EndPt[0])
break;
3836 auto& tp = tj.
Pts[iipt];
3837 if (tp.Chg <= 0)
continue;
3842 tj.
Pts[ipt].AveChg = sum / cnt;
3843 lastAve = tj.
Pts[ipt].AveChg;
3847 for (
unsigned short ii = tj.
EndPt[0]; ii <= tj.
EndPt[1]; ++ii) {
3848 unsigned short ipt = tj.
EndPt[1] - ii;
3849 auto& tp = tj.
Pts[ipt];
3850 if (tp.AveChg == 0) { tp.AveChg = lastAve; }
3852 lastAve = tp.AveChg;
3870 for (
auto& tj : slc.
tjs) {
3871 if (tj.AlgMod[
kKilled])
continue;
3872 for (
auto& tp : tj.Pts)
3876 for (
auto& vx : slc.
vtxs) {
3877 if (vx.ID <= 0)
continue;
3889 if (vx2.
ID == 0)
return;
3892 if (prt) mf::LogVerbatim(
"TC") <<
"UpdateVxEnvironment check Tjs attached to vx2 " << vx2.
ID;
3894 std::vector<int> tjlist;
3895 std::vector<unsigned short> tjends;
3896 if (vx2.
Pos[0] < -0.4)
return;
3897 unsigned int vxWire = std::nearbyint(vx2.
Pos[0]);
3898 unsigned int loWire = vxWire;
3899 unsigned int hiWire = vxWire;
3900 for (
auto& tj : slc.
tjs) {
3902 if (tj.CTP != vx2.
CTP)
continue;
3904 if (tj.AlgMod[
kPhoton])
continue;
3905 for (
unsigned short end = 0;
end < 2; ++
end) {
3906 if (tj.VtxID[
end] != vx2.
ID)
continue;
3907 tjlist.push_back(tj.ID);
3908 tjends.push_back(
end);
3909 if (tj.Pts[tj.EndPt[
end]].Pos[0] < -0.4)
return;
3910 unsigned int endWire = std::nearbyint(tj.Pts[tj.EndPt[
end]].Pos[0]);
3911 if (endWire < loWire) loWire = endWire;
3912 if (endWire > hiWire) hiWire = endWire;
3915 if (tjlist.size() < 2)
return;
3916 if (hiWire < loWire + 1)
return;
3918 mf::LogVerbatim(
"TC") <<
" check Tjs on wires in the range " << loWire <<
" to " << hiWire;
3922 std::vector<std::vector<TrajPoint>> wire_tjpt;
3924 std::vector<int> tjids;
3926 unsigned short nwires = hiWire - loWire + 1;
3927 for (
unsigned short itj = 0; itj < tjlist.size(); ++itj) {
3928 auto& tj = slc.
tjs[tjlist[itj] - 1];
3929 unsigned short end = tjends[itj];
3930 std::vector<TrajPoint> tjpt(nwires);
3932 for (
unsigned short ii = 0; ii < tj.Pts.size(); ++ii) {
3934 if (end == 0) { ipt = tj.EndPt[0] + ii; }
3936 ipt = tj.EndPt[1] - ii;
3938 if (ipt > tj.Pts.size() - 1)
break;
3940 auto tp = tj.Pts[ipt];
3941 if (tp.Chg <= 0)
continue;
3944 if (tp.Pos[0] < -0.4)
continue;
3945 unsigned int wire = std::nearbyint(tp.Pos[0]);
3946 unsigned short indx = wire - loWire;
3947 if (indx > nwires - 1)
break;
3957 if (ltp.
Dir[0] == 0)
continue;
3958 if (ltp.
Pos[0] < -0.4)
continue;
3959 unsigned int wire = std::nearbyint(ltp.
Pos[0]);
3961 unsigned short indx = wire - loWire;
3963 if (tjpt[indx].Chg == 0) tjpt[indx] = ltp;
3965 for (
unsigned short ii = 0; ii < nwires; ++ii) {
3967 for (
unsigned short iwt = 0; iwt < 2; ++iwt)
3968 ltp.
Pos[iwt] += ltp.
Dir[iwt] * stepSize;
3969 if (ltp.
Pos[0] < -0.4)
break;
3970 wire = std::nearbyint(ltp.
Pos[0]);
3971 if (wire < loWire || wire > hiWire)
break;
3972 indx = wire - loWire;
3973 if (tjpt[indx].Chg > 0)
continue;
3977 mf::LogVerbatim myprt(
"TC");
3978 myprt <<
" T" << tj.ID;
3979 for (
auto& tp : tjpt)
3980 myprt <<
" " <<
PrintPos(slc, tp.Pos) <<
"_" << tp.Step <<
"_" << (int)tp.Chg;
3982 wire_tjpt.push_back(tjpt);
3983 tjids.push_back(tj.ID);
3987 for (
unsigned short indx = 0; indx < nwires; ++indx) {
3989 unsigned short npts = 0;
3991 unsigned short npwc = 0;
3992 for (
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
3993 if (wire_tjpt[itj][indx].Pos[0] == 0)
continue;
3996 if (wire_tjpt[itj][indx].Chg > 0) ++npwc;
3999 if (npts == 0)
continue;
4001 if (npwc == npts)
continue;
4003 for (
unsigned short itj = 0; itj < wire_tjpt.size(); ++itj) {
4004 if (wire_tjpt[itj][indx].Pos[0] == 0)
continue;
4005 if (wire_tjpt[itj][indx].Chg == 0)
continue;
4006 auto& tj = slc.
tjs[tjids[itj] - 1];
4007 unsigned short ipt = wire_tjpt[itj][indx].Step;
4009 tj.NeedsUpdate =
true;
4010 if (prt) mf::LogVerbatim(
"TC") <<
" Set kEnvOverlap bit on T" << tj.ID <<
" ipt " << ipt;
4016 for (
auto tjid : tjids) {
4017 auto& tj = slc.
tjs[tjid - 1];
4018 if (!tj.NeedsUpdate)
continue;
4019 if (tj.CTP != vx2.
CTP)
continue;
4067 if (dir[0] == 0 && dir[1] == 0 && dir[2] == 0)
return tp;
4071 Point3_t pos3 = {{100 * dir[0], 100 * dir[1], 100 * dir[2]}};
4073 std::array<double, 2> ori2;
4074 std::array<double, 2> pos2;
4075 std::array<double, 2> dir2;
4083 dir2[0] = pos2[0] - ori2[0];
4084 dir2[1] = pos2[1] - ori2[1];
4086 double norm = sqrt(dir2[0] * dir2[0] + dir2[1] * dir2[1]);
4089 tp.
Ang = atan2(dir2[1], dir2[0]);
4090 tp.
Delta = norm / 100;
4098 norm = sqrt(cs * cs + sn * sn);
4103 tp.
DeltaRMS = 100 / (pos2[0] - ori2[0]);
4112 if (fromHit > slc.
slHits.size() - 1)
return false;
4113 if (toHit > slc.
slHits.size() - 1)
return false;
4118 (
float)fhit.WireID().Wire,
4120 (float)thit.WireID().Wire,
4138 tp.
Pos[0] = fromWire;
4140 tp.
Dir[0] = toWire - fromWire;
4143 if (norm == 0)
return false;
4154 tpOut.
Pos = fromPos;
4156 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
4171 tpOut.
Ang = atan2(tpOut.
Dir[1], tpOut.
Dir[0]);
4180 if (tj.
ID == 0)
return 0;
4191 for (
unsigned short xyz = 0; xyz < 2; ++xyz)
4192 dir[xyz] = p2[xyz] - p1[xyz];
4193 if (dir[0] == 0 && dir[1] == 0)
return dir;
4194 double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
4214 if (tp.
Hits.empty())
return 0;
4215 float minVal = 9999;
4217 for (
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
4218 bool useit = (hitRequest ==
kAllHits);
4221 if (!useit)
continue;
4222 unsigned int iht = tp.
Hits[ii];
4224 float cv =
hit.PeakTime();
4225 float rms =
hit.RMS();
4226 float arg = cv - rms;
4227 if (arg < minVal) minVal = arg;
4229 if (arg > maxVal) maxVal = arg;
4231 if (maxVal == 0)
return 0;
4232 return (maxVal - minVal) / 2;
4238 const std::vector<unsigned int>& hitsInMultiplet,
4247 const std::vector<unsigned int>& hitsInMultiplet,
4250 if (hitsInMultiplet.empty())
return 0;
4252 if (hitsInMultiplet.size() == 1) {
4257 float minVal = 9999;
4259 for (
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
4260 unsigned int iht = hitsInMultiplet[ii];
4261 bool useit = (hitRequest ==
kAllHits);
4262 if (hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
4264 if (!useit)
continue;
4266 float cv =
hit.PeakTime();
4267 float rms =
hit.RMS();
4268 float arg = cv - rms;
4269 if (arg < minVal) minVal = arg;
4271 if (arg > maxVal) maxVal = arg;
4273 if (maxVal == 0)
return 0;
4274 return (maxVal - minVal) / 2;
4280 const std::vector<unsigned int>& hitsInMultiplet,
4290 const std::vector<unsigned int>& hitsInMultiplet,
4297 for (
unsigned short ii = 0; ii < hitsInMultiplet.size(); ++ii) {
4298 unsigned int iht = hitsInMultiplet[ii];
4299 bool useit = (hitRequest ==
kAllHits);
4300 if (hitRequest ==
kUsedHits && slc.
slHits[iht].InTraj > 0) useit =
true;
4302 if (!useit)
continue;
4304 float chg =
hit.Integral();
4305 pos += chg *
hit.PeakTime();
4308 if (sum <= 0)
return -1;
4317 if (tj.
Pts.empty())
return 0;
4318 unsigned short nhits = 0;
4319 for (
auto& tp : tj.
Pts) {
4320 for (
unsigned short ii = 0; ii < tp.Hits.size(); ++ii)
4321 if (tp.UseHit[ii]) ++nhits;
4331 if (tp.
Hits.empty())
return 0;
4335 unsigned short nhits = 0;
4336 for (
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
4338 if (tp.
UseHit[ii]) ++nhits;
4342 if (!tp.
UseHit[ii]) ++nhits;
4352 if (itj > slc.
tjs.size() - 1)
return;
4387 if (npwc > 500) isAMuon =
true;
4408 std::vector<float> cnt(nplanes, 0);
4409 for (
unsigned short iht = 0; iht < (*
evt.
allHits).
size(); ++iht) {
4411 unsigned short plane =
hit.WireID().Plane;
4412 if (plane > nplanes - 1)
return false;
4413 if (cnt[plane] > 200)
continue;
4415 if (
hit.Multiplicity() != 1)
continue;
4417 if (
hit.GoodnessOfFit() < 0 ||
hit.GoodnessOfFit() > 500)
continue;
4419 if (
hit.PeakAmplitude() < 1)
continue;
4423 bool allDone =
true;
4424 for (
unsigned short plane = 0; plane < nplanes; ++plane)
4425 if (cnt[plane] < 200) allDone =
false;
4431 for (
unsigned short plane = 0; plane < nplanes; ++plane) {
4432 if (cnt[plane] > 4) {
evt.
aveHitRMS[plane] /= cnt[plane]; }
4441 std::cout << std::fixed << std::setprecision(1);
4473 unsigned int cstat = inTPCID.
Cryostat;
4474 unsigned int tpc = inTPCID.
TPC;
4477 art::ServiceHandle<lariov::ChannelStatusService>()->GetProvider();
4479 for (
unsigned short pln = 0; pln < nplanes; ++pln) {
4483 for (
unsigned int wire = 0; wire < nwires; ++wire) {
4493 for (
unsigned short pln = 0; pln < nplanes; ++pln) {
4505 for (
unsigned short pln = 0; pln < nplanes; ++pln) {
4508 for (
unsigned int wire = 0; wire < nwires; ++wire)
4513 unsigned int nBadWireFix = 0;
4516 auto wid =
hit.WireID();
4517 if (wid.Cryostat != cstat)
continue;
4518 if (wid.TPC != tpc)
continue;
4519 unsigned short pln = wid.Plane;
4520 unsigned int wire = wid.Wire;
4530 std::cout <<
"FillWireHitRange found hits on " << nBadWireFix
4531 <<
" wires that were declared not-good by the ChannelStatus service. Fixed it...\n";
4549 if (nplanes > 3)
return false;
4552 double local[3] = {0., 0., 0.};
4553 double world[3] = {0., 0., 0.};
4568 slc.
nWires.resize(nplanes);
4573 std::pair<unsigned int, unsigned int>
flag;
4574 flag.first = UINT_MAX;
4575 flag.second = UINT_MAX;
4588 for (
unsigned short plane = 0; plane < nplanes; ++plane) {
4597 unsigned int lastWire = 0, lastPlane = 0;
4598 for (
unsigned int iht = 0; iht < slc.
slHits.size(); ++iht) {
4599 unsigned int ahi = slc.
slHits[iht].allHitsIndex;
4600 if (ahi > (*
evt.
allHits).size() - 1)
return false;
4602 if (
hit.WireID().Cryostat != cstat)
continue;
4603 if (
hit.WireID().TPC != tpc)
continue;
4604 unsigned short plane =
hit.WireID().Plane;
4605 unsigned int wire =
hit.WireID().Wire;
4606 if (wire > slc.
nWires[plane] - 1) {
4607 mf::LogWarning(
"TC") <<
"FillWireHitRange: Invalid wire number " << wire <<
" > "
4608 << slc.
nWires[plane] - 1 <<
" in plane " << plane <<
" Quitting";
4611 if (plane == lastPlane && wire < lastWire) {
4612 mf::LogWarning(
"TC")
4613 <<
"FillWireHitRange: Hits are not in increasing wire order. Quitting ";
4625 unsigned int slhitsSize = slc.
slHits.size();
4626 for (
unsigned short plane = 0; plane < nplanes; ++plane) {
4627 for (
unsigned int wire = slc.
firstWire[plane]; wire < slc.
lastWire[plane]; ++wire) {
4628 if (slc.
wireHitRange[plane][wire].first == UINT_MAX)
continue;
4629 if (slc.
wireHitRange[plane][wire].first > slhitsSize - 1 &&
4639 std::cout <<
"Slice ID/Index " << slc.
ID <<
"/" <<
slices.size() <<
" tpc " << tpc
4642 std::cout << std::fixed << std::setprecision(1) << slc.
xLo <<
" < X < " << slc.
xHi <<
") (";
4643 std::cout << std::fixed << std::setprecision(1) << slc.
yLo <<
" < Y < " << slc.
yHi <<
") (";
4644 std::cout << std::fixed << std::setprecision(1) << slc.
zLo <<
" < Z < " << slc.
zHi <<
")\n";
4671 if (itj1 > slc.
tjs.size() - 1)
return false;
4672 if (itj2 > slc.
tjs.size() - 1)
return false;
4683 if (pfp1 != USHRT_MAX || pfp2 != USHRT_MAX) {
4684 if (pfp1 != USHRT_MAX && pfp2 != USHRT_MAX)
return false;
4686 if (pfp1 == USHRT_MAX) std::swap(itj1, itj2);
4702 mf::LogVerbatim(
"TC") <<
"MergeAndStore: T" << tj1.
ID <<
" and T" << tj2.
ID
4703 <<
" at merge points " <<
PrintPos(slc, tp1e1) <<
" "
4709 std::swap(tj1, tj2);
4710 std::swap(tp1e0, tp2e0);
4711 std::swap(tp1e1, tp2e1);
4713 mf::LogVerbatim(
"TC") <<
" swapped the order. Merge points " <<
PrintPos(slc, tp1e1) <<
" "
4729 if (tp2e0[0] > tp1e0[0] && tp2e1[0] < tp1e1[0])
return false;
4733 if (tp1e0[0] > tp2e0[0] && tp1e1[0] < tp2e1[0])
return false;
4737 if (tp2e1[0] > tp1e1[0] && tp2e0[0] < tp1e0[0])
return false;
4738 if (tp1e1[0] > tp2e1[0] && tp1e0[0] < tp2e0[0])
return false;
4745 mf::LogVerbatim(
"TC") <<
"MergeAndStore: Found a good vertex between Tjs " << tj1.
VtxID[1]
4753 mf::LogVerbatim(
"TC") <<
"MergeAndStore: You are merging the end of trajectory T" << tj1.
ID
4754 <<
" with a Bragg peak. Not merging\n";
4765 float minSep = 1000;
4766 unsigned short tj2ClosePt = 0;
4770 mf::LogVerbatim(
"TC") <<
" Merge point tj1 " <<
PrintPos(slc, endtj1TP) <<
" tj2ClosePt "
4771 << tj2ClosePt <<
" Pos " <<
PrintPos(slc, tj2.
Pts[tj2ClosePt]);
4773 if (tj2ClosePt > tj2.
EndPt[1])
return false;
4782 std::vector<unsigned int> tj1Hits;
4783 for (
unsigned short ii = 0; ii < tj1.
Pts.size(); ++ii) {
4786 unsigned short ipt = tj1.
Pts.size() - 1 - ii;
4787 tj1Hits.insert(tj1Hits.end(), tj1.
Pts[ipt].Hits.begin(), tj1.
Pts[ipt].Hits.end());
4788 if (ipt == 0)
break;
4791 bool bumpedPt =
true;
4794 for (
unsigned short ii = 0; ii < tj2.
Pts[tj2ClosePt].Hits.size(); ++ii) {
4795 unsigned int iht = tj2.
Pts[tj2ClosePt].Hits[ii];
4796 if (std::find(tj1Hits.begin(), tj1Hits.end(), iht) != tj1Hits.end()) bumpedPt =
true;
4798 if (bumpedPt && tj2ClosePt < tj2.
EndPt[1]) { ++tj2ClosePt; }
4803 if (doPrt) mf::LogVerbatim(
"TC") <<
" revised tj2ClosePt " << tj2ClosePt;
4806 tj1.
Pts.insert(tj1.
Pts.end(), tj2.
Pts.begin() + tj2ClosePt, tj2.
Pts.end());
4813 if (tj2.
VtxID[1] > 0) {
4834 int newTjID = slc.
tjs.size();
4838 if (doPrt) mf::LogVerbatim(
"TC") <<
" MAS success. Created T" << newTjID;
4840 for (
auto& tj : slc.
tjs)
4841 if (tj.ParentID == tj1ID || tj.ParentID == tj2ID) tj.ParentID = newTjID;
4854 std::vector<int> tmp;
4855 if (
id <= 0)
return tmp;
4856 unsigned int uid = id;
4858 if (type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"P") {
4860 for (
auto& pfp : slc.
pfps) {
4861 if (pfp.ID <= 0)
continue;
4862 if (std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), id) != pfp.TjIDs.end())
4863 tmp.push_back(pfp.ID);
4868 if (type1Name ==
"P" && uid <= slc.
pfps.size() && (type2Name ==
"2S" || type2Name ==
"3S")) {
4870 auto& pfp = slc.
pfps[uid - 1];
4872 std::vector<int> ssid;
4873 for (
auto& ss : slc.
cots) {
4874 if (ss.ID <= 0)
continue;
4876 if (!shared.empty() && std::find(ssid.begin(), ssid.end(), ss.ID) == ssid.end())
4877 ssid.push_back(ss.ID);
4879 if (type2Name ==
"2S")
return ssid;
4880 for (
auto& ss3 : slc.
showers) {
4881 if (ss3.ID <= 0)
continue;
4883 if (!shared.empty() && std::find(tmp.begin(), tmp.end(), ss3.ID) == tmp.end())
4884 tmp.push_back(ss3.ID);
4889 if (type1Name ==
"2V" && uid <= slc.
vtxs.size() && type2Name ==
"T") {
4891 for (
auto& tj : slc.
tjs) {
4893 for (
unsigned short end = 0;
end < 2; ++
end) {
4894 if (tj.VtxID[
end] !=
id)
continue;
4895 if (std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4901 if (type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"P") {
4902 for (
auto& pfp : slc.
pfps) {
4903 if (pfp.ID == 0)
continue;
4904 for (
unsigned short end = 0;
end < 2; ++
end) {
4905 if (pfp.Vx3ID[
end] !=
id)
continue;
4907 if (std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4913 if (type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"T") {
4915 for (
auto& tj : slc.
tjs) {
4917 for (
unsigned short end = 0;
end < 2; ++
end) {
4918 if (tj.VtxID[
end] > 0 && tj.VtxID[
end] <= slc.
vtxs.size()) {
4919 auto& vx2 = slc.
vtxs[tj.VtxID[
end] - 1];
4920 if (vx2.Vx3ID !=
id)
continue;
4921 if (std::find(tmp.begin(), tmp.end(), tj.ID) == tmp.end()) tmp.push_back(tj.ID);
4928 if (type1Name ==
"3V" && uid <= slc.
vtx3s.size() && type2Name ==
"2V") {
4930 for (
auto& vx2 : slc.
vtxs) {
4931 if (vx2.ID == 0)
continue;
4932 if (vx2.Vx3ID ==
id) tmp.push_back(vx2.ID);
4937 if (type1Name ==
"3S" && uid <= slc.
showers.size() && type2Name ==
"T") {
4939 auto& ss3 = slc.
showers[uid - 1];
4940 if (ss3.ID == 0)
return tmp;
4941 for (
auto cid : ss3.CotIDs) {
4942 auto& ss = slc.
cots[cid - 1];
4943 if (ss.ID == 0)
continue;
4944 tmp.insert(tmp.end(), ss.TjIDs.begin(), ss.TjIDs.end());
4950 if (type1Name ==
"2S" && uid <= slc.
cots.size() && type2Name ==
"T") {
4952 auto& ss = slc.
cots[uid - 1];
4956 if (type1Name ==
"3S" && uid <= slc.
showers.size() && type2Name ==
"P") {
4958 auto& ss3 = slc.
showers[uid - 1];
4959 if (ss3.ID == 0)
return tmp;
4960 for (
auto cid : ss3.CotIDs) {
4961 auto& ss = slc.
cots[cid - 1];
4962 if (ss.ID == 0)
continue;
4963 for (
auto tid : ss.TjIDs) {
4964 auto& tj = slc.
tjs[tid - 1];
4966 if (!tj.AlgMod[
kMat3D])
continue;
4967 for (
auto& pfp : slc.
pfps) {
4968 if (pfp.ID <= 0)
continue;
4969 if (std::find(pfp.TjIDs.begin(), pfp.TjIDs.end(), tj.ID) == pfp.TjIDs.end())
continue;
4970 if (std::find(tmp.begin(), tmp.end(), pfp.ID) == tmp.end()) tmp.push_back(pfp.ID);
4977 if (type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"2S") {
4979 for (
auto& ss : slc.
cots) {
4980 if (ss.ID == 0)
continue;
4981 if (std::find(ss.TjIDs.begin(), ss.TjIDs.end(), id) != ss.TjIDs.end()) tmp.push_back(ss.ID);
4986 if (type1Name ==
"T" && uid <= slc.
tjs.size() && type2Name ==
"3S") {
4988 for (
auto& ss : slc.
cots) {
4989 if (ss.ID == 0)
continue;
4990 if (std::find(ss.TjIDs.begin(), ss.TjIDs.end(), id) == ss.TjIDs.end())
continue;
4991 if (ss.SS3ID > 0) tmp.push_back(ss.SS3ID);
5003 unsigned int fromhit,
5005 unsigned short pass)
5011 float fromWire = fromHit.WireID().Wire;
5012 float fromTick = fromHit.PeakTime();
5013 float toWire = toHit.WireID().Wire;
5014 float toTick = toHit.PeakTime();
5016 bool success =
StartTraj(slc, tj, fromWire, fromTick, toWire, toTick, tCTP, pass);
5017 if (!success)
return false;
5022 auto& tp = tj.
Pts[0];
5023 mf::LogVerbatim(
"TC") <<
"StartTraj T" << tj.
ID <<
" from " << (int)fromWire <<
":"
5024 << (
int)fromTick <<
" -> " << (int)toWire <<
":" << (
int)toTick
5025 <<
" StepDir " << tj.
StepDir <<
" dir " << tp.Dir[0] <<
" " << tp.Dir[1]
5026 <<
" ang " << tp.Ang <<
" AngleCode " << tp.AngleCode <<
" angErr "
5041 unsigned short pass)
5052 int fWire = std::nearbyint(fromWire);
5053 int tWire = std::nearbyint(toWire);
5054 if (tWire < fWire) { stepdir = -1; }
5055 else if (tWire == fWire) {
5057 if (toTick < fromTick) stepdir = -1;
5067 if (!
MakeBareTrajPoint(slc, fromWire, fromTick, toWire, toTick, tCTP, tp))
return false;
5070 tj.
Pts.push_back(tp);
5075 auto& tp = tj.
Pts[0];
5076 mf::LogVerbatim(
"TC") <<
"StartTraj T" << tj.
ID <<
" from " << (int)fromWire <<
":"
5077 << (
int)fromTick <<
" -> " << (int)toWire <<
":" << (
int)toTick
5078 <<
" StepDir " << tj.
StepDir <<
" dir " << tp.
Dir[0] <<
" " << tp.
Dir[1]
5079 <<
" ang " << tp.
Ang <<
" AngleCode " << tp.
AngleCode <<
" angErr "
5087 std::pair<unsigned short, unsigned short>
5091 for (
unsigned short isl = 0; isl <
slices.size(); ++isl) {
5093 if (typeName ==
"T") {
5094 for (
unsigned short indx = 0; indx < slc.tjs.size(); ++indx) {
5095 if (slc.tjs[indx].UID == uID) {
return std::make_pair(isl, indx); }
5098 if (typeName ==
"P") {
5099 for (
unsigned short indx = 0; indx < slc.pfps.size(); ++indx) {
5100 if (slc.pfps[indx].UID == uID) {
return std::make_pair(isl, indx); }
5103 if (typeName ==
"2V") {
5104 for (
unsigned short indx = 0; indx < slc.vtxs.size(); ++indx) {
5105 if (slc.vtxs[indx].UID == uID) {
return std::make_pair(isl, indx); }
5108 if (typeName ==
"3V") {
5109 for (
unsigned short indx = 0; indx < slc.vtx3s.size(); ++indx) {
5110 if (slc.vtx3s[indx].UID == uID) {
return std::make_pair(isl, indx); }
5113 if (typeName ==
"2S") {
5114 for (
unsigned short indx = 0; indx < slc.cots.size(); ++indx) {
5115 if (slc.cots[indx].UID == uID) {
return std::make_pair(isl, indx); }
5118 if (typeName ==
"3S") {
5119 for (
unsigned short indx = 0; indx < slc.showers.size(); ++indx) {
5120 if (slc.showers[indx].UID == uID) {
return std::make_pair(isl, indx); }
5124 return std::make_pair(USHRT_MAX, USHRT_MAX);
5142 static double sum, sumx, sumy, sumx2, sumy2, sumxy;
5143 static unsigned short cnt;
5144 static std::vector<Point2_t> fitPts;
5145 static std::vector<double> fitWghts;
5162 if (inPtErr <= 0.)
return false;
5164 double wght = 1 / (inPtErr * inPtErr);
5166 sumx += wght * inPt[0];
5167 sumx2 += wght * inPt[0] * inPt[0];
5168 sumy += wght * inPt[1];
5169 sumy2 += wght * inPt[1] * inPt[1];
5170 sumxy += wght * inPt[0] * inPt[1];
5171 if (mode == 1)
return true;
5172 fitPts.push_back(inPt);
5173 fitWghts.push_back(wght);
5177 if (cnt < 2)
return false;
5179 double delta = sum * sumx2 - sumx * sumx;
5180 if (delta == 0.)
return false;
5181 double A = (sumx2 * sumy - sumx * sumxy) / delta;
5182 double B = (sumxy * sum - sumx * sumy) / delta;
5186 if (cnt == 2 || fitPts.empty())
return true;
5189 if (fitPts.size() != cnt)
return false;
5190 double ndof = cnt - 2;
5192 (sumy2 + A * A * sum + B * B * sumx2 - 2 * (A * sumy + B * sumxy - A * B * sumx)) / ndof;
5194 outVecErr[0] = sqrt(varnce * sumx2 / delta);
5195 outVecErr[1] = sqrt(varnce * sum / delta);
5203 for (
unsigned short ii = 0; ii < fitPts.size(); ++ii) {
5204 double arg = fitPts[ii][1] - A - B * fitPts[ii][0];
5205 sum += fitWghts[ii] * arg * arg;
5207 chiDOF = sum / ndof;
5221 if (strng ==
"instruct") {
5222 std::cout <<
"****** Unrecognized DebugConfig. Here are your options\n";
5223 std::cout <<
" 'C:T:P:W:Tick' where C = cryostat, T = TPC, W = wire, Tick (+/-5) to debug "
5224 "stepping (DUNE)\n";
5225 std::cout <<
" 'P:W:Tick' for single cryostat/TPC detectors (uB, LArIAT, etc)\n";
5226 std::cout <<
" 'WorkID <id> <slice index>' where <id> is a tj work ID (< 0) in slice <slice "
5227 "index> (default = 0)\n";
5228 std::cout <<
" 'Merge <CTP>' to debug trajectory merging\n";
5229 std::cout <<
" '2V <CTP>' to debug 2D vertex finding\n";
5230 std::cout <<
" '3V' to debug 3D vertex finding\n";
5231 std::cout <<
" 'VxMerge' to debug 2D vertex merging\n";
5232 std::cout <<
" 'JunkVx' to debug 2D junk vertex finder\n";
5233 std::cout <<
" 'PFP' to debug 3D matching and PFParticles\n";
5234 std::cout <<
" 'MVI <MVI> <MVI Iteration>' for detailed debugging of one PFP MatchVecIndex\n";
5235 std::cout <<
" 'DeltaRay' to debug delta ray tagging\n";
5236 std::cout <<
" 'Muon' to debug muon tagging\n";
5237 std::cout <<
" '2S <CTP>' to debug a 2D shower in CTP\n";
5238 std::cout <<
" 'Reco TPC <TPC>' to only reconstruct hits in the specified TPC\n";
5239 std::cout <<
" 'Reco Slice <ID>' to reconstruct all sub-slices in the recob::Slice with the "
5241 std::cout <<
" 'SubSlice <sub-slice index>' where <slice index> restricts output to the "
5242 "specified sub-slice index\n";
5243 std::cout <<
" 'Stitch' to debug PFParticle stitching between TPCs\n";
5244 std::cout <<
" 'Sum' or 'Summary' to print a debug summary report\n";
5245 std::cout <<
" 'Dump <WorkID>' or 'Dump <UID>' to print all TPs in the trajectory to "
5246 "tcdump<UID>.csv\n";
5247 std::cout <<
" Note: Algs with debug printing include HamVx, HamVx2, SplitTjCVx, Comp3DVx, "
5248 "Comp3DVxIG, VtxHitsSwap\n";
5249 std::cout <<
" Set SkipAlgs: [\"bogusText\"] to print a list of algorithm names\n";
5254 if (strng.find(
"3V") != std::string::npos) {
5259 if (strng.find(
"3S") != std::string::npos) {
5264 if (strng.find(
"VxMerge") != std::string::npos) {
5269 if (strng.find(
"JunkVx") != std::string::npos) {
5274 if (strng.find(
"DeltaRay") != std::string::npos) {
5279 if (strng.find(
"Muon") != std::string::npos) {
5284 if (strng.find(
"Stitch") != std::string::npos) {
5289 if (strng.find(
"HamVx") != std::string::npos) {
5294 if (strng.find(
"HamVx2") != std::string::npos) {
5299 if (strng.find(
"Sum") != std::string::npos) {
5305 std::vector<std::string> words;
5306 boost::split(words, strng, boost::is_any_of(
" :"), boost::token_compress_on);
5307 if (words.size() == 5) {
5320 if (words[0] ==
"PFP" || words[0] ==
"MVI") {
5324 if (words.size() > 2) {
5326 if (words.size() == 3)
debug.
MVI_Iter = std::stoi(words[2]);
5330 if (words.size() == 2 && words[0] ==
"Dump") {
5337 if (words.size() > 1 && words[0] ==
"WorkID") {
5342 if (words.size() > 2)
debug.
Slice = std::stoi(words[2]);
5348 if (words.size() == 3 && words[0] ==
"Reco" && words[1] ==
"TPC") {
5354 if (words.size() == 3 && words[0] ==
"Reco" && words[1] ==
"Slice") {
5359 if (words.size() == 3) {
5371 if (words.size() == 2 && words[0] ==
"Merge") {
5377 if (words.size() == 2 && words[0] ==
"2V") {
5383 if (words.size() == 2 && words[0] ==
"2S") {
5390 if (words.size() == 2 && words[0] ==
"SubSlice") {
5406 for (
auto& slc :
slices) {
5407 for (
auto& tj : slc.tjs) {
5410 std::ofstream outfile;
5412 outfile.open(fname, std::ios::out | std::ios::trunc);
5413 outfile <<
"Dump trajectory T" << tj.UID <<
" WorkID " << tj.WorkID;
5414 outfile <<
" ChgRMS " << std::setprecision(2) << tj.ChgRMS;
5416 outfile <<
"Wire, Chg T" << tj.UID
5417 <<
", totChg, Tick, Delta, NTPsFit, Ang, ChiDOF, KinkSig, HitPosErr\n";
5418 for (
unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
5419 auto& tp = tj.Pts[ipt];
5420 outfile << std::fixed;
5421 outfile << std::setprecision(0) << std::nearbyint(tp.Pos[0]);
5422 outfile <<
"," << (int)tp.Chg;
5425 for (
auto iht : tp.Hits) {
5427 totChg +=
hit.Integral();
5429 outfile <<
"," << (int)totChg;
5430 outfile <<
"," << std::setprecision(0) << std::nearbyint(tp.Pos[1] /
tcc.
unitsPerTick);
5431 outfile <<
"," << std::setprecision(2) << tp.Delta;
5432 outfile <<
"," << tp.NTPsFit;
5433 outfile <<
"," << std::setprecision(3) << tp.Ang;
5434 outfile <<
"," << std::setprecision(2) << tp.FitChi;
5435 outfile <<
"," << std::setprecision(2) << tp.KinkSig;
5436 outfile <<
"," << std::setprecision(2) << sqrt(tp.HitPosErr2);
5440 std::cout <<
"Points on T" << tj.UID <<
" dumped to " << fname <<
"\n";
5453 std::cout <<
"*** TrajCluster debug mode configuration in";
5498 unsigned short cnt = 0;
5499 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib) {
5509 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib) {
5529 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5532 if (!slc.vtx3s.empty()) prt3V =
true;
5533 if (!slc.vtxs.empty()) prt2V =
true;
5534 if (!slc.tjs.empty()) prtT =
true;
5535 if (!slc.pfps.empty()) prtP =
true;
5536 if (!slc.showers.empty()) prtS3 =
true;
5538 mf::LogVerbatim myprt(
"TC");
5539 myprt <<
"Debug report from caller " << someText <<
"\n";
5540 myprt <<
" 'prodID' = <sliceID>:<subSliceIndex>:<productID>/<productUID>\n";
5542 myprt <<
"************ Showers ************\n";
5543 myprt <<
" prodID Vtx parUID ___ChgPos____ ______Dir_____ ____posInPln____ "
5544 "___projInPln____ 2D shower UIDs\n";
5545 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5548 if (slc.showers.empty())
continue;
5549 for (
auto& ss3 : slc.showers)
5550 Print3S(detProp, someText, myprt, ss3);
5554 bool printHeader =
true;
5555 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5558 if (slc.pfps.empty())
continue;
5559 for (
auto& pfp : slc.pfps)
5560 PrintP(someText, myprt, pfp, printHeader);
5564 bool printHeader =
true;
5565 myprt <<
"****** 3D vertices "
5566 "******************************************__2DVtx_UID__*******\n";
5567 myprt <<
" prodID Cstat TPC X Y Z XEr YEr "
5568 "ZEr pln0 pln1 pln2 Wire score Prim? Nu? nTru";
5569 myprt <<
" ___________2D_Pos____________ _____Tj UIDs________\n";
5570 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5573 if (slc.vtx3s.empty())
continue;
5574 for (
auto& vx3 : slc.vtx3s)
5575 Print3V(detProp, someText, myprt, vx3, printHeader);
5579 bool printHeader =
true;
5580 myprt <<
"************ 2D vertices ************\n";
5581 myprt <<
" prodID CTP wire err tick err ChiDOF NTj Pass "
5582 " Topo ChgFrac Score v3D Tj UIDs\n";
5583 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5586 if (slc.vtxs.empty())
continue;
5587 for (
auto& vx2 : slc.vtxs)
5588 Print2V(someText, myprt, vx2, printHeader);
5592 bool printHeader =
true;
5593 for (
size_t isl = 0; isl <
slices.size(); ++isl) {
5596 if (slc.tjs.empty())
continue;
5597 for (
auto& tj : slc.tjs)
5598 PrintT(someText, myprt, tj, printHeader);
5607 if (pfp.
ID <= 0)
return;
5609 myprt <<
"************ PFParticles ************\n";
5610 myprt <<
" prodID sVx _____sPos____ CS _______sDir______ ____sdEdx_____ eVx "
5611 "_____ePos____ CS ____edEdx_____ MVI MCSMom Len nTP3 nSec SLk? PDG Par \n";
5612 printHeader =
false;
5615 if (sIndx.first == USHRT_MAX)
return;
5616 auto& slc =
slices[sIndx.first];
5620 myprt << std::setw(12) << str;
5622 for (
unsigned short end = 0;
end < 2; ++
end) {
5625 myprt << std::setw(6) << str;
5626 myprt << std::fixed <<
std::right << std::setprecision(0);
5628 myprt << std::setw(5) << pos[0];
5629 myprt << std::setw(5) << pos[1];
5630 myprt << std::setw(5) << pos[2];
5638 myprt << std::fixed <<
std::right << std::setprecision(2);
5640 myprt << std::setw(6) <<
dir[0];
5641 myprt << std::setw(6) << dir[1];
5642 myprt << std::setw(6) << dir[2];
5644 for (
auto& dedx : pfp.
dEdx[
end]) {
5645 if (dedx < 50) { myprt << std::setw(5) << std::setprecision(1) << dedx; }
5647 myprt << std::setw(5) << std::setprecision(0) << dedx;
5650 if (pfp.
dEdx[end].size() < 3) {
5651 for (
size_t i = 0; i < 3 - pfp.
dEdx[
end].size(); ++i) {
5652 myprt << std::setw(6) <<
' ';
5656 myprt << std::setw(6) << pfp.
MVI;
5659 float length =
Length(pfp);
5660 if (length < 100) { myprt << std::setw(5) << std::setprecision(1) << length; }
5662 myprt << std::setw(5) << std::setprecision(0) << length;
5664 myprt << std::setw(5) << pfp.
TP3Ds.size();
5667 myprt << std::setw(5) << pfp.
PDGCode;
5669 if (!pfp.
TjIDs.empty()) {
5670 if (pfp.
TjUIDs.empty()) {
5672 for (
auto tjid : pfp.
TjIDs)
5673 myprt <<
" TU" << slc.tjs[tjid - 1].UID;
5677 for (
auto tjuid : pfp.
TjUIDs)
5678 myprt <<
" TU" << tjuid;
5683 for (
auto dtruid : pfp.
DtrUIDs)
5684 myprt <<
" PU" << dtruid;
5692 std::string someText,
5693 mf::LogVerbatim& myprt,
5698 if (vx3.
ID <= 0)
return;
5700 if (sIndx.first == USHRT_MAX)
return;
5701 auto& slc =
slices[sIndx.first];
5704 <<
"****** 3D vertices ******************************************__2DVtx_UID__*******\n";
5705 myprt <<
" prodID Cstat TPC X Y Z pln0 pln1 pln2 Wire score "
5707 myprt <<
" ___________2D_Pos____________ _____Tj UIDs________\n";
5708 printHeader =
false;
5711 myprt <<
std::right << std::setw(12) << std::fixed << str;
5712 myprt << std::setprecision(0);
5718 for (
auto vx2id : vx3.
Vx2ID) {
5728 unsigned short nTruMatch = 0;
5729 for (
unsigned short ipl = 0; ipl < slc.nPlanes; ++ipl) {
5730 if (vx3.
Vx2ID[ipl] == 0)
continue;
5731 unsigned short iv2 = vx3.
Vx2ID[ipl] - 1;
5734 myprt <<
std::right << std::setw(6) << std::setprecision(1) << vx3.
Score;
5735 myprt << std::setw(6) << vx3.
Primary;
5736 myprt << std::setw(4) << vx3.
Neutrino;
5737 myprt <<
std::right << std::setw(5) << nTruMatch;
5739 for (
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5741 myprt <<
" " <<
PrintPos(slc, pos);
5743 if (vx3.
Wire == -2) {
5745 for (
unsigned short end = 0;
end < 2; ++
end) {
5746 for (
auto& pfp : slc.pfps) {
5747 if (pfp.Vx3ID[
end] == vx3.
ID) {
5748 for (
auto tjID : pfp.TjIDs) {
5749 auto& tj = slc.tjs[tjID - 1];
5750 myprt <<
" T" << tj.UID;
5757 auto vxtjs =
GetAssns(slc,
"3V", vx3.
ID,
"T");
5758 for (
auto tjid : vxtjs) {
5759 auto& tj = slc.tjs[tjid - 1];
5760 myprt <<
" TU" << tj.UID;
5771 if (vx2.
ID <= 0)
return;
5774 if (sIndx.first == USHRT_MAX)
return;
5775 auto& slc =
slices[sIndx.first];
5777 myprt <<
"************ 2D vertices ************\n";
5778 myprt <<
" prodID CTP wire err tick err ChiDOF NTj Pass Topo ChgFrac Score "
5780 printHeader =
false;
5783 myprt <<
std::right << std::setw(12) << std::fixed << str;
5785 myprt <<
std::right << std::setw(8) << std::setprecision(0) << std::nearbyint(vx2.
Pos[0]);
5786 myprt <<
std::right << std::setw(5) << std::setprecision(1) << vx2.
PosErr[0];
5787 myprt <<
std::right << std::setw(8) << std::setprecision(0)
5795 myprt <<
std::right << std::setw(6) << std::setprecision(1) << vx2.
Score;
5797 if (vx2.
Vx3ID > 0) v3id = slc.vtx3s[vx2.
Vx3ID - 1].UID;
5801 for (
unsigned short ii = 0; ii < slc.tjs.size(); ++ii) {
5802 auto const& tj = slc.tjs[ii];
5803 if (tj.AlgMod[
kKilled])
continue;
5804 for (
unsigned short end = 0;
end < 2; ++
end) {
5805 if (tj.VtxID[
end] != (
short)vx2.
ID)
continue;
5812 for (
unsigned short ib = 1; ib <
VtxBitNames.size(); ++ib)
5820 std::string someText,
5821 mf::LogVerbatim& myprt,
5824 if (ss3.
ID <= 0)
return;
5826 if (sIndx.first == USHRT_MAX)
return;
5827 auto& slc =
slices[sIndx.first];
5831 myprt << std::fixed << std::setw(12) << str;
5834 myprt << std::setw(6) << str;
5835 for (
unsigned short xyz = 0; xyz < 3; ++xyz)
5836 myprt << std::setprecision(0) << std::setw(5) << ss3.
ChgPos[xyz];
5837 for (
unsigned short xyz = 0; xyz < 3; ++xyz)
5838 myprt << std::setprecision(2) << std::setw(5) << ss3.
Dir[xyz];
5839 std::vector<float> projInPlane(slc.nPlanes);
5840 for (
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5843 myprt <<
" " <<
PrintPos(slc, tp.Pos);
5844 projInPlane[plane] = tp.Delta;
5846 for (
unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
5847 myprt << std::setprecision(2) << std::setw(5) << projInPlane[plane];
5849 for (
auto cid : ss3.
CotIDs) {
5850 auto& ss = slc.cots[cid - 1];
5852 myprt << std::setw(5) << str;
5854 if (ss3.
NeedsUpdate) myprt <<
" *** Needs update";
5863 if (tj.
ID <= 0)
return;
5866 myprt <<
"************ Trajectories ************\n";
5867 myprt <<
"Tj AngleCode-EndFlag decoder (EF): <AngleCode> + <reason for stopping>";
5868 myprt <<
" (B=Bragg Peak, V=Vertex, A=AngleKink, C=ChargeKink, T=Trajectory)\n";
5869 myprt <<
" prodID CTP Pass Pts W:T Ang EF AveQ W:T Ang EF AveQ "
5870 "Chg(k) chgRMS Mom __Vtx__ PDG eLike Par Pri NuPar WorkID \n";
5871 printHeader =
false;
5874 if (sIndx.first == USHRT_MAX)
return;
5875 auto& slc =
slices[sIndx.first];
5877 myprt << std::fixed << std::setw(12) << str;
5878 myprt << std::setw(6) << tj.
CTP;
5879 myprt << std::setw(5) << tj.
Pass;
5880 myprt << std::setw(5) << tj.
EndPt[1] - tj.
EndPt[0] + 1;
5881 unsigned short endPt0 = tj.
EndPt[0];
5882 auto& tp0 = tj.
Pts[endPt0];
5884 if (itick < 0) itick = 0;
5885 myprt << std::setw(6) << (int)(tp0.Pos[0] + 0.5) <<
":" << itick;
5886 if (itick < 10) { myprt <<
" "; }
5887 if (itick < 100) { myprt <<
" "; }
5888 if (itick < 1000) { myprt <<
" "; }
5889 myprt << std::setw(6) << std::setprecision(2) << tp0.Ang;
5890 myprt << std::setw(2) << tp0.AngleCode;
5904 myprt << std::setw(5) << (int)tp0.AveChg;
5905 unsigned short endPt1 = tj.
EndPt[1];
5906 auto& tp1 = tj.
Pts[endPt1];
5908 myprt << std::setw(6) << (int)(tp1.Pos[0] + 0.5) <<
":" << itick;
5909 if (itick < 10) { myprt <<
" "; }
5910 if (itick < 100) { myprt <<
" "; }
5911 if (itick < 1000) { myprt <<
" "; }
5912 myprt << std::setw(6) << std::setprecision(2) << tp1.Ang;
5913 myprt << std::setw(2) << tp1.AngleCode;
5927 myprt << std::setw(5) << (int)tp1.AveChg;
5928 myprt << std::setw(7) << std::setprecision(1) << tj.
TotChg / 1000;
5929 myprt << std::setw(7) << std::setprecision(2) << tj.
ChgRMS;
5930 myprt << std::setw(5) << tj.
MCSMom;
5932 if (tj.
VtxID[0] > 0) vxid = slc.vtxs[tj.
VtxID[0] - 1].UID;
5933 myprt << std::setw(4) << vxid;
5935 if (tj.
VtxID[1] > 0) vxid = slc.vtxs[tj.
VtxID[1] - 1].UID;
5936 myprt << std::setw(4) << vxid;
5937 myprt << std::setw(5) << tj.
PDGCode;
5939 myprt << std::setw(5) << tj.
ParentID;
5940 myprt << std::setw(5) <<
PrimaryID(slc, tj);
5942 myprt << std::setw(7) << tj.
WorkID;
5943 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
5953 std::string someText,
5960 mf::LogVerbatim myprt(
"TC");
5963 if (!slc.
vtx3s.empty()) {
5967 <<
"****** 3D vertices ******************************************__2DVtx_ID__*******\n";
5969 <<
" Vtx Cstat TPC X Y Z XEr YEr ZEr pln0 pln1 pln2 Wire "
5970 "score Prim? Nu? nTru";
5971 myprt <<
" ___________2D_Pos____________ _____Tjs________\n";
5972 for (
unsigned short iv = 0; iv < slc.
vtx3s.size(); ++iv) {
5973 if (slc.
vtx3s[iv].ID == 0)
continue;
5977 myprt <<
std::right << std::setw(5) << std::fixed << vid;
5978 myprt << std::setprecision(1);
5991 unsigned short nTruMatch = 0;
5992 for (
unsigned short ipl = 0; ipl < slc.
nPlanes; ++ipl) {
5993 if (vx3.
Vx2ID[ipl] == 0)
continue;
5994 unsigned short iv2 = vx3.
Vx2ID[ipl] - 1;
5997 myprt <<
std::right << std::setw(6) << std::setprecision(1) << vx3.
Score;
5998 myprt << std::setw(6) << vx3.
Primary;
5999 myprt << std::setw(4) << vx3.
Neutrino;
6000 myprt <<
std::right << std::setw(5) << nTruMatch;
6002 for (
unsigned short plane = 0; plane < slc.
nPlanes; ++plane) {
6004 myprt <<
" " <<
PrintPos(slc, pos);
6006 if (vx3.
Wire == -2) {
6008 for (
auto& pfp : slc.
pfps) {
6009 if (pfp.Vx3ID[0] == slc.
vtx3s[iv].ID) {
6010 for (
auto& tjID : pfp.TjIDs)
6011 myprt <<
" t" << tjID;
6013 if (pfp.Vx3ID[1] == slc.
vtx3s[iv].ID) {
6014 for (
auto& tjID : pfp.TjIDs)
6015 myprt <<
" t" << tjID;
6020 auto vxtjs =
GetAssns(slc,
"3V", vx3.
ID,
"T");
6021 for (
auto tjid : vxtjs)
6022 myprt <<
" t" << tjid;
6027 if (!slc.
vtxs.empty()) {
6028 bool foundOne =
false;
6029 for (
unsigned short iv = 0; iv < slc.
vtxs.size(); ++iv) {
6030 auto& vx2 = slc.
vtxs[iv];
6032 if (vx2.NTraj == 0)
continue;
6037 myprt << someText <<
"************ 2D vertices ************\n";
6039 <<
" ID CTP wire err tick err ChiDOF NTj Pass Topo ChgFrac Score v3D "
6041 for (
auto& vx2 : slc.
vtxs) {
6042 if (vx2.ID == 0)
continue;
6046 myprt <<
std::right << std::setw(5) << std::fixed << vid;
6047 myprt <<
std::right << std::setw(6) << vx2.CTP;
6048 myprt <<
std::right << std::setw(8) << std::setprecision(0)
6049 << std::nearbyint(vx2.Pos[0]);
6050 myprt <<
std::right << std::setw(5) << std::setprecision(1) << vx2.PosErr[0];
6051 myprt <<
std::right << std::setw(8) << std::setprecision(0)
6053 myprt <<
std::right << std::setw(5) << std::setprecision(1)
6055 myprt <<
std::right << std::setw(7) << vx2.ChiDOF;
6056 myprt <<
std::right << std::setw(5) << vx2.NTraj;
6057 myprt <<
std::right << std::setw(5) << vx2.Pass;
6058 myprt <<
std::right << std::setw(6) << vx2.Topo;
6059 myprt <<
std::right << std::setw(9) << std::setprecision(2) << vx2.TjChgFrac;
6060 myprt <<
std::right << std::setw(6) << std::setprecision(1) << vx2.Score;
6061 myprt <<
std::right << std::setw(5) << vx2.Vx3ID;
6064 for (
unsigned short ii = 0; ii < slc.
tjs.size(); ++ii) {
6065 auto const& aTj = slc.
tjs[ii];
6067 if (aTj.AlgMod[
kKilled])
continue;
6068 for (
unsigned short end = 0;
end < 2; ++
end) {
6069 if (aTj.VtxID[
end] != (
short)vx2.ID)
continue;
6075 for (
unsigned short ib = 1; ib <
VtxBitNames.size(); ++ib)
6076 if (vx2.Stat[ib]) myprt <<
" " <<
VtxBitNames[ib];
6083 if (slc.
tjs.empty()) {
6084 mf::LogVerbatim(
"TC") << someText <<
" No allTraj trajectories to print";
6090 if (itj == USHRT_MAX) {
6092 myprt <<
"Tj AngleCode-EndFlag (EF) decoder: <AngleCode> + <reason for stopping>";
6093 myprt <<
" (B=Bragg Peak, V=Vertex, A=AngleKink, C=ChargeKink, T=Trajectory)\n";
6094 std::vector<unsigned int> tmp;
6096 <<
" UID CTP Pass Pts W:T Ang EF AveQ W:T Ang EF AveQ Chg(k) "
6097 "chgRMS Mom SDr __Vtx__ PDG Par Pri NuPar WorkID \n";
6098 for (
unsigned short ii = 0; ii < slc.
tjs.size(); ++ii) {
6099 auto& aTj = slc.
tjs[ii];
6101 myprt << someText <<
" ";
6107 myprt << std::fixed << std::setw(5) << tid;
6108 myprt << std::setw(6) << aTj.CTP;
6109 myprt << std::setw(5) << aTj.Pass;
6110 myprt << std::setw(5) << aTj.EndPt[1] - aTj.EndPt[0] + 1;
6111 unsigned short endPt0 = aTj.EndPt[0];
6112 auto& tp0 = aTj.Pts[endPt0];
6114 if (itick < 0) itick = 0;
6115 myprt << std::setw(6) << (int)(tp0.Pos[0] + 0.5) <<
":" << itick;
6116 if (itick < 10) { myprt <<
" "; }
6117 if (itick < 100) { myprt <<
" "; }
6118 if (itick < 1000) { myprt <<
" "; }
6119 myprt << std::setw(6) << std::setprecision(2) << tp0.Ang;
6120 myprt << std::setw(2) << tp0.AngleCode;
6121 if (aTj.EndFlag[0][
kBragg]) { myprt <<
"B"; }
6122 else if (aTj.EndFlag[0][
kAtVtx]) {
6125 else if (aTj.EndFlag[0][
kAtKink]) {
6128 else if (aTj.EndFlag[0][
kAtTj]) {
6134 myprt << std::setw(5) << (int)tp0.AveChg;
6135 unsigned short endPt1 = aTj.EndPt[1];
6136 auto& tp1 = aTj.Pts[endPt1];
6138 myprt << std::setw(6) << (int)(tp1.Pos[0] + 0.5) <<
":" << itick;
6139 if (itick < 10) { myprt <<
" "; }
6140 if (itick < 100) { myprt <<
" "; }
6141 if (itick < 1000) { myprt <<
" "; }
6142 myprt << std::setw(6) << std::setprecision(2) << tp1.Ang;
6143 myprt << std::setw(2) << tp1.AngleCode;
6144 if (aTj.EndFlag[1][
kBragg]) { myprt <<
"B"; }
6145 else if (aTj.EndFlag[1][
kAtVtx]) {
6151 myprt << std::setw(5) << (int)tp1.AveChg;
6152 myprt << std::setw(7) << std::setprecision(1) << aTj.TotChg / 1000;
6153 myprt << std::setw(7) << std::setprecision(2) << aTj.ChgRMS;
6154 myprt << std::setw(5) << aTj.MCSMom;
6155 myprt << std::setw(4) << aTj.StepDir;
6156 myprt << std::setw(4) << aTj.VtxID[0];
6157 myprt << std::setw(4) << aTj.VtxID[1];
6158 myprt << std::setw(5) << aTj.PDGCode;
6159 myprt << std::setw(5) << aTj.ParentID;
6160 myprt << std::setw(5) <<
PrimaryID(slc, aTj);
6162 myprt << std::setw(7) << aTj.WorkID;
6163 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
6164 if (aTj.AlgMod[ib]) myprt <<
" " <<
AlgBitNames[ib];
6170 if (itj > slc.
tjs.size() - 1)
return;
6172 auto const& aTj = slc.
tjs[itj];
6174 mf::LogVerbatim(
"TC") <<
"Print slc.tjs[" << itj <<
"] Vtx[0] " << aTj.VtxID[0] <<
" Vtx[1] "
6177 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
6178 if (aTj.AlgMod[ib]) myprt <<
" " <<
AlgBitNames[ib];
6182 if (ipt == USHRT_MAX) {
6184 for (
unsigned short ii = 0; ii < aTj.Pts.size(); ++ii)
6185 PrintTP(someText, slc, ii, aTj.StepDir, aTj.Pass, aTj.Pts[ii]);
6189 PrintTP(someText, slc, ipt, aTj.StepDir, aTj.Pass, aTj.Pts[ipt]);
6198 unsigned short tPoint)
6202 if (tPoint == USHRT_MAX) {
6204 mf::LogVerbatim myprt(
"TC");
6205 myprt << someText <<
" ";
6206 myprt <<
"Work: UID " << tj.
UID <<
" CTP " << tj.
CTP <<
" StepDir " << tj.
StepDir
6208 <<
" nPts " << tj.
Pts.size() <<
" EndPts " << tj.
EndPt[0] <<
" " << tj.
EndPt[1];
6209 myprt <<
" MCSMom " << tj.
MCSMom;
6211 myprt <<
" AlgMods:";
6212 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
6216 mf::LogVerbatim myprt(
"TC");
6217 myprt << someText <<
" ";
6218 myprt <<
"slcID " << slc.
ID <<
" T" << tj.
ID <<
" uT" << tj.
UID <<
" WorkID " << tj.
WorkID
6220 <<
" " << tj.
VtxID[1] <<
" nPts " << tj.
Pts.size() <<
" EndPts " << tj.
EndPt[0] <<
" "
6222 myprt <<
" MCSMom " << tj.
MCSMom;
6224 myprt <<
" AlgMods:";
6225 for (
unsigned short ib = 0; ib <
AlgBitNames.size(); ++ib)
6229 for (
unsigned short ipt = 0; ipt < tj.
Pts.size(); ++ipt)
6233 for (
unsigned short ic = 0; ic < slc.
cots.size(); ++ic) {
6234 if (slc.
cots[ic].TjIDs.empty())
continue;
6236 if (slc.
cots[ic].ShowerTjID != tj.
ID)
continue;
6238 mf::LogVerbatim myprt(
"TC");
6239 myprt <<
"cots index " << ic <<
" ";
6240 myprt << someText <<
" Envelope";
6241 if (ss.
Envelope.empty()) { myprt <<
" NA"; }
6244 myprt <<
" " << (int)vtx[0] <<
":" << (
int)(vtx[1] /
tcc.
unitsPerTick);
6246 myprt <<
" Energy " << (int)ss.
Energy;
6247 myprt <<
" Area " << std::fixed << std::setprecision(1) << (int)ss.
EnvelopeArea
6249 myprt <<
"\nInShower TjIDs";
6251 myprt <<
" " << tjID;
6255 myprt <<
"NearTjIDs";
6257 myprt <<
" " << tjID;
6261 myprt <<
"Angle " << std::fixed << std::setprecision(2) << ss.
Angle <<
" +/- "
6263 myprt <<
" AspectRatio " << std::fixed << std::setprecision(2) << ss.
AspectRatio;
6264 myprt <<
" DirectionFOM " << std::fixed << std::setprecision(2) << ss.
DirectionFOM;
6267 myprt <<
" No parent";
6269 myprt <<
" TruParentID " << ss.
TruParentID <<
" SS3ID " << ss.
SS3ID <<
"\n";
6270 if (ss.
NeedsUpdate) myprt <<
"*********** This shower needs to be updated ***********";
6271 myprt <<
"................................................";
6277 if (tPoint > tj.
Pts.size() - 1) {
6278 mf::LogVerbatim(
"TC") <<
"Can't print non-existent traj point " << tPoint;
6289 mf::LogVerbatim(
"TC") << someText
6290 <<
" TRP CTP Ind Stp Delta RMS Ang C Err Dir0 Dir1 Q "
6291 " AveQ Pull FitChi NTPF KinkSig Hits ";
6300 unsigned short pass,
6303 mf::LogVerbatim myprt(
"TC");
6304 myprt << someText <<
" TRP" << std::fixed;
6306 if (dir > 0) { myprt <<
"+"; }
6310 myprt << std::setw(6) << tp.
CTP;
6311 myprt << std::setw(5) << ipt;
6312 myprt << std::setw(5) << tp.
Step;
6313 myprt << std::setw(6) << std::setprecision(2) << tp.
Delta;
6314 myprt << std::setw(6) << std::setprecision(2) << tp.
DeltaRMS;
6315 myprt << std::setw(6) << std::setprecision(2) << tp.
Ang;
6317 myprt << std::setw(6) << std::setprecision(2) << tp.
AngErr;
6318 myprt << std::setw(6) << std::setprecision(2) << tp.
Dir[0];
6319 myprt << std::setw(6) << std::setprecision(2) << tp.
Dir[1];
6320 myprt << std::setw(7) << (int)tp.
Chg;
6321 myprt << std::setw(8) << (int)tp.
AveChg;
6322 myprt << std::setw(6) << std::setprecision(1) << tp.
ChgPull;
6323 myprt << std::setw(7) << tp.
FitChi;
6324 myprt << std::setw(6) << tp.
NTPsFit;
6325 myprt << std::setw(7) << std::setprecision(3) << tp.
KinkSig;
6327 if (tp.
Hits.size() > 16) {
6329 myprt <<
" " << tp.
Hits.size() <<
" shower hits";
6332 for (
unsigned short ii = 0; ii < tp.
Hits.size(); ++ii) {
6333 unsigned int iht = tp.
Hits[ii];
6335 myprt <<
" " <<
hit.WireID().Wire <<
":" << (int)
hit.PeakTime();
6343 myprt <<
"T" << slc.
slHits[iht].InTraj;
6345 if (tp.
InPFP > 0) myprt <<
" inP" << tp.
InPFP;
6356 std::string str =
"";
6357 for (
unsigned short ib = 0; ib < 8; ++ib) {
6366 if (ib ==
kEnvFlag) str +=
" Flag";
6375 mf::LogVerbatim myprt(
"TC");
6378 myprt <<
" PFP sVx ________sPos_______ EF _______sDir______ ____sdEdx_____ eVx "
6379 "________ePos_______ EF _______eDir______ ____edEdx____ Len nTp3 MCSMom ShLike? "
6384 myprt << std::setw(5) << pid;
6386 for (
unsigned short end = 0;
end < 2; ++
end) {
6387 myprt << std::setw(4) << pfp.
Vx3ID[
end];
6388 myprt << std::fixed <<
std::right << std::setprecision(1);
6390 myprt << std::setw(7) << pos[0];
6391 myprt << std::setw(7) << pos[1];
6392 myprt << std::setw(7) << pos[2];
6400 myprt << std::setw(6) << ef;
6401 myprt << std::fixed <<
std::right << std::setprecision(2);
6403 myprt << std::setw(6) <<
dir[0];
6404 myprt << std::setw(6) << dir[1];
6405 myprt << std::setw(6) << dir[2];
6406 for (
auto& dedx : pfp.
dEdx[
end]) {
6407 if (dedx < 50) { myprt << std::setw(5) << std::setprecision(1) << dedx; }
6409 myprt << std::setw(5) << std::setprecision(0) << dedx;
6412 if (pfp.
dEdx[end].size() < 3) {
6413 for (
size_t i = 0; i < 3 - pfp.
dEdx[
end].size(); ++i) {
6414 myprt << std::setw(6) <<
' ';
6419 float length =
Length(pfp);
6420 if (length < 100) { myprt << std::setw(5) << std::setprecision(1) << length; }
6422 myprt << std::setw(5) << std::setprecision(0) << length;
6424 myprt << std::setw(5) << std::setprecision(2) << pfp.
TP3Ds.size();
6427 myprt << std::setw(5) << pfp.
PDGCode;
6430 myprt << std::setw(5) <<
PrimaryUID(slc, pfp);
6431 if (!pfp.
TjIDs.empty()) {
6432 for (
auto& tjID : pfp.
TjIDs)
6433 myprt <<
" T" << tjID;
6437 for (
auto& dtrUID : pfp.
DtrUIDs)
6438 myprt <<
" P" << dtrUID;
6446 if (slc.
pfps.empty())
return;
6448 mf::LogVerbatim myprt(
"TC");
6451 <<
" PFP sVx ________sPos_______ ______sDir______ ______sdEdx_____ eVx "
6452 "________ePos_______ ______eDir______ ______edEdx_____ BstPln PDG TruPDG Par Prim E*P\n";
6453 bool printHeader =
true;
6454 for (
auto& pfp : slc.
pfps) {
6455 PrintPFP(someText, slc, pfp, printHeader);
6456 printHeader =
false;
6465 if (end > 1)
return "Invalid end";
6468 for (
unsigned short ib = 0; ib <
EndFlagNames.size(); ++ib) {
6479 if (first) tmp =
" none";
6487 if (end > 1)
return "Invalid end";
6490 for (
unsigned short ib = 0; ib <
EndFlagNames.size(); ++ib) {
6535 unsigned int wire = 0;
6536 if (pos[0] > -0.4) wire = std::nearbyint(pos[0]);
Expect tracks entering from the front face. Don't create neutrino PFParticles.
void PrintAll(detinfo::DetectorPropertiesData const &detProp, std::string someText)
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 HitsPosTime(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
void CheckTrajBeginChg(TCSlice &slc, unsigned short itj)
float AveChg
Calculated using ALL hits.
void ReleaseHits(TCSlice &slc, Trajectory &tj)
short MCSMom(const TCSlice &slc, const std::vector< int > &tjIDs)
std::vector< Trajectory > tjs
vector of all trajectories in each plane
unsigned short FarEnd(const TCSlice &slc, const PFPStruct &pfp, const Point3_t &pos)
Point2_t dEdx
dE/dx for 3D matched trajectories
float Length(const PFPStruct &pfp)
bool dbgStitch
debug PFParticle stitching
void SetEndPoints(Trajectory &tj)
then if[["$THISISATEST"==1]]
void FitPar(const TCSlice &slc, const Trajectory &tj, unsigned short originPt, unsigned short npts, short fitDir, ParFit &pFit, unsigned short usePar)
bool MakeVertexObsolete(std::string fcnLabel, TCSlice &slc, VtxStore &vx2, bool forceKill)
bool TrajHitsOK(TCSlice &slc, const std::vector< unsigned int > &iHitsInMultiplet, const std::vector< unsigned int > &jHitsInMultiplet)
std::vector< float > kinkCuts
kink finder algorithm
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.
bool InsideFV(const TCSlice &slc, const PFPStruct &pfp, unsigned short end)
unsigned short CloseEnd(const TCSlice &slc, const Trajectory &tj, const Point2_t &pos)
struct of temporary 2D vertices (end points)
std::vector< int > GetAssns(TCSlice &slc, std::string type1Name, int id, std::string type2Name)
std::vector< unsigned int > PutTrajHitsInVector(const Trajectory &tj, HitStatus_t hitRequest)
const std::vector< std::string > AlgBitNames
std::vector< ShowerStruct > cots
bool AttachAnyVertexToTraj(TCSlice &slc, int tjID, bool prt)
CTP_t CTP
Cryostat, TPC, Plane code.
std::vector< float > maxPos0
short recoTPC
only reconstruct in the seleted TPC
process_name opflash particleana ie x
std::vector< int > NearTjIDs
std::array< double, 3 > Point3_t
std::vector< ShowerStruct3D > showers
bool SignalAtTp(TrajPoint &tp)
void SetPDGCode(TCSlice &slc, unsigned short itj)
then echo unknown compiler flag
std::vector< Point2_t > Envelope
void Print2V(std::string someText, mf::LogVerbatim &myprt, VtxStore &vx2, bool &printHeader)
tagged as a vertex between Tjs that are matched to MC truth neutrino interaction particles ...
void Print3V(detinfo::DetectorPropertiesData const &detProp, std::string someText, mf::LogVerbatim &myprt, Vtx3Store &vx3, bool &printHeader)
void PrintPFP(std::string someText, TCSlice &slc, const PFPStruct &pfp, bool printHeader)
vertex position fixed manually - no fitting done
Declaration of signal hit object.
void FindAlongTrans(Point3_t pos1, Vector3_t dir1, Point3_t pos2, Point2_t &alongTrans)
void PrintTrajectory(std::string someText, const TCSlice &slc, const Trajectory &tj, unsigned short tPoint)
void PrintTP(std::string someText, const TCSlice &slc, unsigned short ipt, short dir, unsigned short pass, const TrajPoint &tp)
std::vector< std::vector< std::pair< unsigned int, unsigned int > > > wireHitRange
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
BEGIN_PROLOG or score(default)}sbnd_crttrackmatchingalg_crID
std::string PrintEndFlag(const PFPStruct &pfp, unsigned short end)
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.
double Temperature() const
In kelvin.
short MCSMom
Normalized RMS using ALL hits. Assume it is 50% to start.
float TpSumHitChg(const TCSlice &slc, TrajPoint const &tp)
std::string PrintPos(const TCSlice &slc, const TrajPoint &tp)
void ChkChgAsymmetry(TCSlice &slc, Trajectory &tj, bool prt)
CryostatID_t Cryostat
Index of cryostat.
float ExpectedHitsRMS(TCSlice &slc, const TrajPoint &tp)
std::size_t size(FixedBins< T, C > const &) noexcept
bool TrajClosestApproach(Trajectory const &tj, float x, float y, unsigned short &closePt, float &DOCA)
void PosInPlane(detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, const Vtx3Store &vx3, unsigned short plane, Point2_t &pos)
void FillWireHitRange(geo::TPCID inTPCID)
float TrajPointSeparation(const TrajPoint &tp1, const TrajPoint &tp2)
std::vector< std::pair< unsigned int, unsigned int > > tpcSrcHitRange
void SetAngleCode(TrajPoint &tp)
void PrintP(std::string someText, mf::LogVerbatim &myprt, PFPStruct &pfp, bool &printHeader)
PFPStruct CreatePFP(const TCSlice &slc)
Point3_t PosAtEnd(const PFPStruct &pfp, unsigned short end)
float PointTrajDOCA(const TCSlice &slc, unsigned int iht, TrajPoint const &tp)
double DeltaAngle(const Vector3_t v1, const Vector3_t v2)
a general purpose flag bit used in 3D matching
bool dbgSlc
debug only in the user-defined slice? default is all slices
bool StartTraj(TCSlice &slc, Trajectory &tj, unsigned int fromhit, unsigned int tohit, unsigned short pass)
bool MakeBareTrajPoint(const TCSlice &slc, unsigned int fromHit, unsigned int toHit, TrajPoint &tp)
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)
float MCSThetaRMS(const TCSlice &slc, const Trajectory &tj)
std::array< int, 2 > Vx3ID
bool expectSlicedHits
info passed from the module - used to (not) define wireHitRange
short int Multiplicity() const
How many hits could this one be shared with.
float TPHitsRMSTime(const TCSlice &slc, const TrajPoint &tp, HitStatus_t hitRequest)
unsigned int MVI
MatchVec Index for detailed 3D matching.
bool IsShowerLike(TCSlice &slc, const std::vector< int > TjIDs)
unsigned short NumUsedHitsInTj(const TCSlice &slc, const Trajectory &tj)
std::string TPEnvString(const TrajPoint &tp)
pure virtual base interface for detector clocks
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)
float MaxTjLen(const TCSlice &slc, std::vector< int > &tjIDs)
void Print3S(detinfo::DetectorPropertiesData const &detProp, std::string someText, mf::LogVerbatim &myprt, ShowerStruct3D &ss3)
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)
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
const std::vector< std::string > EndFlagNames
std::vector< float > showerTag
shower-like trajectory tagging + shower reconstruction
unsigned short Pass
the pass on which it was created
bool dbg3V
debug 3D vertex finding
double Efield(unsigned int planegap=0) const
kV/cm
std::string PrintHitShort(const TCHit &tch)
TrajPoint MakeBareTP(detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, const Point3_t &pos, CTP_t inCTP)
float OverlapFraction(const TCSlice &slc, const Trajectory &tj1, const Trajectory &tj2)
float HitsRMSTime(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
Access the description of detector geometry.
unsigned int Hit
set to the hit index in evt.allHits if a Plane:Wire:Tick match is found
bool CompatibleMerge(const TCSlice &slc, std::vector< int > &tjIDs, bool prt)
std::vector< int > TjUIDs
std::vector< unsigned int > PutHitsInVector(const TCSlice &slc, PFPStruct const &pfp, HitStatus_t hitRequest)
const std::vector< std::string > StrategyBitNames
float HitSep2(const TCSlice &slc, unsigned int iht, unsigned int jht)
int Cryostat
Select Cryostat.
int NeutrinoPrimaryTjID(const TCSlice &slc, const Trajectory &tj)
float HitsRMSTick(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
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.
void PrintAllTraj(detinfo::DetectorPropertiesData const &detProp, std::string someText, TCSlice &slc, unsigned short itj, unsigned short ipt, bool prtVtx)
short nPtsAve
dump trajectory points
int PrimaryID(const TCSlice &slc, const Trajectory &tj)
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
process_name opflash particleana ie ie y
int Wire
Select hit Wire for debugging.
std::array< float, 2 > Point2_t
std::vector< float > maxPos1
int PDGCodeVote(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, PFPStruct &pfp)
float unitsPerTick
scale factor from Tick to WSE equivalent units
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
bool TrajIsClean(TCSlice &slc, Trajectory &tj, bool prt)
int WorkID
Select the StartWorkID for debugging.
float DeadWireCount(const TCSlice &slc, const TrajPoint &tp1, const TrajPoint &tp2)
bool BraggSplit(TCSlice &slc, unsigned short itj)
void DefineHitPos(TCSlice &slc, TrajPoint &tp)
unsigned short NearbyCleanPt(const TCSlice &slc, const Trajectory &tj, unsigned short end)
Vector3_t PointDirection(const Point3_t p1, const Point3_t p2)
TP is near a hit in the srcHit collection but no allHit hit exists (DUNE disambiguation error) ...
CTP_t CTP
Cryostat, TPC, Plane code.
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
std::vector< float > aveHitRMS
average RMS of an isolated hit
std::vector< TrajPoint > Pts
Trajectory points.
float ElectronLikelihood(const TCSlice &slc, const Trajectory &tj)
float TwoTPAngle(const TrajPoint &tp1, const TrajPoint &tp2)
float KinkSignificance(TCSlice &slc, Trajectory &tj1, unsigned short end1, Trajectory &tj2, unsigned short end2, unsigned short nPtsFit, bool useChg, bool prt)
std::vector< std::vector< bool > > goodWire
for($it=0;$it< $RaceTrack_number;$it++)
float ChgFracNearPos(const TCSlice &slc, const Point2_t &pos, const std::vector< int > &tjIDs)
std::vector< unsigned int > FindCloseHits(const TCSlice &slc, std::array< int, 2 > const &wireWindow, Point2_t const &timeWindow, const unsigned short plane, HitStatus_t hitRequest, bool usePeakTime, bool &hitsNear)
float ChgFracBetween(detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, Point3_t pos1, Point3_t pos2)
void MakeHaloTj(TCSlice &slc, Trajectory &muTj, bool prt)
auto end(FixedBins< T, C > const &) noexcept
std::vector< VtxStore > vtxs
2D vertices
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}
double ConvertXToTicks(double X, int p, int t, int c) const
bool PointInsideEnvelope(const Point2_t &Point, const std::vector< Point2_t > &Envelope)
void ChkEndKink(TCSlice &slc, Trajectory &tj, bool prt)
std::vector< float > match3DCuts
3D matching cuts
std::vector< SectionFit > SectionFits
void TagJunkTj(TCSlice &slc, Trajectory &tj, bool prt)
unsigned int NumberTimeSamples() const
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
virtual bool IsGood(raw::ChannelID_t channel) const
Returns whether the specified channel is physical and good.
void MakeTrajectoryObsolete(TCSlice &slc, unsigned int itj)
short StartEnd
The starting end (-1 = don't know)
float PointTrajDOCA2(const TCSlice &slc, float wire, float time, TrajPoint const &tp)
double PosSep2(const Point3_t &pos1, const Point3_t &pos2)
unsigned short GetPFPIndex(const TCSlice &slc, int tjID)
void FitTraj(TCSlice &slc, Trajectory &tj)
std::string PrintHit(const TCHit &tch)
bool Fit2D(short mode, Point2_t inPt, float &inPtErr, Vector2_t &outVec, Vector2_t &outVecErr, float &chiDOF)
bool SplitTraj(detinfo::DetectorPropertiesData const &detProp, TCSlice &slc, unsigned short itj, float XPos, bool makeVx2, bool prt)
void TrajPointTrajDOCA(const TCSlice &slc, TrajPoint const &tp, Trajectory const &tj, unsigned short &closePt, float &minSep)
const geo::GeometryCore * geom
Class providing information about the quality of channels.
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
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)
unsigned short NearestPtWithChg(const TCSlice &slc, const Trajectory &tj, unsigned short thePt)
bool valsIncreasing(const SortEntry &c1, const SortEntry &c2)
bool SetMag(Vector3_t &v1, double mag)
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
Definition of data types for geometry description.
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)
float HitsPosTick(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
std::vector< unsigned int > firstWire
the first wire with a hit
auto norm(Vector const &v)
Return norm of the specified vector.
int ID
ID that is local to one slice.
std::vector< TCSlice > slices
std::array< unsigned short, 2 > VtxID
ID of 2D vertex.
void UpdateTjChgProperties(std::string inFcnLabel, TCSlice &slc, Trajectory &tj, bool prt)
std::bitset< 16 > modes
number of points to find AveChg
std::vector< TCHit > slHits
float PointPull(const PFPStruct &pfp, const TP3D &tp3d)
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
bool equal(double a, double b)
Comparison tolerance, in centimeters.
std::bitset< 16 > Stat
Vertex status bits using kVtxBit_t.
int Tick
Select hit PeakTime for debugging (< 0 for vertex finding)
void TrajIntersection(TrajPoint const &tp1, TrajPoint const &tp2, Point2_t &pos)
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
double DotProd(const Vector3_t &v1, const Vector3_t &v2)
std::vector< Vtx3Store > vtx3s
3D vertices
bool DecodeDebugString(std::string strng)
std::vector< recob::Hit > const * srcHits
std::bitset< 128 > useAlg
Max hit separation for making junk trajectories. < 0 to turn off.
Contains all timing reference information for the detector.
short StepDir
-1 = going US (-> small wire#), 1 = going DS (-> large wire#)
float MaxHitDelta(TCSlice &slc, Trajectory &tj)
float TrajLength(const Trajectory &tj)
std::string to_string(WindowPattern const &pattern)
std::bitset< 128 > AlgMod
Bit set if algorithm AlgBit_t modifed the trajectory.
then echo File list $list not found else cat $list while read file do echo $file sed s
std::vector< short > muonTag
void UpdateVxEnvironment(TCSlice &slc)
geo::PlaneID DecodeCTP(CTP_t CTP)
std::vector< int > GetVtxTjIDs(const TCSlice &slc, const VtxStore &vx2)
double PosSep(const Point3_t &pos1, const Point3_t &pos2)
void TrimHiChgEndPts(TCSlice &slc, Trajectory &tj, bool prt)
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
bool valsDecreasing(const SortEntry &c1, const SortEntry &c2)
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
Interface for experiment-specific channel quality info provider.
std::pair< unsigned short, unsigned short > GetSliceIndex(std::string typeName, int uID)
unsigned short MVI_Iter
MVI iteration - see FindPFParticles.
std::vector< unsigned int > nWires
use the stiff electron strategy
std::array< std::bitset< 8 >, 2 > EndFlag
float PointTrajSep2(float wire, float time, TrajPoint const &tp)
std::array< double, 3 > Vector3_t
std::vector< float > chkStopCuts
Bragg peak finder configuration.
bool SignalAtTpInSlc(const TCSlice &slc, const TrajPoint &tp)
std::vector< TP3D > TP3Ds
int ID
ID of the recob::Slice (not the sub-slice)
std::array< std::vector< float >, 2 > dEdx
void SetVx2Score(TCSlice &slc)
std::vector< float > vtx2DCuts
Max position pull, max Position error rms.
std::bitset< 8 > Strategy
finds tracks best matching by angle
bool NearbySrcHit(geo::PlaneID plnID, unsigned int wire, float loTick, float hiTick)
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
void TjDeltaRMS(const TCSlice &slc, const Trajectory &tj, unsigned short firstPt, unsigned short lastPt, double &rms, unsigned short &cnt)
std::vector< PFPStruct > pfps
std::vector< int > FindCloseTjs(const TCSlice &slc, const TrajPoint &fromTp, const TrajPoint &toTp, const float &maxDelta)
bool SignalBetween(const TCSlice &slc, const TrajPoint &tp1, const TrajPoint &tp2, const float &MinWireSignalFraction)
2D representation of charge deposited in the TDC/wire plane
void MoveTPToWire(TrajPoint &tp, float wire)
unsigned short NumPtsWithCharge(const TCSlice &slc, const Trajectory &tj, bool includeDeadWires)
void MergeGhostTjs(TCSlice &slc, CTP_t inCTP)
unsigned int ChannelID_t
Type representing the ID of a readout channel.
unsigned int allHitsIndex
print OUTPUT<< EOF;< setup name="Default"version="1.0">< worldref="volWorld"/></setup ></gdml > EOF close(OUTPUT)
TPCID_t TPC
Index of the TPC within its cryostat.
Interface for experiment-specific service for channel quality info.
bool StorePFP(TCSlice &slc, PFPStruct &pfp)
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
int PrimaryUID(const TCSlice &slc, const PFPStruct &pfp)
bool TrajTrajDOCA(const TCSlice &slc, const Trajectory &tj1, const Trajectory &tj2, unsigned short &ipt1, unsigned short &ipt2, float &minSep)
std::vector< std::vector< std::pair< unsigned int, unsigned int > > > wireHitRange
Vector3_t DirAtEnd(const PFPStruct &pfp, unsigned short end)
short recoSlice
only reconstruct the slice with ID (0 = all)
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 LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
float TPHitsRMSTick(const TCSlice &slc, const TrajPoint &tp, HitStatus_t hitRequest)
physics associatedGroupsWithLeft p1
void PrintTPHeader(std::string someText)
BEGIN_PROLOG could also be cout
CTP_t CTP
set to an invalid CTP
std::vector< int > DtrUIDs
constexpr Point origin()
Returns a origin position with a point of the specified type.
unsigned short AngleRange(TrajPoint const &tp)
use the stiff muon strategy
Encapsulate the construction of a single detector plane.
std::array< std::bitset< 8 >, 2 > EndFlag
void SetTPEnvironment(TCSlice &slc, CTP_t inCTP)
bool HasDuplicateHits(const TCSlice &slc, Trajectory const &tj, bool prt)