51 return (c1.length > c2.length);
56 return (c1.length < c2.length);
133 std::array<float, 2>
X;
150 std::array<std::vector<clPar>, 3>
cls;
155 std::array<float, 2>
X;
186 std::array<std::vector<unsigned short>, 3>
vxCls;
191 std::array<std::vector<art::Ptr<recob::Hit>>, 3>
TrkHits;
207 std::array<std::vector<art::Ptr<recob::Hit>>, 3>
trkHits;
209 std::array<std::vector<art::Ptr<recob::Hit>>, 3>
seedHits;
221 std::array<unsigned short, 3>
End;
240 void PrintTracks()
const;
243 art::FindManyP<recob::Hit>
const& fmCluHits);
244 float dXClTraj(art::FindManyP<recob::Hit>
const& fmCluHits,
248 unsigned short icl2);
254 void FindMaybeVertices();
257 art::FindManyP<recob::Hit>
const& fmCluHits);
260 art::FindManyP<recob::Hit>
const& fmCluHits);
262 void AngMatch(art::FindManyP<recob::Hit>
const& fmCluHits);
275 float ChargeAsym(std::array<float, 3>& mChg);
277 bool FindMissingCluster(
unsigned short kpl,
279 unsigned short& kend,
288 art::FindManyP<recob::Hit>
const& fmCluHits,
289 unsigned short procCode);
292 void FillTrkHits(art::FindManyP<recob::Hit>
const& fmCluHits,
unsigned short imat);
299 art::FindManyP<recob::Hit>
const& fmCluHits,
301 unsigned short procCode);
304 float ChargeNear(
unsigned short ipl,
305 unsigned short wire1,
307 unsigned short wire2,
311 float AngleFactor(
float slope);
322 fMatchAlgs = pset.get<std::vector<short>>(
"MatchAlgs");
323 fXMatchErr = pset.get<std::vector<float>>(
"XMatchErr");
326 fMatchMinLen = pset.get<std::vector<float>>(
"MatchMinLen");
329 fMaxDAng = pset.get<
float>(
"MaxDAng");
342 fuBCode = pset.get<
bool>(
"uBCode");
350 if (fMatchAlgs.size() > fXMatchErr.size() || fMatchAlgs.size() > fAngleMatchErr.size() ||
351 fMatchAlgs.size() > fChgAsymFactor.size() || fMatchAlgs.size() > fMatchMinLen.size() ||
352 fMatchAlgs.size() > fMakeAlgTracks.size()) {
353 mf::LogError(
"CCTM") <<
"Incompatible fcl input vector sizes";
357 for (
unsigned short ii = 0; ii < fMatchAlgs.size(); ++ii) {
358 if (fAngleMatchErr[ii] <= 0 || fXMatchErr[ii] <= 0) {
359 mf::LogError(
"CCTM") <<
"Invalid matching parameters " << fAngleMatchErr[ii] <<
" " 365 produces<std::vector<recob::PFParticle>>();
366 produces<art::Assns<recob::PFParticle, recob::Track>>();
367 produces<art::Assns<recob::PFParticle, recob::Cluster>>();
368 produces<art::Assns<recob::PFParticle, recob::Seed>>();
369 produces<art::Assns<recob::PFParticle, recob::Vertex>>();
370 produces<std::vector<recob::Vertex>>();
371 produces<std::vector<recob::Track>>();
372 produces<art::Assns<recob::Track, recob::Hit>>();
373 produces<std::vector<recob::Seed>>();
384 auto tcol = std::make_unique<std::vector<recob::Track>>();
385 auto thassn = std::make_unique<art::Assns<recob::Track, recob::Hit>>();
386 auto vcol = std::make_unique<std::vector<recob::Vertex>>();
387 auto pcol = std::make_unique<std::vector<recob::PFParticle>>();
388 auto ptassn = std::make_unique<art::Assns<recob::PFParticle, recob::Track>>();
389 auto pcassn = std::make_unique<art::Assns<recob::PFParticle, recob::Cluster>>();
390 auto psassn = std::make_unique<art::Assns<recob::PFParticle, recob::Seed>>();
391 auto pvassn = std::make_unique<art::Assns<recob::PFParticle, recob::Vertex>>();
394 auto scol = std::make_unique<std::vector<recob::Seed>>();
395 auto shassn = std::make_unique<art::Assns<recob::Seed, recob::Hit>>();
401 std::vector<art::Ptr<recob::Cluster>> clusterlist;
404 std::vector<art::Ptr<recob::Vertex>> vtxlist;
414 if (clusterlist.size() == 0)
return;
421 art::FindManyP<recob::Cluster, unsigned short> fmVtxCls(VtxListHandle, evt,
fVertexModuleLabel);
423 std::vector<CluLen> clulens;
425 unsigned short ipl, icl,
end, itr, tID, tIndex;
433 std::vector<art::Ptr<recob::Hit>> tmpHits;
434 std::vector<art::Ptr<recob::Cluster>> tmpCls;
435 std::vector<art::Ptr<recob::Vertex>> tmpVtx;
438 std::vector<size_t> dtrIndices;
441 double sPos[3], sDir[3];
442 double sErr[3] = {0, 0, 0};
448 std::vector<art::Ptr<recob::Hit>> clusterhits;
449 for (icl = 0; icl < clusterlist.size(); ++icl) {
450 ipl = clusterlist[icl]->Plane().Plane;
451 clusterhits = fmCluHits.at(icl);
452 if (clusterhits[0]->
WireID().
Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
453 std::cout <<
"CCTM Cluster-Hit End wire mis-match " << clusterhits[0]->WireID().Wire
454 <<
" vs " << std::nearbyint(clusterlist[icl]->EndWire()) <<
" Bail out! \n";
457 for (
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
458 if (clusterhits[iht]->
WireID().Plane != ipl) {
459 std::cout <<
"CCTM Cluster-Hit plane mis-match " << ipl <<
" vs " 460 << clusterhits[iht]->WireID().Plane <<
" on hit " << iht <<
" Bail out! \n";
473 for (ipl = 0; ipl < 3; ++ipl) {
480 for (ipl = 0; ipl <
nplanes; ++ipl) {
483 for (icl = 0; icl < clusterlist.size(); ++icl) {
484 if (clusterlist[icl]->
Plane().Cryostat !=
cstat)
continue;
485 if (clusterlist[icl]->
Plane().TPC !=
tpc)
continue;
486 if (clusterlist[icl]->
Plane().
Plane != ipl)
continue;
489 clulen.length = clusterlist[icl]->EndWire();
490 clulens.push_back(clulen);
492 if (clulens.size() == 0)
continue;
494 std::sort(clulens.begin(), clulens.end(),
lessThan);
495 if (clulens.size() == 0)
continue;
496 for (
unsigned short ii = 0; ii < clulens.size(); ++ii) {
497 const unsigned short icl = clulens[ii].index;
522 if (clstr.
Time[1] > clstr.
Time[0]) {
539 clstr.
Length = (
unsigned short)(0.5 + clstr.
Wire[1] - clstr.
Wire[0]);
542 clusterhits = fmCluHits.at(icl);
543 if (clusterhits.size() == 0) {
544 mf::LogError(
"CCTM") <<
"No associated cluster hits " << icl;
549 cls[ipl].push_back(clstr);
557 for (
unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
561 vtxlist[ivx]->XYZ(xyz);
568 std::vector<art::Ptr<recob::Cluster>>
const& vtxCls = fmVtxCls.at(ivx);
569 std::vector<const unsigned short*>
const& vtxClsEnd = fmVtxCls.data(ivx);
570 for (
unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
571 icl = vtxCls[vcass].key();
573 ipl = vtxCls[vcass]->Plane().Plane;
574 end = *vtxClsEnd[vcass];
577 <<
"Invalid end data from vertex - cluster association" <<
end;
581 for (
unsigned short jcl = 0; jcl <
cls[ipl].size(); ++jcl) {
582 if (
cls[ipl][jcl].EvtIndex == icl) {
583 cls[ipl][jcl].VtxIndex[
end] = ivx;
590 throw cet::exception(
"CCTM") <<
"Bad index from vertex - cluster association" << icl;
623 for (
unsigned short ipf = 0; ipf <
pfpToTrkID.size(); ++ipf) {
626 if (tID >
trk.size() + 1) {
633 for (
unsigned short jpf = 0; jpf <
pfpToTrkID.size(); ++jpf) {
635 if (
trk[itr].MomID == tID) dtrIndices.push_back(jpf);
636 if (
trk[itr].MomID == tID)
639 unsigned short parentIndex = USHRT_MAX;
644 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
645 if (!
vtx[ivx].Neutrino)
continue;
650 size_t vStart = vcol->size();
653 size_t vEnd = vcol->size();
656 vtx[ivx].ID = -
vtx[ivx].ID;
665 for (
unsigned short ii = 0; ii <
pfpToTrkID.size(); ++ii) {
673 <<
"daughters tID " << tID <<
" pdg " <<
trk[tIndex].PDGCode <<
" ipf " << ipf
674 <<
" parentIndex " << parentIndex <<
" dtr size " << dtrIndices.size();
679 size_t tStart = tcol->size();
692 size_t tEnd = tcol->size();
696 trk[tIndex].ID = -
trk[tIndex].ID;
699 for (ipl = 0; ipl <
nplanes; ++ipl)
701 tmpHits.end(),
trk[tIndex].TrkHits[ipl].begin(),
trk[tIndex].TrkHits[ipl].end());
706 unsigned short itj = 0;
707 if (end > 0) itj =
trk[tIndex].TrjPos.size() - 1;
708 for (
unsigned short ii = 0; ii < 3; ++ii) {
709 sPos[ii] =
trk[tIndex].TrjPos[itj](ii);
710 sDir[ii] =
trk[tIndex].TrjDir[itj](ii);
712 size_t sStart = scol->size();
715 size_t sEnd = scol->size();
720 for (ipl = 0; ipl <
nplanes; ++ipl)
726 for (
unsigned short ii = 0; ii <
trk[tIndex].ClsEvtIndices.size(); ++ii) {
727 icl =
trk[tIndex].ClsEvtIndices[ii];
728 tmpCls.push_back(clusterlist[icl]);
734 for (
unsigned short itr = 0; itr <
trk.size(); ++itr) {
736 if (
trk[itr].
ID < 0)
continue;
750 for (ipl = 0; ipl <
nplanes; ++ipl)
752 tmpHits.end(),
trk[itr].TrkHits[ipl].begin(),
trk[itr].TrkHits[ipl].end());
756 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
757 if (
vtx[ivx].
ID < 0)
continue;
766 double orphanLen = 0;
767 for (ipl = 0; ipl <
nplanes; ++ipl) {
768 for (icl = 0; icl <
cls[ipl].size(); ++icl) {
769 if (
cls[ipl][icl].
Length > 40 &&
cls[ipl][icl].InTrack < 0) {
770 orphanLen +=
cls[ipl][icl].Length;
773 <<
"Orphan long cluster " << ipl <<
":" << icl <<
":" <<
cls[ipl][icl].Wire[0]
774 <<
":" << (
int)
cls[ipl][icl].Time[0] <<
" length " <<
cls[ipl][icl].
Length;
781 std::cout <<
"Total orphan length " << orphanLen <<
"\n";
811 std::vector<std::vector<geo::WireID>> hitWID;
812 std::vector<std::vector<double>> hitX;
813 std::vector<std::vector<double>> hitXErr;
814 TVector3
pos, posErr;
815 std::vector<TVector3> trkDir;
816 std::vector<TVector3> trkDirErr;
821 unsigned short indx, indx2, iht, nHitsFit;
823 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
824 if (!
vtx[ivx].Neutrino)
continue;
830 unsigned int thePln, theTPC, theCst;
831 for (
unsigned short itk = 0; itk <
trk.size(); ++itk) {
832 for (
unsigned short end = 0;
end < 2; ++
end) {
833 if (
trk[itk].VtxIndex[
end] != ivx)
continue;
834 unsigned short itj = 0;
835 if (
end == 1) itj =
trk[itk].TrjPos.size() - 1;
838 hitWID.resize(indx + 1);
839 hitX.resize(indx + 1);
840 hitXErr.resize(indx + 1);
841 trkDir.resize(indx + 1);
842 trkDir[indx] =
trk[itk].TrjDir[itj];
843 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
844 if (
trk[itk].TrkHits[ipl].
size() < 2)
continue;
846 nHitsFit =
trk[itk].TrkHits[ipl].size();
848 indx2 = hitWID[indx].size();
849 hitWID[indx].resize(indx2 + nHitsFit);
850 hitX[indx].resize(indx2 + nHitsFit);
851 hitXErr[indx].resize(indx2 + nHitsFit);
852 for (
unsigned short ii = 0; ii < nHitsFit; ++ii) {
853 if (
end == 0) { iht = ii; }
855 iht =
trk[itk].TrkHits[ipl].size() - ii - 1;
857 hitWID[indx][indx2 + ii] =
trk[itk].TrkHits[ipl][iht]->WireID();
858 thePln =
trk[itk].TrkHits[ipl][iht]->WireID().Plane;
859 theTPC =
trk[itk].TrkHits[ipl][iht]->WireID().TPC;
860 theCst =
trk[itk].TrkHits[ipl][iht]->WireID().Cryostat;
862 trk[itk].TrkHits[ipl][iht]->PeakTime(), thePln, theTPC, theCst);
863 hitXErr[indx][indx2 + ii] =
fHitFitErrFac *
trk[itk].TrkHits[ipl][iht]->RMS();
868 if (hitX.size() < 2) {
876 if (ChiDOF > 3000)
continue;
882 unsigned short fitTrk = 0;
883 for (
unsigned short itk = 0; itk <
trk.size(); ++itk) {
884 for (
unsigned short end = 0;
end < 2; ++
end) {
885 if (
trk[itk].VtxIndex[
end] != ivx)
continue;
886 unsigned short itj = 0;
887 if (
end == 1) itj =
trk[itk].TrjPos.size() - 1;
888 trk[itk].TrjDir[itj] = trkDir[fitTrk];
901 unsigned short wire,
nwires, indx;
902 float dir, ctime,
cx, chgWinLo, chgWinHi;
905 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
906 for (
unsigned short icl = 0; icl <
cls[ipl].size(); ++icl) {
908 nwires =
cls[ipl][icl].Length / 2;
909 if (nwires < 2)
continue;
911 if (nwires > 30) nwires = 30;
912 for (
unsigned short end = 0;
end < 2; ++
end) {
916 for (
unsigned short w = 0;
w <
nwires; ++
w) {
917 wire =
cls[ipl][icl].Wire[
end] + dir *
w;
926 for (
unsigned int hit = firhit;
hit < lashit; ++
hit) {
929 <<
"FillChgNear bad lashit " << lashit <<
" size " <<
allhits.size() <<
"\n";
932 if (
allhits[
hit]->PeakTime() < chgWinLo)
continue;
933 if (
allhits[
hit]->PeakTime() > chgWinHi)
continue;
937 cnear /= (
float)(nwires - 1);
938 if (cnear >
cls[ipl][icl].Charge[
end]) {
942 cls[ipl][icl].ChgNear[
end] = 0;
956 unsigned short ivx, itr, ipl, ii, jtr;
957 unsigned short nus, nds, nuhs, ndhs;
958 float longUSTrk, longDSTrk, qual;
962 float tgMuonCut2 = 9;
966 unsigned short VtxIndex;
967 unsigned short nUSTk;
968 unsigned short nDSTk;
969 unsigned short nUSHit;
970 unsigned short nDSHit;
975 std::vector<NuVtx> nuVtxCand;
980 float best = 999, dx, dy, dz, dr;
984 for (ivx = 0; ivx <
vtx.size(); ++ivx) {
985 vtx[ivx].Neutrino =
false;
994 for (itr = 0; itr <
trk.size(); ++itr) {
995 if (
trk[itr].
ID < 0)
continue;
996 if (
trk[itr].PDGCode != 13)
continue;
997 for (itj = 0; itj <
trk[itr].TrjPos.size(); ++itj) {
998 dx =
trk[itr].TrjPos[itj](0) -
vtx[ivx].
X;
999 dy =
trk[itr].TrjPos[itj](1) -
vtx[ivx].
Y;
1000 dz =
trk[itr].TrjPos[itj](2) -
vtx[ivx].
Z;
1001 dr = dx * dx + dy * dy + dz * dz;
1002 if (dr < tgMuonCut2) {
1010 if (skipVtx)
continue;
1011 for (itr = 0; itr <
trk.size(); ++itr) {
1012 if (
trk[itr].
ID < 0)
continue;
1013 if (
trk[itr].VtxIndex[0] == ivx) {
1016 if (
trk[itr].
Length > longDSTrk) longDSTrk =
trk[itr].Length;
1017 for (ipl = 0; ipl <
nplanes; ++ipl)
1018 ndhs +=
trk[itr].TrkHits[ipl].
size();
1023 if (
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] >= 0) {
1027 if (
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] < 0) {
1030 if (
trk[itr].
Length > longUSTrk) longUSTrk =
trk[itr].Length;
1031 for (ipl = 0; ipl <
nplanes; ++ipl)
1032 nuhs +=
trk[itr].TrkHits[ipl].
size();
1036 if (skipVtx)
continue;
1037 if (nds == 0)
continue;
1038 qual = 1 / (
float)nds;
1039 qual /= (
float)ndhs;
1040 if (nus > 0) qual *= (
float)nuhs / (
float)ndhs;
1045 if (nds > 0 && longDSTrk > 5) {
1047 aNuVtx.VtxIndex = ivx;
1050 aNuVtx.nUSHit = nuhs;
1051 aNuVtx.nDSHit = ndhs;
1052 aNuVtx.longUSTrk = longUSTrk;
1053 aNuVtx.longDSTrk = longDSTrk;
1055 nuVtxCand.push_back(aNuVtx);
1065 if (imbest < 0)
return;
1069 vtx[ivx].Neutrino =
true;
1077 std::vector<unsigned short> dtrGen;
1078 std::vector<unsigned short> dtrNextGen;
1079 for (itr = 0; itr <
trk.size(); ++itr) {
1080 if (
trk[itr].
ID < 0)
continue;
1081 if (
trk[itr].VtxIndex[0] == ivx) {
1085 trk[itr].PDGCode = 2212;
1087 dtrGen.push_back(itr);
1089 if (
trk[itr].VtxIndex[1] == ivx) {
1093 trk[itr].PDGCode = 2212;
1097 for (ii = 0; ii <
trk[itr].TrjDir.size(); ++ii)
1098 trk[itr].TrjDir[ii] = -
trk[itr].TrjDir[ii];
1102 if (dtrGen.size() == 0)
return;
1104 unsigned short tmp, indx;
1105 unsigned short nit = 0;
1113 for (ii = 0; ii < dtrGen.size(); ++ii) {
1115 if (
trk[itr].VtxIndex[1] >= 0) {
1117 ivx =
trk[itr].VtxIndex[1];
1119 for (jtr = 0; jtr <
trk.size(); ++jtr) {
1120 if (jtr == itr)
continue;
1121 if (
trk[jtr].VtxIndex[0] == ivx) {
1123 indx =
trk[itr].DtrID.size();
1124 trk[itr].DtrID.resize(indx + 1);
1125 trk[itr].DtrID[indx] = jtr;
1127 trk[jtr].MomID =
trk[itr].ID;
1129 trk[jtr].PDGCode = 211;
1130 dtrNextGen.push_back(jtr);
1133 if (
trk[jtr].VtxIndex[1] == ivx) {
1135 indx =
trk[itr].DtrID.size();
1136 trk[itr].DtrID.resize(indx + 1);
1137 trk[itr].DtrID[indx] = jtr;
1139 trk[jtr].MomID =
trk[itr].ID;
1141 trk[jtr].PDGCode = 211;
1142 dtrNextGen.push_back(jtr);
1146 for (
unsigned short jj = 0; jj <
trk[jtr].TrjDir.size(); ++jj)
1147 trk[jtr].TrjDir[jj] = -
trk[jtr].TrjDir[jj];
1149 tmp =
trk[jtr].VtxIndex[0];
1150 trk[jtr].VtxIndex[0] =
trk[jtr].VtxIndex[1];
1151 trk[jtr].VtxIndex[1] =
tmp;
1157 if (dtrNextGen.size() == 0)
break;
1158 dtrGen = dtrNextGen;
1168 unsigned short ipf, itj;
1172 double local[3] = {0., 0., 0.};
1173 double world[3] = {0., 0., 0.};
1184 bool startsIn, endsIn;
1186 for (
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1188 if (
trk[itk].
ID < 0)
continue;
1193 for (ipf = 0; ipf <
pfpToTrkID.size(); ++ipf) {
1199 if (skipit)
continue;
1201 if (
trk[itk].TrjPos[0](0) < XLo ||
trk[itk].TrjPos[0](0) > XHi) startsIn =
false;
1202 if (
trk[itk].TrjPos[0](1) < YLo ||
trk[itk].TrjPos[0](1) > YHi) startsIn =
false;
1203 if (
trk[itk].TrjPos[0](2) < ZLo ||
trk[itk].TrjPos[0](2) > ZHi) startsIn =
false;
1205 if (startsIn)
continue;
1207 itj =
trk[itk].TrjPos.size() - 1;
1208 if (
trk[itk].TrjPos[itj](0) < XLo ||
trk[itk].TrjPos[itj](0) > XHi) endsIn =
false;
1209 if (
trk[itk].TrjPos[itj](1) < YLo ||
trk[itk].TrjPos[itj](1) > YHi) endsIn =
false;
1210 if (
trk[itk].TrjPos[itj](2) < ZLo ||
trk[itk].TrjPos[itj](2) > ZHi) endsIn =
false;
1212 if (endsIn)
continue;
1214 trk[itk].PDGCode = 13;
1220 for (
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1222 if (
trk[itk].PDGCode != 13)
continue;
1231 art::FindManyP<recob::Hit>
const& fmCluHits)
1234 unsigned short ivx, ii, ipl, icl, jj, jpl, jcl, kk, kpl, kcl;
1235 short idir, iend, jdir, jend, kdir, kend, ioend;
1237 for (ivx = 0; ivx <
vtx.size(); ++ivx) {
1240 for (ipl = 0; ipl <
nplanes; ++ipl) {
1242 for (icl = 0; icl <
clsChain[ipl].size(); ++icl) {
1243 if (
clsChain[ipl][icl].InTrack >= 0)
continue;
1244 for (iend = 0; iend < 2; ++iend) {
1245 if (
clsChain[ipl][icl].VtxIndex[iend] ==
vtx[ivx].EvtIndex)
vxCls[ipl].push_back(icl);
1252 myprt <<
"VtxMatch: Vertex ID " <<
vtx[ivx].EvtIndex <<
"\n";
1253 for (ipl = 0; ipl <
nplanes; ++ipl) {
1254 myprt <<
"ipl " << ipl <<
" cls";
1255 for (
unsigned short ii = 0; ii <
vxCls[ipl].size(); ++ii)
1256 myprt <<
" " <<
vxCls[ipl][ii];
1265 for (ipl = 0; ipl <
nplanes; ++ipl) {
1266 if (nplanes == 2 && ipl > 0)
continue;
1267 for (ii = 0; ii <
vxCls[ipl].size(); ++ii) {
1268 icl =
vxCls[ipl][ii];
1270 if (
clsChain[ipl][icl].InTrack >= 0)
continue;
1271 jpl = (ipl + 1) % nplanes;
1272 kpl = (jpl + 1) % nplanes;
1273 for (jj = 0; jj <
vxCls[jpl].size(); ++jj) {
1274 jcl =
vxCls[jpl][jj];
1275 if (
clsChain[jpl][jcl].InTrack >= 0)
continue;
1276 for (iend = 0; iend < 2; ++iend) {
1277 if (
clsChain[ipl][icl].VtxIndex[iend] !=
vtx[ivx].EvtIndex)
continue;
1279 idir =
clsChain[ipl][icl].Dir[iend];
1280 for (jend = 0; jend < 2; ++jend) {
1281 if (
clsChain[jpl][jcl].VtxIndex[jend] !=
vtx[ivx].EvtIndex)
continue;
1282 jdir =
clsChain[jpl][jcl].Dir[jend];
1283 if (idir != 0 && jdir != 0 && idir != jdir)
continue;
1288 match.
Cls[ipl] = icl;
1289 match.
End[ipl] = iend;
1290 match.
Cls[jpl] = jcl;
1291 match.
End[jpl] = jend;
1301 <<
"FillEndMatch2: Err " << match.
Err <<
" oErr " << match.
oErr;
1302 if (match.
Err + match.
oErr > 100)
continue;
1307 match.
Cls[kpl] = -1;
1311 <<
"VtxMatch: check " << ipl <<
":" << icl <<
":" << iend <<
" and " << jpl
1312 <<
":" << jcl <<
":" << jend <<
" for cluster in kpl " << kpl;
1314 for (kk = 0; kk <
vxCls[kpl].size(); ++kk) {
1315 kcl =
vxCls[kpl][kk];
1316 if (
clsChain[kpl][kcl].InTrack >= 0)
continue;
1317 for (kend = 0; kend < 2; ++kend) {
1318 kdir =
clsChain[kpl][kcl].Dir[kend];
1319 if (idir != 0 && kdir != 0 && idir != kdir)
continue;
1320 if (
clsChain[kpl][kcl].VtxIndex[kend] !=
vtx[ivx].EvtIndex)
continue;
1323 match.
Cls[kpl] = kcl;
1324 match.
End[kpl] = kend;
1329 if (match.
Chg[kpl] <= 0)
continue;
1330 if (match.
Err + match.
oErr > 100)
continue;
1338 if (gotkcl)
continue;
1342 unsigned short kbend = 0;
1344 mf::LogVerbatim(
"CCTM") <<
"VtxMatch: look for missed cluster chain in kpl";
1345 for (kcl = 0; kcl <
clsChain[kpl].size(); ++kcl) {
1346 if (
clsChain[kpl][kcl].InTrack >= 0)
continue;
1347 for (kend = 0; kend < 2; ++kend) {
1348 kdir =
clsChain[kpl][kcl].Dir[kend];
1349 if (idir != 0 && kdir != 0 && idir != kdir)
continue;
1350 if (
clsChain[kpl][kcl].VtxIndex[kend] >= 0)
continue;
1352 if (fabs(
clsChain[kpl][kcl].
X[kend] -
vtx[ivx].
X) > 5)
continue;
1354 if (fabs(
clsChain[kpl][kcl].X[1 - kend] -
clsChain[ipl][icl].X[ioend]) > 50)
1357 match.
Cls[kpl] = kcl;
1358 match.
End[kpl] = kend;
1361 totErr = match.
Err + match.
oErr;
1364 myprt <<
"VtxMatch: Chk missing cluster match ";
1365 for (
unsigned short ii = 0; ii <
nplanes; ++ii)
1366 myprt <<
" " << ii <<
":" << match.
Cls[ii] <<
":" << match.
End[ii];
1367 myprt <<
" Err " << match.
Err <<
"\n";
1369 if (totErr > 100)
continue;
1370 if (totErr < best) {
1379 match.
Cls[kpl] = kbst;
1380 match.
End[kpl] = kbend;
1384 clsChain[kpl][kbst].VtxIndex[kbend] = ivx;
1386 vxCls[kpl].push_back(kbst);
1390 match.
Cls[kpl] = -1;
1402 if (
matcomb.size() == 0)
continue;
1407 for (ipl = 0; ipl < 3; ++ipl)
1419 unsigned short ipl, icl,
end, ivx, oend;
1420 float best, dWire, dX;
1423 if (
vtx.size() == 0)
return;
1425 for (ipl = 0; ipl <
nplanes; ++ipl) {
1426 for (icl = 0; icl <
cls[ipl].size(); ++icl) {
1427 for (end = 0; end < 2; ++
end) {
1429 if (
cls[ipl][icl].VtxIndex[end] >= 0)
continue;
1434 for (ivx = 0; ivx <
vtx.size(); ++ivx) {
1436 if (
cls[ipl][icl].VtxIndex[oend] == ivx)
continue;
1446 if (dWire > 30 || dWire < -2)
continue;
1449 if (dWire < -30 || dWire > 2)
continue;
1452 dX = fabs(
cls[ipl][icl].
X[end] +
cls[ipl][icl].Slope[end] *
fWirePitch * dWire -
1462 cls[ipl][icl].VtxIndex[
end] = ibstvx;
1463 cls[ipl][icl].mVtxIndex[
end] = ibstvx;
1474 art::FindManyP<recob::Hit>
const& fmCluHits)
1476 unsigned short ipl, icl, icl1, icl2;
1477 float dw, dx, dWCut, dw1Max, dw2Max;
1478 float dA, dA2, dACut =
fMaxDAng, chgAsymCut;
1479 float dXCut, chgasym, mrgErr;
1482 bool gotprt =
false;
1483 for (ipl = 0; ipl <
nplanes; ++ipl) {
1485 for (icl1 = 0; icl1 <
cls[ipl].size() - 1; ++icl1) {
1487 if (
prt) gotprt =
true;
1489 dw1Max = 0.6 *
cls[ipl][icl1].Length;
1490 ls1 = (
cls[ipl][icl1].Length > 100 &&
1491 fabs(
cls[ipl][icl1].Angle[0] -
cls[ipl][icl1].Angle[1]) < 0.04);
1492 for (icl2 = icl1 + 1; icl2 <
cls[ipl].size(); ++icl2) {
1493 ls2 = (
cls[ipl][icl2].Length > 100 &&
1494 fabs(
cls[ipl][icl2].Angle[0] -
cls[ipl][icl2].Angle[1]) < 0.04);
1495 dw2Max = 0.6 *
cls[ipl][icl2].Length;
1498 if (dw2Max < dWCut) dWCut = dw2Max;
1500 if (dWCut > 100) dWCut = 100;
1501 if (dWCut < 2) dWCut = 2;
1507 <<
"MCC P:C:W icl1 " << ipl <<
":" << icl1 <<
":" <<
cls[ipl][icl1].Wire[1]
1508 <<
" vtx " <<
cls[ipl][icl1].VtxIndex[1] <<
" ls1 " << ls1 <<
" icl2 " << ipl <<
":" 1509 << icl2 <<
":" <<
cls[ipl][icl2].Wire[0] <<
" vtx " <<
cls[ipl][icl2].VtxIndex[0]
1510 <<
" ls2 " << ls2 <<
" dWCut " << dWCut;
1518 dA = fabs(
cls[ipl][icl1].Angle[1] -
cls[ipl][icl2].Angle[0]);
1521 dA2 = fabs(
cls[ipl][icl1].Angle[0] -
cls[ipl][icl2].Angle[1]);
1525 <<
" dA " << dA <<
" dA2 " << dA2 <<
" DACut " << dACut <<
" dXCut " << dXCut;
1527 if (dA2 < dA) dA = dA2;
1533 cls[ipl][icl2].X[0];
1534 unsigned short ivx =
cls[ipl][icl1].VtxIndex[1];
1535 if (
vtx[ivx].nClusInPln[ipl] == 2 && fabs(dx) < 1) {
1536 cls[ipl][icl1].VtxIndex[1] = -2;
1537 cls[ipl][icl2].VtxIndex[0] = -2;
1538 vtx[ivx].nClusInPln[ipl] = 0;
1544 if (
cls[ipl][icl1].VtxIndex[1] >= 0)
continue;
1545 if (
cls[ipl][icl2].VtxIndex[0] >= 0)
continue;
1548 if (
cls[ipl][icl2].Wire[0] -
cls[ipl][icl1].Wire[1] < 3 &&
1559 dx =
cls[ipl][icl2].X[0] -
cls[ipl][icl1].X[1];
1560 float dA3 =
std::abs(atan(dx / dw) -
cls[ipl][icl1].Angle[1]);
1562 if (dA3 > dA) dA = dA3;
1566 if (dA > dACut)
continue;
1570 <<
" rough dX " << fabs(
cls[ipl][icl1].
X[1] -
cls[ipl][icl2].
X[0]) <<
" cut = 20";
1573 if (fabs(
cls[ipl][icl1].X[1] -
cls[ipl][icl2].X[0]) > 20)
continue;
1581 chgasym = fabs(
cls[ipl][icl1].Charge[1] -
cls[ipl][icl2].Charge[0]);
1582 chgasym /=
cls[ipl][icl1].Charge[1] +
cls[ipl][icl2].Charge[0];
1584 if (chgasym > chgAsymCut)
continue;
1590 cls[ipl][icl2].X[0];
1595 cls[ipl][icl1].X[1];
1599 if (dA2 < 0.01 &&
abs(dx) > dXCut && dx < -1) {
1600 dx =
dXClTraj(fmCluHits, ipl, icl1, 1, icl2);
1606 <<
" X0 " <<
cls[ipl][icl1].X[1] <<
" slp " <<
cls[ipl][icl1].Slope[1] <<
" dw " 1607 << dw <<
" oX " <<
cls[ipl][icl2].X[0] <<
" dx " << dx <<
" cut " << dXCut;
1609 if (fabs(dx) > dXCut)
continue;
1612 float xerr = dx / dXCut;
1613 float aerr = dA / dACut;
1614 mrgErr = xerr * xerr + aerr * aerr;
1618 <<
"icl1 mrgErr " << mrgErr <<
" MergeError " <<
cls[ipl][icl1].MergeError[1]
1619 <<
" icl2 MergeError " <<
cls[ipl][icl2].MergeError[0];
1622 if (mrgErr >
cls[ipl][icl1].MergeError[1])
continue;
1623 if (mrgErr >
cls[ipl][icl2].MergeError[0])
continue;
1626 if (
cls[ipl][icl1].BrkIndex[1] >= 0) {
1627 unsigned short ocl =
cls[ipl][icl1].BrkIndex[1];
1629 if (
cls[ipl][ocl].BrkIndex[0] == icl1) {
1630 cls[ipl][ocl].BrkIndex[0] = -1;
1633 if (
cls[ipl][ocl].BrkIndex[1] == icl1) {
1634 cls[ipl][ocl].BrkIndex[1] = -1;
1638 cls[ipl][icl1].BrkIndex[1] = icl2;
1639 cls[ipl][icl1].MergeError[1] = mrgErr;
1642 if (
cls[ipl][icl2].BrkIndex[0] >= 0) {
1643 unsigned short ocl =
cls[ipl][icl2].BrkIndex[0];
1645 if (
cls[ipl][ocl].BrkIndex[0] == icl1) {
1646 cls[ipl][ocl].BrkIndex[0] = -1;
1649 if (
cls[ipl][ocl].BrkIndex[1] == icl1) {
1650 cls[ipl][ocl].BrkIndex[1] = -1;
1654 cls[ipl][icl2].BrkIndex[0] = icl1;
1655 cls[ipl][icl2].MergeError[0] = mrgErr;
1664 for (icl1 = 0; icl1 <
cls[ipl].size() - 1; ++icl1) {
1666 for (icl2 = icl1 + 1; icl2 <
cls[ipl].size(); ++icl2) {
1668 for (
unsigned short end = 0;
end < 2; ++
end) {
1670 if (
cls[ipl][icl1].BrkIndex[
end] >= 0)
continue;
1671 if (
cls[ipl][icl2].BrkIndex[
end] >= 0)
continue;
1673 if (fabs(
cls[ipl][icl1].Angle[
end]) < 1)
continue;
1675 if (fabs(
cls[ipl][icl2].Angle[end]) < 1)
continue;
1678 <<
"BrokenC: clusters " <<
cls[ipl][icl1].Wire[
end] <<
":" 1679 << (
int)
cls[ipl][icl1].Time[end] <<
" " <<
cls[ipl][icl2].
Wire[end] <<
":" 1680 << (
int)
cls[ipl][icl2].Time[
end] <<
" angles " <<
cls[ipl][icl1].Angle[
end] <<
" " 1681 <<
cls[ipl][icl2].Angle[
end] <<
" dWire " 1683 if (fabs(
cls[ipl][icl1].
Wire[end] -
cls[ipl][icl2].
Wire[end]) > 5)
continue;
1686 float dsl =
cls[ipl][icl2].Slope[
end] -
cls[ipl][icl1].Slope[
end];
1692 if (fabs(
cls[ipl][icl1].
Wire[end] - fvw) > 4)
continue;
1693 if (fabs(
cls[ipl][icl2].
Wire[end] - fvw) > 4)
continue;
1694 cls[ipl][icl1].BrkIndex[
end] = icl2;
1696 cls[ipl][icl1].MergeError[
end] = 1;
1697 cls[ipl][icl2].BrkIndex[
end] = icl1;
1698 cls[ipl][icl2].MergeError[
end] = 1;
1700 dx = fabs(
cls[ipl][icl1].
X[end] -
cls[ipl][icl2].
X[end]);
1703 <<
"BrokenC: icl1:W " << icl1 <<
":" <<
cls[ipl][icl1].Wire[
end] <<
" icl2:W " 1704 << icl2 <<
":" <<
cls[ipl][icl2].Wire[
end] <<
" end " << end <<
" dx " << dx;
1713 unsigned short end, mom, momBrkEnd, dtrBrkEnd, nit;
1716 std::vector<bool> gotcl(
cls[ipl].
size());
1717 for (icl = 0; icl <
cls[ipl].size(); ++icl)
1720 mf::LogVerbatim(
"CCTM") <<
"ipl " << ipl <<
" cls.size() " <<
cls[ipl].size() <<
"\n";
1722 std::vector<unsigned short> sCluster;
1723 std::vector<unsigned short> sOrder;
1724 for (icl = 0; icl <
cls[ipl].size(); ++icl) {
1727 if (gotcl[icl])
continue;
1729 if (
cls[ipl][icl].BrkIndex[0] >= 0 &&
cls[ipl][icl].BrkIndex[1] >= 0)
continue;
1730 for (end = 0; end < 2; ++
end) {
1731 if (
cls[ipl][icl].BrkIndex[end] < 0)
continue;
1737 sCluster.push_back(mom);
1738 if (momBrkEnd == 1) {
1740 sOrder.push_back(0);
1744 sOrder.push_back(1);
1746 dtr =
cls[ipl][icl].BrkIndex[
end];
1748 while (dtr >= 0 && dtr < (
short)
cls[ipl].
size() && nit <
cls[ipl].
size()) {
1750 for (dtrBrkEnd = 0; dtrBrkEnd < 2; ++dtrBrkEnd)
1751 if (
cls[ipl][dtr].BrkIndex[dtrBrkEnd] == mom)
break;
1752 if (dtrBrkEnd == 2) {
1758 sCluster.push_back(dtr);
1759 sOrder.push_back(dtrBrkEnd);
1766 momBrkEnd = 1 - dtrBrkEnd;
1768 dtr =
cls[ipl][mom].BrkIndex[momBrkEnd];
1770 if (dtrBrkEnd == 2)
continue;
1775 sCluster.push_back(icl);
1776 sOrder.push_back(0);
1779 if (sCluster.size() == 0) {
1780 mf::LogError(
"CCTM") <<
"MakeClusterChains error in plane " << ipl <<
" cluster " << icl;
1786 unsigned short jcl = sCluster[0];
1787 if (jcl >
cls[ipl].
size()) std::cout <<
"oops MCC\n";
1788 unsigned short oend;
1789 for (end = 0; end < 2; ++
end) {
1791 if (sOrder[0] > 0) oend = 1 -
end;
1794 ccp.
X[
end] =
cls[ipl][jcl].X[oend];
1806 for (
unsigned short ii = 1; ii < sCluster.size(); ++ii) {
1808 if (jcl >
cls[ipl].
size()) std::cout <<
"oops MCC\n";
1811 if (end > 1) std::cout <<
"oops2 MCC\n";
1814 ccp.
Wire[1] =
cls[ipl][jcl].Wire[oend];
1815 ccp.
Time[1] =
cls[ipl][jcl].Time[oend];
1816 ccp.
X[1] =
cls[ipl][jcl].X[oend];
1817 ccp.
Slope[1] =
cls[ipl][jcl].Slope[oend];
1818 ccp.
Angle[1] =
cls[ipl][jcl].Angle[oend];
1819 ccp.
Dir[1] =
cls[ipl][jcl].Dir[oend];
1821 ccp.
ChgNear[1] =
cls[ipl][jcl].ChgNear[oend];
1842 unsigned short brkCls;
1844 for (
unsigned short ccl = 0; ccl <
clsChain[ipl].size(); ++ccl) {
1845 for (
unsigned short end = 0; end < 2; ++
end) {
1846 if (
clsChain[ipl][ccl].mBrkIndex[end] < 0)
continue;
1850 for (
unsigned short ccl2 = 0; ccl2 <
clsChain[ipl].size(); ++ccl2) {
1851 if (ccl2 == ccl)
continue;
1852 if (std::find(
clsChain[ipl][ccl2].ClsIndex.begin(),
1853 clsChain[ipl][ccl2].ClsIndex.end(),
1854 brkCls) ==
clsChain[ipl][ccl2].ClsIndex.end())
1862 mf::LogError(
"CCTM") <<
"MCC: Cluster chain " << ccl <<
" end " << end
1863 <<
" Failed to find brkCls " << brkCls <<
" in plane " << ipl;
1878 unsigned short icl1,
1879 unsigned short end1,
1880 unsigned short icl2)
1883 float dw, dx, best = 999;
1884 std::vector<art::Ptr<recob::Hit>> clusterhits = fmCluHits.at(
cls[ipl][icl1].EvtIndex);
1885 for (
unsigned short hit = 0;
hit < clusterhits.size(); ++
hit) {
1886 dw = clusterhits[
hit]->WireID().Wire -
cls[ipl][icl1].Wire[end1];
1887 dx = fabs(
cls[ipl][icl1].Time[end1] + dw *
fWirePitch *
cls[ipl][icl1].Slope[end1] -
1888 clusterhits[
hit]->PeakTime());
1889 if (dx < best) best = dx;
1890 if (dx < 0.01)
break;
1898 art::FindManyP<recob::Hit>
const& fmCluHits,
1899 unsigned short imat,
1900 unsigned short procCode)
1906 if (imat >
matcomb.size() - 1) {
1912 unsigned short nhitinpl = 0;
1913 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl)
1916 mf::LogError(
"CCTM") <<
"StoreTrack: Not enough hits in each plane\n";
1920 mf::LogVerbatim(
"CCTM") <<
"In StoreTrack: matcomb " << imat <<
" cluster chains " 1925 std::array<std::vector<geo::WireID>, 3> trkWID;
1926 std::array<std::vector<double>, 3> trkX;
1927 std::array<std::vector<double>, 3> trkXErr;
1930 std::vector<TVector3> trkPos;
1931 std::vector<TVector3> trkDir;
1933 newtrk.
ID =
trk.size() + 1;
1934 newtrk.
Proc = procCode;
1943 newtrk.
EndInTPC = {{
false,
false}};
1944 newtrk.
GoodEnd = {{
false,
false}};
1948 unsigned short ipl, icl, iht;
1951 mf::LogVerbatim(
"CCTM") <<
"CCTM: Make traj for track " << newtrk.
ID <<
" procCode " 1952 << procCode <<
" nhits in planes " <<
trkHits[0].size() <<
" " 1956 trkWID[2].resize(0);
1958 trkXErr[2].resize(0);
1960 for (ipl = 0; ipl <
nplanes; ++ipl) {
1964 for (iht = 0; iht <
trkHits[ipl].size(); ++iht) {
1965 trkWID[ipl][iht] =
trkHits[ipl][iht]->WireID();
1972 if (trkPos.size() < 2) {
1973 mf::LogError(
"CCTM") <<
"StoreTrack: No trajectory points on failed track " << newtrk.
ID 1974 <<
" in StoreTrack: matcomb " << imat <<
" cluster chains " 1990 unsigned short end, nClose, indx, jndx;
1992 for (end = 0; end < 2; ++
end) {
1994 for (ipl = 0; ipl < nplanes - 1; ++ipl) {
1995 if (trkX[ipl].
size() == 0)
continue;
1996 for (
unsigned short jpl = ipl + 1; jpl <
nplanes; ++jpl) {
1997 if (trkX[jpl].
size() == 0)
continue;
2003 indx = trkXErr[ipl].size() - 1;
2004 jndx = trkXErr[jpl].size() - 1;
2006 xErr = 3 * (trkXErr[ipl][indx] + trkXErr[jpl][jndx]);
2007 if (
std::abs(trkX[ipl][indx] - trkX[jpl][jndx]) < xErr) ++nClose;
2010 if (nClose == nplanes) newtrk.
GoodEnd[
end] =
true;
2014 unsigned short ivx, itj, ccl;
2015 float dx, dy, dz, dr0, dr1;
2016 unsigned short attachEnd;
2017 for (end = 0; end < 2; ++
end) {
2020 if (end == 1 &&
matcomb[imat].oVtx >= 0) ivx =
matcomb[imat].oVtx;
2021 if (ivx == USHRT_MAX)
continue;
2024 dx =
vtx[ivx].X - newtrk.
TrjPos[itj](0);
2025 dy =
vtx[ivx].Y - newtrk.
TrjPos[itj](1);
2026 dz =
vtx[ivx].Z - newtrk.
TrjPos[itj](2);
2027 dr0 = dx * dx + dy * dy + dz * dz;
2028 itj = newtrk.
TrjPos.size() - 1;
2029 dx =
vtx[ivx].X - newtrk.
TrjPos[itj](0);
2030 dy =
vtx[ivx].Y - newtrk.
TrjPos[itj](1);
2031 dz =
vtx[ivx].Z - newtrk.
TrjPos[itj](2);
2032 dr1 = dx * dx + dy * dy + dz * dz;
2038 if (dr0 > 5)
return;
2042 if (dr1 > 5)
return;
2052 newtrk.
TrjDir[0] = dir.Unit();
2056 newtrk.
TrjDir[itj] = dir.Unit();
2062 <<
"StoreTrack: Trying to attach a vertex to both ends of a track. imat = " << imat;
2070 for (
unsigned short itj = 1; itj < newtrk.
TrjPos.size(); ++itj) {
2074 norm = sqrt(X * X + Y * Y + Z * Z);
2080 for (ipl = 0; ipl <
nplanes; ++ipl) {
2081 if (
matcomb[imat].Cls[ipl] < 0)
continue;
2083 if (ccl >
clsChain[ipl].
size()) std::cout <<
"oops StoreTrack\n";
2085 for (
unsigned short icc = 0; icc <
clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
2086 icl =
clsChain[ipl][ccl].ClsIndex[icc];
2087 if (icl >
cls[ipl].
size()) std::cout <<
"oops StoreTrack\n";
2088 cls[ipl][icl].InTrack = newtrk.
ID;
2089 if (
cls[ipl][icl].EvtIndex > fmCluHits.size() - 1) {
2090 std::cout <<
"ooops2 store track EvtIndex " <<
cls[ipl][icl].EvtIndex <<
" size " 2091 << fmCluHits.size() <<
" icl " << icl <<
"\n";
2100 trk.push_back(newtrk);
2106 art::FindManyP<recob::Hit>
const& fmCluHits)
2111 float kSlp, kAng,
kX, kWir, okWir;
2112 short idir, ioend, jdir, joend, kdir;
2127 std::array<float, 3> mchg;
2129 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
2130 for (
unsigned short icl = 0; icl <
clsChain[ipl].size(); ++icl) {
2131 if (
clsChain[ipl][icl].InTrack >= 0)
continue;
2134 unsigned short jpl = (ipl + 1) % nplanes;
2135 unsigned short kpl = (jpl + 1) % nplanes;
2136 for (
unsigned short jcl = 0; jcl <
clsChain[jpl].size(); ++jcl) {
2137 if (
clsChain[jpl][jcl].InTrack >= 0)
continue;
2141 mchg[0] =
clsChain[ipl][icl].TotChg;
2142 mchg[1] =
clsChain[jpl][jcl].TotChg;
2145 for (
unsigned short iend = 0; iend < 2; ++iend) {
2146 idir =
clsChain[ipl][icl].Dir[iend];
2147 for (
unsigned short jend = 0; jend < 2; ++jend) {
2148 jdir =
clsChain[jpl][jcl].Dir[jend];
2149 if (idir != 0 && jdir != 0 && idir != jdir)
continue;
2171 if (yp > tpcSizeY || yp < -tpcSizeY)
continue;
2172 if (zp < 0 || zp > tpcSizeZ)
continue;
2184 if (yp > tpcSizeY || yp < -tpcSizeY)
continue;
2185 if (zp < 0 || zp > tpcSizeZ)
continue;
2189 <<
"PlnMatch: chk i " << ipl <<
":" << icl <<
":" << iend <<
" idir " << idir
2190 <<
" X " <<
clsChain[ipl][icl].X[iend] <<
" j " << jpl <<
":" << jcl <<
":" 2191 << jend <<
" jdir " << jdir <<
" X " <<
clsChain[jpl][jcl].X[jend];
2195 <<
"PlnMatch: chk j " << ipl <<
":" << icl <<
":" << iend <<
" " << jpl <<
":" 2198 <<
clsChain[jpl][jcl].Slope[jend] <<
" kWir " << (
int)kWir <<
" okWir " 2204 ignoreSign = (fabs(kSlp) > 1.5);
2205 if (ignoreSign) kAng = fabs(kAng);
2207 bool gotkcl =
false;
2208 for (
unsigned short kcl = 0; kcl <
clsChain[kpl].size(); ++kcl) {
2209 if (
clsChain[kpl][kcl].InTrack >= 0)
continue;
2211 mchg[0] =
clsChain[ipl][icl].TotChg;
2212 mchg[1] =
clsChain[jpl][jcl].TotChg;
2213 mchg[2] =
clsChain[kpl][kcl].TotChg;
2215 for (
unsigned short kend = 0; kend < 2; ++kend) {
2216 kdir =
clsChain[kpl][kcl].Dir[kend];
2217 if (idir != 0 && kdir != 0 && idir != kdir)
continue;
2220 <<
" kcl " << kcl <<
" kend " << kend <<
" dx " 2226 <<
" kcl " << kcl <<
" kend " << kend <<
" dw " 2227 << (
clsChain[kpl][kcl].Wire[kend] - kWir) <<
" ignoreSign " << ignoreSign;
2228 if (fabs(
clsChain[kpl][kcl].
Wire[kend] - kWir) > dwcut)
continue;
2231 match.
Cls[ipl] = icl;
2232 match.
End[ipl] = iend;
2233 match.
Cls[jpl] = jcl;
2234 match.
End[jpl] = jend;
2235 match.
Cls[kpl] = kcl;
2236 match.
End[kpl] = kend;
2247 <<
":" << match.
End[kpl] <<
" oChg " << match.
Chg[kpl]
2248 <<
" mErr " << match.
Err <<
" oErr " << match.
oErr;
2249 if (match.
Chg[kpl] == 0)
continue;
2250 if (match.
Err > 10 || match.
oErr > 10)
continue;
2261 match.
Cls[ipl] = icl;
2262 match.
End[ipl] = iend;
2263 match.
Cls[jpl] = jcl;
2264 match.
End[jpl] = jend;
2265 match.
Cls[kpl] = -1;
2277 <<
" Tried 2-plane match" 2278 <<
" k " << kpl <<
":" << match.
Cls[kpl] <<
":" << match.
End[kpl] <<
" Chg " 2279 << match.
Chg[kpl] <<
" Err " << match.
Err <<
" match.oErr " << match.
oErr;
2280 if (match.
Chg[kpl] <= 0)
continue;
2281 if (match.
Err > 10 || match.
oErr > 10)
continue;
2290 if (
matcomb.size() == 0)
return;
2299 unsigned short nMatCl, nMiss;
2300 float toterr = match.
Err + match.
oErr;
2301 for (
unsigned int imat = 0; imat <
matcomb.size(); ++imat) {
2328 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
2329 if (match.
Cls[ipl] >= 0) {
2330 if (match.
Cls[ipl] ==
matcomb[imat].Cls[ipl] &&
2338 if (nMatCl == 2 && nMiss == 1)
return true;
2346 art::FindManyP<recob::Hit>
const& fmCluHits,
2347 unsigned short procCode)
2352 std::vector<CluLen> materr;
2353 unsigned int ii,
im;
2355 if (
matcomb.size() == 0)
return;
2358 for (ii = 0; ii <
matcomb.size(); ++ii) {
2361 materr.push_back(merr);
2363 std::sort(materr.begin(), materr.end(),
lessThan);
2367 myprt <<
"SortMatches\n";
2368 myprt <<
" ii im Vx Err dW dA dX oVx oErr odW odA odX Asym " 2370 for (ii = 0; ii < materr.size(); ++ii) {
2371 im = materr[ii].index;
2392 std::array<std::vector<bool>, 3> pclUsed;
2394 for (ipl = 0; ipl <
nplanes; ++ipl) {
2399 unsigned short matcombTotCl = 0;
2400 float matcombTotLen = 0;
2402 for (ii = 0; ii <
matcomb.size(); ++ii) {
2403 for (ipl = 0; ipl <
nplanes; ++ipl) {
2404 if (
matcomb[ii].Cls[ipl] < 0)
continue;
2407 matcombTotLen +=
clsChain[ipl][icl].Length;
2412 mf::LogVerbatim(
"CCTM") <<
"Number of clusters to match " << matcombTotCl <<
" total length " 2415 if (matcombTotLen <= 0) {
2416 mf::LogError(
"CCTM") <<
"SortMatches: bad matcomb total length " << matcombTotLen;
2421 std::vector<unsigned short> matIndex;
2423 std::vector<unsigned short> bestMatIndex;
2424 float totLen, totErr, bestTotErr = 9999;
2426 unsigned short jj, jm, nused, jcl;
2430 for (ii = 0; ii < materr.size(); ++ii) {
2431 im = materr[ii].index;
2434 if (
matcomb[im].Err > bestTotErr)
continue;
2437 for (ipl = 0; ipl <
nplanes; ++ipl) {
2441 if (
matcomb[im].Cls[ipl] < 0)
continue;
2443 pclUsed[ipl][icl] =
true;
2444 totLen +=
clsChain[ipl][icl].Length;
2449 matIndex.push_back(im);
2451 for (jj = 0; jj < materr.size(); ++jj) {
2452 if (jj == ii)
continue;
2453 jm = materr[jj].index;
2455 if (
matcomb[jm].Err > bestTotErr)
continue;
2458 for (ipl = 0; ipl <
nplanes; ++ipl) {
2459 if (
matcomb[jm].Cls[ipl] < 0)
continue;
2461 if (pclUsed[ipl][jcl]) ++nused;
2463 if (nused > 0)
break;
2464 totLen +=
clsChain[ipl][jcl].Length;
2467 if (nused != 0)
continue;
2470 matIndex.push_back(jm);
2472 for (ipl = 0; ipl <
nplanes; ++ipl) {
2473 if (
matcomb[jm].Cls[ipl] < 0)
continue;
2475 pclUsed[ipl][jcl] =
true;
2478 if (totLen == 0)
continue;
2480 for (ipl = 0; ipl <
nplanes; ++ipl) {
2481 for (
unsigned short indx = 0; indx < pclUsed[ipl].size(); ++indx)
2482 if (pclUsed[ipl][indx]) ++nused;
2484 if (totLen > matcombTotLen) std::cout <<
"Oops " << totLen <<
" " << matcombTotLen <<
"\n";
2486 fracLen = totLen / matcombTotLen;
2490 myprt <<
"match " << im <<
" totErr " << totErr <<
" nused " << nused <<
" fracLen " 2491 << fracLen <<
" totLen " << totLen <<
" mat: ";
2492 for (
unsigned short indx = 0; indx < matIndex.size(); ++indx)
2493 myprt <<
" " << matIndex[indx];
2496 if (totErr < bestTotErr) {
2497 bestTotErr = totErr;
2498 bestMatIndex = matIndex;
2499 if (nused == matcombTotCl)
break;
2502 myprt <<
"bestTotErr " << bestTotErr <<
" nused " << nused <<
" matcombTotCl " 2503 << matcombTotCl <<
" mat: ";
2504 for (
unsigned short indx = 0; indx < bestMatIndex.size(); ++indx)
2505 myprt <<
" " << bestMatIndex[indx];
2508 if (fracLen > 0.999)
break;
2512 if (bestTotErr > 9000)
return;
2514 for (ii = 0; ii < bestMatIndex.size(); ++ii) {
2515 im = bestMatIndex[ii];
2519 StoreTrack(detProp, fmCluHits, im, procCode);
2538 unsigned short ipl = 0;
2539 unsigned short jpl = 1;
2541 if (match.
Cls[0] < 0 || match.
Cls[1] < 0)
return;
2543 unsigned short icl = match.
Cls[ipl];
2544 unsigned short iend = match.
End[ipl];
2547 float miX =
clsChain[ipl][icl].X[iend];
2549 unsigned short oiend = 1 - iend;
2550 float oiX =
clsChain[ipl][icl].X[oiend];
2552 unsigned short jcl = match.
Cls[jpl];
2553 unsigned short jend = match.
End[jpl];
2556 float mjX =
clsChain[jpl][jcl].X[jend];
2558 unsigned short ojend = 1 - jend;
2559 float ojX =
clsChain[jpl][jcl].X[ojend];
2563 if (
clsChain[ipl][icl].VtxIndex[iend] >= 0 &&
2572 if (
clsChain[ipl][icl].VtxIndex[oiend] >= 0 &&
2573 clsChain[ipl][icl].VtxIndex[oiend] ==
clsChain[jpl][jcl].VtxIndex[ojend]) {
2582 chgAsym = fabs(match.
Chg[ipl] - match.
Chg[jpl]) / (match.
Chg[ipl] + match.
Chg[jpl]);
2583 if (chgAsym > 0.5)
return;
2588 float maxSlp = fabs(
clsChain[ipl][icl].Slope[iend]);
2589 if (fabs(
clsChain[jpl][jcl].Slope[jend]) > maxSlp)
2590 maxSlp = fabs(
clsChain[jpl][jcl].Slope[jend]);
2592 match.
dX = fabs(miX - mjX);
2593 match.
Err = chgAsym * match.
dX / sigmaX;
2596 maxSlp = fabs(
clsChain[ipl][icl].Slope[oiend]);
2597 if (fabs(
clsChain[jpl][jcl].Slope[ojend]) > maxSlp)
2598 maxSlp = fabs(
clsChain[jpl][jcl].Slope[ojend]);
2600 match.
odX = fabs(oiX - ojX);
2601 match.
oErr = chgAsym * match.
odX / sigmaX;
2604 mf::LogVerbatim(
"CCTM") <<
"FEM2: m " << ipl <<
":" << icl <<
":" << iend <<
" miX " << miX
2605 <<
" - " << jpl <<
":" << jcl <<
":" << jend <<
" mjX " << mjX
2606 <<
" match.dX " << match.
dX <<
" match.Err " << match.
Err 2607 <<
" chgAsym " << chgAsym <<
" o " 2608 <<
" oiX " << oiX <<
" ojX " << ojX <<
" match.odX " << match.
odX 2609 <<
" match.oErr " << match.
oErr <<
"\n";
2629 std::array<short, 3> mVtx;
2630 std::array<short, 3> oVtx;
2631 std::array<float, 3> oWir;
2632 std::array<float, 3> oSlp;
2633 std::array<float, 3> oAng;
2634 std::array<float, 3> oX;
2636 std::array<float, 3> mChg;
2638 unsigned short ii, ipl, iend, jpl, jend, kpl, kend, oend;
2639 short icl, jcl, kcl;
2641 for (ipl = 0; ipl < 3; ++ipl) {
2665 for (ipl = 0; ipl <
nplanes; ++ipl) {
2666 myprt <<
" " << ipl <<
":" << match.
Cls[ipl] <<
":" << match.
End[ipl];
2670 short missingPlane = -1;
2671 unsigned short nClInPln = 0;
2674 unsigned short novxmat = 0;
2676 unsigned short nvxmat = 0;
2677 unsigned short nShortCl = 0;
2679 for (ipl = 0; ipl <
nplanes; ++ipl) {
2680 if (match.
Cls[ipl] < 0) {
2685 icl = match.
Cls[ipl];
2687 mChg[ipl] =
clsChain[ipl][icl].TotChg;
2688 iend = match.
End[ipl];
2689 mVtx[ipl] =
clsChain[ipl][icl].VtxIndex[iend];
2691 if (mVtx[ipl] >= 0) {
2692 if (aVtx < 0) aVtx = mVtx[ipl];
2693 if (mVtx[ipl] == aVtx) ++nvxmat;
2696 mf::LogVerbatim(
"CCTM") <<
"FEM: m " << ipl <<
":" << icl <<
":" << iend <<
" Vtx " 2697 << mVtx[ipl] <<
" Wir " <<
clsChain[ipl][icl].Wire[iend]
2699 <<
clsChain[ipl][icl].Slope[iend] << std::fixed
2703 oWir[ipl] =
clsChain[ipl][icl].Wire[oend];
2704 oAng[ipl] =
clsChain[ipl][icl].Angle[oend];
2705 oSlp[ipl] =
clsChain[ipl][icl].Slope[oend];
2706 oX[ipl] =
clsChain[ipl][icl].X[oend];
2707 oVtx[ipl] =
clsChain[ipl][icl].VtxIndex[oend];
2708 if (oVtx[ipl] >= 0) {
2709 if (aoVtx < 0) aoVtx = oVtx[ipl];
2710 if (oVtx[ipl] == aoVtx) ++novxmat;
2714 mf::LogVerbatim(
"CCTM") <<
" o " << ipl <<
":" << icl <<
":" << oend <<
" oVtx " 2715 << oVtx[ipl] <<
" oWir " << oWir[ipl] << std::fixed
2722 bool isShort = (nShortCl > 1);
2730 mf::LogVerbatim(
"CCTM") <<
"FEM: Vtx m " << aVtx <<
" count " << nvxmat <<
" o " << aoVtx
2731 <<
" count " << novxmat <<
" missingPlane " << missingPlane
2732 <<
" nClInPln " << nClInPln;
2735 if (nvxmat == 3 && novxmat == 3) {
2746 float ovxFactor = 1;
2747 if (nClInPln == 3) {
2780 float kSlp, okSlp, kAng, okAng, okX,
kX, kTim, okTim;
2782 if (nClInPln == 3) {
2794 else if (kpl == 1) {
2803 iend = match.
End[ipl];
2804 jend = match.
End[jpl];
2805 icl = match.
Cls[ipl];
2806 jcl = match.
Cls[jpl];
2808 kcl = match.
Cls[kpl];
2809 kend = match.
End[kpl];
2814 okAng = atan(okSlp);
2817 bool ignoreSign = (fabs(okSlp) > 10);
2818 if (ignoreSign) okAng = fabs(okAng);
2819 if (match.
oVtx >= 0) {
2828 okX = 0.5 * (oX[ipl] + oX[jpl]);
2833 <<
" kpl " << kpl <<
" okSlp " << okSlp <<
" okAng " << okAng
2834 <<
" okWir " << (
int)okWir <<
" okX " << okX;
2841 if (ignoreSign) kAng = fabs(kAng);
2842 if (match.
Vtx >= 0) {
2843 if (
vtx.size() == 0 || (
unsigned int)match.
Vtx >
vtx.size() - 1) {
2844 mf::LogError(
"CCTM") <<
"FEM: Bad match.Vtx " << match.
Vtx <<
" vtx size " <<
vtx.size();
2867 <<
" kpl " << kpl <<
" kSlp " << kSlp <<
" kAng " << kAng <<
" kX " 2874 match.
Cls[kpl] = kcl;
2875 match.
End[kpl] = kend;
2877 mChg[kpl] =
clsChain[kpl][kcl].TotChg;
2879 oWir[kpl] =
clsChain[kpl][kcl].Wire[oend];
2880 oX[kpl] =
clsChain[kpl][kcl].X[oend];
2881 oAng[kpl] =
clsChain[kpl][kcl].Angle[oend];
2882 oSlp[kpl] =
clsChain[kpl][kcl].Slope[oend];
2887 if (nClInPln == 2 && fabs(okWir - kWir) > 3)
return;
2893 if (nClInPln < 3 && mChg[missingPlane] <= 0) {
2894 if (missingPlane != kpl)
2895 mf::LogError(
"CCTM") <<
"FEM bad missingPlane " << missingPlane <<
" " << kpl <<
"\n";
2896 mChg[kpl] =
ChargeNear(kpl, (
unsigned short)kWir, kTim, (
unsigned short)okWir, okTim);
2897 match.
Chg[kpl] = mChg[kpl];
2899 mf::LogVerbatim(
"CCTM") <<
"FEM: Missing cluster in " << kpl <<
" ChargeNear " << (
int)kWir
2900 <<
":" << (
int)kTim <<
" " << (
int)okWir <<
":" << (
int)okTim
2901 <<
" chg " << mChg[kpl];
2902 if (mChg[kpl] <= 0)
return;
2907 if (chgAsym > 0.5)
return;
2912 float sigmaX, sigmaA;
2918 bool allPlnVtxMatch =
false;
2919 if (nClInPln == 3) {
2920 unsigned short nmvtx = 0;
2921 for (ii = 0; ii <
nplanes; ++ii) {
2922 if (mVtx[ii] >= 0) {
2923 if (aVtx < 0) aVtx = mVtx[ii];
2928 if (nmvtx) allPlnVtxMatch =
true;
2938 if (nClInPln == 3) {
2939 kcl = match.
Cls[kpl];
2940 kend = match.
End[kpl];
2941 dw = kWir -
clsChain[kpl][kcl].Wire[kend];
2943 if (fabs(match.
dWir) > 100)
return;
2944 if (match.
Vtx >= 0) { match.
dX = kX -
clsChain[kpl][kcl].X[kend]; }
2952 if (ignoreSign) { match.
dAng = kAng - fabs(
clsChain[kpl][kcl].Angle[kend]); }
2957 da = fabs(match.
dAng) / sigmaA;
2958 dx = fabs(match.
dX) / sigmaX;
2959 if (allPlnVtxMatch) {
2961 match.
Err = vxFactor * chgAsym * da / 3;
2967 match.
Err = vxFactor * chgAsym * sqrt(dx * dx + da * da + dw * dw) / 9;
2977 match.
Err = 3 + vxFactor * chgAsym * fabs(match.
dX) / sigmaX;
2982 if (nClInPln == 3) {
2984 dw = okWir - oWir[kpl];
2986 if (match.
oVtx >= 0) { match.
odX = okX - oX[kpl]; }
2995 if (ignoreSign) { match.
odAng = okAng - fabs(oAng[kpl]); }
2997 match.
odAng = okAng - oAng[kpl];
3000 da = match.
odAng / sigmaA;
3001 dx = fabs(match.
odX) / sigmaX;
3005 match.
oErr = ovxFactor * chgAsym * sqrt(dx * dx + da * da + dw * dw) / 9;
3010 match.
odX = (oX[ipl] - oX[jpl]) / sigmaX;
3011 match.
oErr = 3 + ovxFactor * chgAsym * fabs(match.
odX);
3020 unsigned short& kend,
3028 unsigned short okend;
3031 if (kcl >= 0)
return false;
3034 float kslp = fabs((okX - kX) / (okWir - kWir));
3035 if (kslp > 20) kslp = 20;
3038 unsigned short nfound = 0;
3039 unsigned short foundCl = 0, foundEnd = 0;
3040 for (
unsigned short ccl = 0; ccl <
clsChain[kpl].size(); ++ccl) {
3041 if (
clsChain[kpl][ccl].InTrack >= 0)
continue;
3043 for (
unsigned short end = 0;
end < 2; ++
end) {
3046 if (fabs(
clsChain[kpl][ccl].
Wire[okend] - okWir) > 4)
continue;
3049 fabs(
clsChain[kpl][ccl].
X[okend] - okX) > dxcut)
3056 if (nfound == 0)
return false;
3058 mf::LogVerbatim(
"CCTM") <<
"FindMissingCluster: Found too many matches. Write some code " 3074 float big = 0, small = 1.E9;
3075 for (
unsigned short ii = 0; ii < 3; ++ii) {
3076 if (mChg[ii] < small) small = mChg[ii];
3077 if (mChg[ii] > big) big = mChg[ii];
3080 return (big - small) / (big + small);
3091 for (ipl = 0; ipl < 3; ++ipl)
3094 if (imat >
matcomb.size())
return;
3096 unsigned short indx;
3097 std::vector<art::Ptr<recob::Hit>> clusterhits;
3098 unsigned short icc, ccl, icl, ecl, iht, ii;
3099 short endOrder, fillOrder;
3102 mf::LogVerbatim(
"CCTM") <<
"In FillTrkHits: matcomb " << imat <<
" cluster chains " 3106 for (ipl = 0; ipl <
nplanes; ++ipl) {
3107 if (
matcomb[imat].Cls[ipl] < 0)
continue;
3111 endOrder = 1 - 2 *
matcomb[imat].End[ipl];
3116 for (ii = 0; ii <
clsChain[ipl][ccl].Order.size(); ++ii)
3120 mf::LogError(
"CCTM") <<
"Bad cluster chain index " << ccl <<
" in plane " << ipl;
3124 for (icc = 0; icc <
clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
3125 icl =
clsChain[ipl][ccl].ClsIndex[icc];
3126 if (icl > fmCluHits.size() - 1) {
3127 std::cout <<
"oops in FTH " << icl <<
" clsChain size " <<
clsChain[ipl].size() <<
"\n";
3130 ecl =
cls[ipl][icl].EvtIndex;
3131 if (ecl > fmCluHits.size() - 1) {
3132 std::cout <<
"FTH bad EvtIndex " << ecl <<
" fmCluHits size " << fmCluHits.size() <<
"\n";
3135 clusterhits = fmCluHits.at(ecl);
3136 if (clusterhits.size() == 0) {
3137 std::cout <<
"FTH no cluster hits for EvtIndex " <<
cls[ipl][icl].EvtIndex <<
"\n";
3141 trkHits[ipl].resize(indx + clusterhits.size());
3143 fillOrder = 1 - 2 *
clsChain[ipl][ccl].Order[icc];
3145 if (fillOrder == 1) {
3147 for (iht = 0; iht < clusterhits.size(); ++iht) {
3148 if (indx + iht >
trkHits[ipl].
size() - 1) std::cout <<
"FTH oops3\n";
3149 trkHits[ipl][indx + iht] = clusterhits[iht];
3155 for (ii = 0; ii < clusterhits.size(); ++ii) {
3156 iht = clusterhits.size() - 1 - ii;
3157 if (indx + ii >
trkHits[ipl].
size() - 1) std::cout <<
"FTH oops4\n";
3158 trkHits[ipl][indx + ii] = clusterhits[iht];
3165 <<
" w " <<
trkHits[ipl][0]->WireID().Wire <<
":" 3166 << (
int)
trkHits[ipl][0]->PeakTime() <<
" last p " 3167 <<
trkHits[ipl][ii]->WireID().Plane <<
" w " 3168 <<
trkHits[ipl][ii]->WireID().Wire <<
":" 3183 myprt <<
"********* PrintTracks \n";
3184 myprt <<
"vtx Index X Y Z\n";
3185 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
3187 myprt << std::fixed;
3191 if (
vtx[ivx].Neutrino) myprt <<
" Neutrino vertex";
3195 myprt <<
">>>>>>>>>> Tracks \n";
3196 myprt <<
"trk ID Proc nht nTrj sX sY sZ eX eY eZ sVx eVx sGd eGd " 3197 "ChgOrd dirZ Mom PDG ClsIndices\n";
3198 for (
unsigned short itr = 0; itr <
trk.size(); ++itr) {
3201 unsigned short nht = 0;
3202 for (
unsigned short ii = 0; ii < 3; ++ii)
3203 nht +=
trk[itr].TrkHits[ii].
size();
3206 myprt << std::fixed;
3210 unsigned short itj =
trk[itr].TrjPos.size() - 1;
3221 for (
unsigned short ii = 0; ii <
trk[itr].ClsEvtIndices.size(); ++ii)
3222 myprt <<
" " <<
trk[itr].ClsEvtIndices[ii];
3233 unsigned short iTime;
3235 myprt <<
"******* PrintClusters ********* Num_Clusters_in Wire:Time\n";
3236 myprt <<
"vtx Index X Y Z Pln0 Pln1 Pln2 Pln0 Pln1 Pln2\n";
3237 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
3239 myprt << std::fixed;
3247 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
3256 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
3257 myprt <<
">>>>>>>>>> Cluster chains in Plane " << ipl <<
"\n";
3258 myprt <<
"ipl ccl Len Chg W0:T0 Ang0 Dir0 Vx0 mBk0 W1:T1 Ang1 Dir1 Vx1 " 3259 " mBk1 InTk cls:Order \n";
3260 for (
unsigned short ccl = 0; ccl <
clsChain[ipl].size(); ++ccl) {
3265 for (
unsigned short end = 0;
end < 2; ++
end) {
3269 if (iTime < 10) { myprt <<
" "; }
3270 else if (iTime < 100) {
3273 else if (iTime < 1000)
3285 for (
unsigned short ii = 0; ii <
clsChain[ipl][ccl].ClsIndex.size(); ++ii)
3286 myprt <<
" " <<
clsChain[ipl][ccl].ClsIndex[ii] <<
":" <<
clsChain[ipl][ccl].Order[ii];
3290 myprt <<
">>>>>>>>>> Clusters in Plane " << ipl <<
"\n";
3291 myprt <<
"ipl icl Evt Len Chg W0:T0 Ang0 Dir0 Vx0 CN0 W1:T1 Ang1 " 3292 "Dir1 Vx1 CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
3293 for (
unsigned short icl = 0; icl <
cls[ipl].size(); ++icl) {
3299 for (
unsigned short end = 0;
end < 2; ++
end) {
3300 iTime =
cls[ipl][icl].Time[
end];
3302 if (iTime < 10) { myprt <<
" "; }
3303 else if (iTime < 100) {
3306 else if (iTime < 1000)
3312 <<
cls[ipl][icl].ChgNear[
end];
3314 myprt << std::fixed;
3318 <<
cls[ipl][icl].MergeError[0];
3321 <<
cls[ipl][icl].MergeError[1];
3332 float slp = fabs(slope);
3333 if (slp > 10.) slp = 30.;
3335 return 1 + 0.05 * slp * slp;
3341 unsigned short wire1,
3343 unsigned short wire2,
3350 unsigned short w1 = wire1;
3351 unsigned short w2 = wire2;
3355 if (w1 == w2) { slp = 0; }
3363 slp = (t2 -
t1) / (w2 - w1);
3366 unsigned short wire;
3374 if (wire < w1)
continue;
3375 if (wire > w2)
continue;
3376 prtime = t1 + (wire - w1) * slp;
3378 if (prtime >
allhits[
hit]->PeakTimePlusRMS(3))
continue;
3379 if (prtime <
allhits[
hit]->PeakTimeMinusRMS(3))
continue;
3394 for (ipl = 0; ipl < 3; ++ipl) {
3404 unsigned short oldipl = 0;
3417 mf::LogError(
"CCTM") <<
"Hits are not in increasing-plane order\n";
3430 for (ipl = 0; ipl <
nplanes; ++ipl) {
3432 mf::LogError(
"CCTM") <<
"Invalid first/last wire in plane " << ipl;
3439 for (ipl = 0; ipl <
nplanes; ++ipl)
3448 unsigned int indx, thisWire, thisHit, lastFirstHit;
3450 for (ipl = 0; ipl <
nplanes; ++ipl) {
3455 for (wire = 0; wire <
nwires; ++wire)
3456 WireHitRange[ipl][wire] = std::make_pair(sflag, sflag);
3459 for (wire = 0; wire <
nwires; ++wire) {
3473 indx =
lastWire[ipl] - firstWire[ipl];
3474 int tmp1 = lastFirstHit;
3478 lastFirstHit = thisHit;
3480 else if (thisWire <
lastWire[ipl]) {
3481 mf::LogError(
"CCTM") <<
"Hit not in proper order in plane " << ipl;
3487 indx =
lastWire[ipl] - firstWire[ipl];
3488 int tmp1 = lastFirstHit;
3497 for (ipl = 0; ipl <
nplanes; ++ipl) {
3500 if (
firstHit[ipl] < INT_MAX)
continue;
3501 if (
lastHit[ipl] > 0)
continue;
3502 std::cout <<
"FWHR problem\n";
3506 unsigned int nht = 0;
3507 std::vector<bool> hchk(
allhits.size());
3508 for (
unsigned int ii = 0; ii < hchk.size(); ++ii)
3510 for (ipl = 0; ipl <
nplanes; ++ipl) {
3513 if (indx > lastWire[ipl]) {
3514 std::cout <<
"FWHR bad index " << indx <<
"\n";
3521 for (
unsigned int hit = firhit;
hit < lashit; ++
hit) {
3524 std::cout <<
"FWHR: Bad hchk " <<
hit <<
" size " <<
allhits.size() <<
"\n";
3529 std::cout <<
"FWHR bad plane " <<
allhits[
hit]->WireID().Plane <<
" " << ipl
3530 <<
" or wire " <<
allhits[
hit]->WireID().Wire <<
" " <<
w <<
"\n";
3538 std::cout <<
"FWHR hit count problem " << nht <<
" " <<
allhits.size() <<
"\n";
3539 for (
unsigned int ii = 0; ii < hchk.size(); ++ii)
3541 std::cout <<
" " << ii <<
" " <<
allhits[ii]->WireID().Plane <<
" " geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
std::string fHitModuleLabel
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
float Length(const PFPStruct &pfp)
std::array< short, 2 > VtxIndex
std::vector< MatchPars > matcomb
float ChargeNear(unsigned short ipl, unsigned short wire1, float time1, unsigned short wire2, float time2)
art::ServiceHandle< geo::Geometry const > geom
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
std::string fVertexModuleLabel
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
std::array< float, 3 > ChgNorm
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
std::vector< float > fChgAsymFactor
std::array< unsigned short, 3 > End
unsigned int Nplanes() const
Number of planes in this tpc.
std::array< unsigned int, 3 > firstWire
void FillEndMatch2(detinfo::DetectorPropertiesData const &detProp, MatchPars &match)
Planes which measure X direction.
Geometry information for a single TPC.
void SortMatches(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
std::vector< art::Ptr< recob::Hit > > allhits
std::array< short, 2 > Dir
TrackTrajectory::Flags_t Flags_t
void StoreTrack(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat, unsigned short procCode)
double ThirdPlaneSlope(geo::PlaneID const &pid1, double slope1, geo::PlaneID const &pid2, double slope2, geo::PlaneID const &output_plane) const
Returns the slope on the third plane, given it in the other two.
float StartWire() const
Returns the wire coordinate of the start of the cluster.
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
Plane(const Point_t &planePos, const Vector_t &planeDir)
Constructor from reference position on the plane and direction orthogonal to the plane.
std::string fClusterModuleLabel
TrackTrajectoryAlg fTrackTrajectoryAlg
std::array< float, 2 > ChgNear
void FillWireHitRange(geo::TPCID inTPCID)
Set of hits with a 2D structure.
std::array< short, 2 > BrkIndex
float EndTick() const
Returns the tick coordinate of the end of the cluster.
std::vector< unsigned short > pfpToTrkID
std::vector< TVector3 > TrjPos
std::vector< TrkPar > trk
float dXClTraj(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short ipl, unsigned short icl1, unsigned short end1, unsigned short icl2)
void PlnMatch(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
bool FindMissingCluster(unsigned short kpl, short &kcl, unsigned short &kend, float kWir, float kX, float okWir, float okX)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< float > fAngleMatchErr
std::array< float, 2 > ChgNear
std::array< std::vector< clPar >, 3 > cls
void FitVertices(detinfo::DetectorPropertiesData const &detProp)
float StartAngle() const
Returns the starting angle of the cluster.
Definition of vertex object for LArSoft.
std::array< float, 2 > Slope
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::array< bool, 2 > EndInTPC
Q_EXPORT QTSManip setprecision(int p)
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.
art framework interface to geometry description
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
std::array< std::vector< ClsChainPar >, 3 > clsChain
float EndCharge() const
Returns the charge on the last wire of the cluster.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
bool DupMatch(MatchPars &match)
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
void FillTrkHits(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat)
#define DEFINE_ART_MODULE(klass)
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
A trajectory in space reconstructed from hits.
std::vector< float > fMatchMinLen
void FillEndMatch(detinfo::DetectorPropertiesData const &detProp, MatchPars &match)
std::vector< unsigned short > Order
float AngleFactor(float slope)
std::array< short, 2 > VtxIndex
std::array< short, 2 > mVtxIndex
std::vector< short > DtrID
double ConvertXToTicks(double X, int p, int t, int c) const
unsigned int NTPC() const
Number of TPCs in this cryostat.
std::vector< vtxPar > vtx
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
std::array< float, 2 > MergeError
void produce(art::Event &evt) override
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
std::array< bool, 2 > GoodEnd
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
std::array< float, 2 > Wire
static int max(int a, int b)
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
void TrackTrajectory(std::array< std::vector< geo::WireID >, 3 > trkWID, std::array< std::vector< double >, 3 > trkX, std::array< std::vector< double >, 3 > trkXErr, std::vector< TVector3 > &TrajPos, std::vector< TVector3 > &TrajDir)
std::array< unsigned int, 3 > firstHit
std::array< float, 2 > Charge
std::vector< unsigned short > ClsIndex
void MakeClusterChains(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
auto norm(Vector const &v)
Return norm of the specified vector.
std::vector< unsigned short > ClsEvtIndices
Detector simulation of raw signals on wires.
std::array< unsigned int, 3 > lastWire
Q_EXPORT QTSManip setw(int w)
Class defining a plane for tracking. It provides various functionalities to convert track parameters ...
double ConvertTicksToX(double ticks, int p, int t, int c) const
bool greaterThan(CluLen c1, CluLen c2)
Declaration of signal hit object.
void VertexFit(std::vector< std::vector< geo::WireID >> const &hitWID, std::vector< std::vector< double >> const &hitX, std::vector< std::vector< double >> const &hitXErr, TVector3 &VtxPos, TVector3 &VtxPosErr, std::vector< TVector3 > &TrkDir, std::vector< TVector3 > &TrkDirErr, float &ChiDOF) const
Hierarchical representation of particle flow.
std::array< float, 2 > Time
float StartCharge() const
Returns the charge on the first wire of the cluster.
std::array< float, 2 > Slope
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc'th TPC in the cryostat.
std::array< short, 2 > VtxIndex
void PrintClusters(detinfo::DetectorPropertiesData const &detProp) const
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
std::array< unsigned int, 3 > lastHit
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Provides recob::Track data product.
bool lessThan(CluLen c1, CluLen c2)
std::array< short, 2 > Dir
vector< vector< double > > clear
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
std::vector< TVector3 > TrjDir
std::array< float, 2 > Angle
void FillChgNear(detinfo::DetectorPropertiesData const &detProp)
std::vector< bool > fMakeAlgTracks
std::vector< short > fMatchAlgs
std::vector< float > fXMatchErr
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
float EndAngle() const
Returns the ending angle of the cluster.
recob::tracking::Plane Plane
float ChargeAsym(std::array< float, 3 > &mChg)
std::array< float, 2 > Wire
std::array< short, 3 > Cls
void VtxMatch(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
float StartTick() const
Returns the tick coordinate of the start of the cluster.
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > TrkHits
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
VertexFitAlg fVertexFitAlg
std::array< short, 2 > Time
std::array< float, 3 > Chg
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
std::array< float, 2 > Angle
cet::coded_exception< error, detail::translate > exception
Encapsulate the construction of a single detector plane.
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
std::array< std::vector< unsigned short >, 3 > vxCls
std::array< unsigned short, 3 > nClusInPln
unsigned short fNVtxTrkHitsFit
float Integral() const
Returns the total charge of the cluster from hit shape.
float EndWire() const
Returns the wire coordinate of the end of the cluster.
std::array< short, 2 > mBrkIndex