20 #include "art/Framework/Core/EDProducer.h"
21 #include "art/Framework/Core/ModuleMacros.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Principal/Handle.h"
24 #include "art/Framework/Services/Registry/ServiceHandle.h"
25 #include "canvas/Persistency/Common/Ptr.h"
26 #include "fhiclcpp/ParameterSet.h"
27 #include "messagefacility/MessageLogger/MessageLogger.h"
51 return (c1.length > c2.length);
56 return (c1.length < c2.length);
73 art::ServiceHandle<geo::Geometry const>
geom;
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;
243 art::FindManyP<recob::Hit>
const& fmCluHits);
244 float dXClTraj(art::FindManyP<recob::Hit>
const& fmCluHits,
248 unsigned short icl2);
257 art::FindManyP<recob::Hit>
const& fmCluHits);
260 art::FindManyP<recob::Hit>
const& fmCluHits);
262 void AngMatch(art::FindManyP<recob::Hit>
const& fmCluHits);
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);
305 unsigned short wire1,
307 unsigned short wire2,
318 fHitModuleLabel = pset.get<std::string>(
"HitModuleLabel");
319 fClusterModuleLabel = pset.get<std::string>(
"ClusterModuleLabel");
320 fVertexModuleLabel = pset.get<std::string>(
"VertexModuleLabel");
322 fMatchAlgs = pset.get<std::vector<short>>(
"MatchAlgs");
323 fXMatchErr = pset.get<std::vector<float>>(
"XMatchErr");
324 fAngleMatchErr = pset.get<std::vector<float>>(
"AngleMatchErr");
325 fChgAsymFactor = pset.get<std::vector<float>>(
"ChgAsymFactor");
326 fMatchMinLen = pset.get<std::vector<float>>(
"MatchMinLen");
327 fMakeAlgTracks = pset.get<std::vector<bool>>(
"MakeAlgTracks");
329 fMaxDAng = pset.get<
float>(
"MaxDAng");
330 fChainMaxdX = pset.get<
float>(
"ChainMaxdX");
331 fChainVtxAng = pset.get<
float>(
"ChainVtxAng");
332 fMergeChgAsym = pset.get<
float>(
"MergeChgAsym");
334 fFiducialCut = pset.get<
float>(
"FiducialCut");
335 fDeltaRayCut = pset.get<
float>(
"DeltaRayCut");
337 fMakePFPs = pset.get<
bool>(
"MakePFPs");
339 fNVtxTrkHitsFit = pset.get<
unsigned short>(
"NVtxTrkHitsFit");
340 fHitFitErrFac = pset.get<
float>(
"HitFitErrFac");
342 fuBCode = pset.get<
bool>(
"uBCode");
344 fDebugAlg = pset.get<
short>(
"DebugAlg");
345 fDebugPlane = pset.get<
short>(
"DebugPlane");
346 fDebugCluster = pset.get<
short>(
"DebugCluster");
347 fPrintAllClusters = pset.get<
bool>(
"PrintAllClusters");
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>>();
398 art::Handle<std::vector<recob::Hit>> allhitsListHandle;
400 art::Handle<std::vector<recob::Cluster>> clusterListHandle;
401 std::vector<art::Ptr<recob::Cluster>> clusterlist;
403 art::Handle<std::vector<recob::Vertex>> VtxListHandle;
404 std::vector<art::Ptr<recob::Vertex>> vtxlist;
409 art::fill_ptr_vector(
allhits, allhitsListHandle);
412 if (evt.getByLabel(fClusterModuleLabel, clusterListHandle))
413 art::fill_ptr_vector(clusterlist, clusterListHandle);
414 if (clusterlist.size() == 0)
return;
416 art::FindManyP<recob::Hit> fmCluHits(clusterListHandle, evt, fClusterModuleLabel);
419 if (evt.getByLabel(fVertexModuleLabel, VtxListHandle))
420 art::fill_ptr_vector(vtxlist, VtxListHandle);
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};
445 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
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;
548 clstr.
TotChg *= clstr.
Length / (float)clusterhits.size();
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];
576 throw cet::exception(
"CCTM")
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;
602 prt = (fDebugAlg == 1);
606 else if (fMatchAlgs[
algIndex] == 2) {
607 prt = (fDebugAlg == 2);
623 for (
unsigned short ipf = 0; ipf <
pfpToTrkID.size(); ++ipf) {
626 if (tID >
trk.size() + 1) {
627 mf::LogWarning(
"CCTM") <<
"Bad track ID";
632 mf::LogVerbatim(
"CCTM") <<
"PFParticle " << ipf <<
" tID " << tID;
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)
637 mf::LogVerbatim(
"CCTM") <<
" dtr jpf " << jpf <<
" itr " << itr;
639 unsigned short parentIndex = USHRT_MAX;
643 pcol->emplace_back(std::move(pfp));
644 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
645 if (!
vtx[ivx].Neutrino)
continue;
650 size_t vStart = vcol->size();
652 vcol->emplace_back(std::move(vertex));
653 size_t vEnd = vcol->size();
656 vtx[ivx].ID = -
vtx[ivx].ID;
665 for (
unsigned short ii = 0; ii <
pfpToTrkID.size(); ++ii) {
672 mf::LogVerbatim(
"CCTM")
673 <<
"daughters tID " << tID <<
" pdg " <<
trk[tIndex].PDGCode <<
" ipf " << ipf
674 <<
" parentIndex " << parentIndex <<
" dtr size " << dtrIndices.size();
676 pcol->emplace_back(std::move(pfp));
679 size_t tStart = tcol->size();
691 tcol->emplace_back(std::move(
track));
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();
714 scol->emplace_back(std::move(seed));
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;
748 tcol->emplace_back(std::move(
track));
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;
762 vcol->emplace_back(std::move(vertex));
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;
772 mf::LogVerbatim(
"CCTM")
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";
788 evt.put(std::move(pcol));
789 evt.put(std::move(ptassn));
790 evt.put(std::move(pcassn));
791 evt.put(std::move(pvassn));
792 evt.put(std::move(psassn));
793 evt.put(std::move(tcol));
794 evt.put(std::move(thassn));
795 evt.put(std::move(scol));
796 evt.put(std::move(vcol));
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;
819 if (fNVtxTrkHitsFit == 0)
return;
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) {
869 mf::LogVerbatim(
"CCTM") <<
"Not enough hits to fit vtx " << ivx;
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;
1096 std::reverse(
trk[itr].TrjPos.begin(),
trk[itr].TrjPos.end());
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);
1145 std::reverse(
trk[jtr].TrjPos.begin(),
trk[jtr].TrjPos.end());
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;
1218 if (fDeltaRayCut <= 0)
return;
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);
1251 mf::LogVerbatim myprt(
"CCTM");
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;
1300 mf::LogVerbatim(
"CCTM")
1301 <<
"FillEndMatch2: Err " << match.
Err <<
" oErr " << match.
oErr;
1302 if (match.
Err + match.
oErr > 100)
continue;
1307 match.
Cls[kpl] = -1;
1310 mf::LogVerbatim(
"CCTM")
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;
1363 mf::LogVerbatim myprt(
"CCTM");
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;
1506 mf::LogVerbatim(
"CCTM")
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;
1511 if (
std::abs(
cls[ipl][icl1].Wire[1] -
cls[ipl][icl2].Wire[0]) > dWCut)
continue;
1516 dACut = fMaxDAng * af;
1517 dXCut = fChainMaxdX * 5 * af;
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]);
1524 mf::LogVerbatim(
"CCTM")
1525 <<
" dA " << dA <<
" dA2 " << dA2 <<
" DACut " << dACut <<
" dXCut " << dXCut;
1527 if (dA2 < dA) dA = dA2;
1530 if (dA < fChainVtxAng &&
cls[ipl][icl1].VtxIndex[1] >= 0) {
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;
1539 if (
prt) mf::LogVerbatim(
"CCTM") <<
" clobbered vertex " << ivx;
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 &&
1550 if (
prt) mf::LogVerbatim(
"CCTM") <<
"Stopping cluster";
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]);
1561 if (
prt) mf::LogVerbatim(
"CCTM") <<
" dA3 " << dA3;
1562 if (dA3 > dA) dA = dA3;
1566 if (dA > dACut)
continue;
1569 mf::LogVerbatim(
"CCTM")
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;
1578 if (dA > fChainVtxAng)
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];
1583 if (
prt) mf::LogVerbatim(
"CCTM") <<
" chgasym " << chgasym <<
" cut " << chgAsymCut;
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);
1601 if (
prt) mf::LogVerbatim(
"CCTM") <<
" new dx from dXClTraj " << dx;
1605 mf::LogVerbatim(
"CCTM")
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;
1617 mf::LogVerbatim(
"CCTM")
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];
1628 if (
prt) mf::LogVerbatim(
"CCTM") <<
"clobber old icl1 BrkIndex " << ocl;
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];
1644 if (
prt) mf::LogVerbatim(
"CCTM") <<
"clobber old icl2 BrkIndex " << ocl;
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;
1656 if (
prt) mf::LogVerbatim(
"CCTM") <<
" merge " << icl1 <<
" and " << icl2;
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;
1677 mf::LogVerbatim(
"CCTM")
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 "
1682 << fabs(
cls[ipl][icl1].Wire[end] -
cls[ipl][icl2].Wire[end]);
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];
1691 if (
prt) mf::LogVerbatim(
"CCTM") <<
" fvw " << fvw;
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]);
1702 mf::LogVerbatim(
"CCTM")
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];
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) {
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) {
1907 mf::LogError(
"CCTM") <<
"Bad imat in StoreTrack";
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();
1968 fHitFitErrFac *
trkHits[ipl][iht]->RMS() *
trkHits[ipl][iht]->Multiplicity();
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 "
1986 if (
prt) mf::LogVerbatim(
"CCTM") <<
" number of traj points " << trkPos.size();
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();
2061 mf::LogError(
"CCTM")
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;
2085 for (
unsigned short icc = 0; icc <
clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
2086 icl =
clsChain[ipl][ccl].ClsIndex[icc];
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";
2098 if (
prt) mf::LogVerbatim(
"CCTM") <<
" track ID " << newtrk.
ID <<
" stored in StoreTrack";
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;
2115 float tpcSizeY =
geom->DetHalfWidth();
2116 float tpcSizeZ =
geom->DetLength();
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;
2139 if (
clsChain[jpl][jcl].
Length < fMatchMinLen[algIndex])
continue;
2141 mchg[0] =
clsChain[ipl][icl].TotChg;
2142 mchg[1] =
clsChain[jpl][jcl].TotChg;
2144 if (fChgAsymFactor[algIndex] > 0 &&
ChargeAsym(mchg) > 0.5)
continue;
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;
2155 kSlp =
geom->ThirdPlaneSlope(ipl,
2163 geom->IntersectionPoint((
unsigned int)(0.5 +
clsChain[ipl][icl].Wire[iend]),
2164 (
unsigned int)(0.5 +
clsChain[jpl][jcl].Wire[jend]),
2171 if (yp > tpcSizeY || yp < -tpcSizeY)
continue;
2172 if (zp < 0 || zp > tpcSizeZ)
continue;
2176 geom->IntersectionPoint((
unsigned int)(0.5 +
clsChain[ipl][icl].Wire[ioend]),
2177 (
unsigned int)(0.5 +
clsChain[jpl][jcl].Wire[joend]),
2184 if (yp > tpcSizeY || yp < -tpcSizeY)
continue;
2185 if (zp < 0 || zp > tpcSizeZ)
continue;
2188 mf::LogVerbatim(
"CCTM")
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];
2194 mf::LogVerbatim(
"CCTM")
2195 <<
"PlnMatch: chk j " << ipl <<
":" << icl <<
":" << iend <<
" " << jpl <<
":"
2196 << jcl <<
":" << jend <<
" iSlp " << std::setprecision(2)
2197 <<
clsChain[ipl][icl].Slope[iend] <<
" jSlp " << std::setprecision(2)
2198 <<
clsChain[jpl][jcl].Slope[jend] <<
" kWir " << (int)kWir <<
" okWir "
2199 << (
int)okWir <<
" kSlp " << std::setprecision(2) << kSlp <<
" kAng "
2200 << std::setprecision(2) << kAng <<
" kX " << std::setprecision(1) <<
kX;
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;
2214 if (fChgAsymFactor[algIndex] > 0 &&
ChargeAsym(mchg) > 0.5)
continue;
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;
2219 mf::LogVerbatim(
"CCTM")
2220 <<
" kcl " << kcl <<
" kend " << kend <<
" dx "
2225 mf::LogVerbatim(
"CCTM")
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;
2229 if (
prt) mf::LogVerbatim(
"CCTM") <<
" chk k " << kpl <<
":" << kcl <<
":" << kend;
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;
2246 mf::LogVerbatim(
"CCTM") <<
" PlnMatch: match k " << kpl <<
":" << match.
Cls[kpl]
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;
2251 if (
prt) mf::LogVerbatim(
"CCTM") <<
" dup? ";
2257 if (
prt) mf::LogVerbatim(
"CCTM") <<
" PlnMatch: gotkcl " << gotkcl;
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;
2276 mf::LogVerbatim(
"CCTM")
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);
2366 mf::LogVerbatim myprt(
"CCTM");
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;
2376 myprt << std::fixed <<
std::right << std::setw(5) << ii << std::setw(5) << im
2377 << std::setw(4) <<
matcomb[im].Vtx << std::setw(7) << std::setprecision(2)
2378 <<
matcomb[im].Err << std::setw(7) << std::setprecision(1) <<
matcomb[im].dWir
2379 << std::setw(7) << std::setprecision(2) <<
matcomb[im].dAng << std::setw(7)
2380 << std::setprecision(2) <<
matcomb[im].dX << std::setw(4) <<
matcomb[im].oVtx
2381 << std::setw(7) << std::setprecision(2) <<
matcomb[im].oErr << std::setw(7)
2382 << std::setprecision(1) <<
matcomb[im].odWir << std::setw(7) << std::setprecision(2)
2383 <<
matcomb[im].odAng << std::setw(7) << std::setprecision(2) <<
matcomb[im].odX
2384 << std::setw(7) << std::setprecision(3) << asym <<
" 0:" <<
matcomb[im].Cls[0] <<
":"
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;
2489 mf::LogVerbatim myprt(
"CCTM");
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;
2501 mf::LogVerbatim myprt(
"CCTM");
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]) {
2581 if (fChgAsymFactor[
algIndex] > 0) {
2582 chgAsym = fabs(match.
Chg[ipl] - match.
Chg[jpl]) / (match.
Chg[ipl] + match.
Chg[jpl]);
2583 if (chgAsym > 0.5)
return;
2584 chgAsym = 1 + fChgAsymFactor[
algIndex] * chgAsym;
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]);
2591 float sigmaX = fXMatchErr[
algIndex] + std::max(maxSlp, (
float)20);
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]);
2599 sigmaX = fXMatchErr[
algIndex] + std::max(maxSlp, (
float)20);
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) {
2663 mf::LogVerbatim myprt(
"CCTM");
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]
2698 << std::fixed << std::setprecision(3) <<
" Slp "
2699 <<
clsChain[ipl][icl].Slope[iend] << std::fixed
2700 << std::setprecision(1) <<
" X " <<
clsChain[ipl][icl].X[iend];
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
2716 << std::setprecision(3) <<
" oSlp " << oSlp[ipl] << std::fixed
2717 << std::setprecision(1) <<
" oX " << oX[ipl] <<
" Chg "
2722 bool isShort = (nShortCl > 1);
2725 mf::LogWarning(
"CCTM") <<
"Not enough matched planes supplied";
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];
2813 okSlp =
geom->ThirdPlaneSlope(ipl, oSlp[ipl], jpl, oSlp[jpl],
tpc,
cstat);
2814 okAng = atan(okSlp);
2817 bool ignoreSign = (fabs(okSlp) > 10);
2818 if (ignoreSign) okAng = fabs(okAng);
2819 if (match.
oVtx >= 0) {
2826 geom->IntersectionPoint(oWir[ipl], oWir[jpl], ipl, jpl,
cstat,
tpc, ypos, zpos);
2827 okWir = (0.5 +
geom->WireCoordinate(ypos, zpos, kpl,
tpc,
cstat));
2828 okX = 0.5 * (oX[ipl] + oX[jpl]);
2832 mf::LogVerbatim(
"CCTM") <<
"FEM: oEnd"
2833 <<
" kpl " << kpl <<
" okSlp " << okSlp <<
" okAng " << okAng
2834 <<
" okWir " << (int)okWir <<
" okX " << okX;
2838 kSlp =
geom->ThirdPlaneSlope(
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();
2861 kWir = (0.5 +
geom->WireCoordinate(ypos, zpos, kpl,
tpc,
cstat));
2866 mf::LogVerbatim(
"CCTM") <<
"FEM: mEnd"
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;
2905 if (fChgAsymFactor[
algIndex] > 0) {
2907 if (chgAsym > 0.5)
return;
2908 chgAsym = 1 + fChgAsymFactor[
algIndex] * chgAsym;
2911 if (
prt) mf::LogVerbatim(
"CCTM") <<
"FEM: charge asymmetry factor " << chgAsym;
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;
2932 sigmaX = fXMatchErr[
algIndex] + std::max(kSlp, (
float)20);
2935 mf::LogVerbatim(
"CCTM") <<
"bb " <<
algIndex <<
" " << fXMatchErr[
algIndex] <<
" "
2936 << fAngleMatchErr[
algIndex] <<
" kslp " << kSlp;
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]; }
2949 if (
prt) mf::LogVerbatim(
"CCTM") <<
" dw " << dw <<
" dx " << match.
dX;
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;
2962 if (
prt) mf::LogVerbatim(
"CCTM") <<
" 3-pln w Vtx match.Err " << match.
Err;
2967 match.
Err = vxFactor * chgAsym * sqrt(dx * dx + da * da + dw * dw) / 9;
2968 if (
prt) mf::LogVerbatim(
"CCTM") <<
" 3-pln match.Err " << match.
Err;
2977 match.
Err = 3 + vxFactor * chgAsym * fabs(match.
dX) / sigmaX;
2978 if (
prt) mf::LogVerbatim(
"CCTM") <<
" 2-pln Err " << match.
Err;
2982 if (nClInPln == 3) {
2984 dw = okWir - oWir[kpl];
2986 if (match.
oVtx >= 0) { match.
odX = okX - oX[kpl]; }
2991 mf::LogVerbatim(
"CCTM") <<
" odw " << match.
odWir <<
" odx " << match.
odX <<
" sigmaX "
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;
3006 if (
prt) mf::LogVerbatim(
"CCTM") <<
" 3-pln match.oErr " << match.
oErr;
3010 match.
odX = (oX[ipl] - oX[jpl]) / sigmaX;
3011 match.
oErr = 3 + ovxFactor * chgAsym * fabs(match.
odX);
3012 if (
prt) mf::LogVerbatim(
"CCTM") <<
" 2-pln match.oErr " << match.
oErr;
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;
3037 dxcut = 3 * fXMatchErr[
algIndex] + kslp;
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) {
3045 if (fabs(
clsChain[kpl][ccl].Wire[
end] - kWir) > 4)
continue;
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];
3114 std::reverse(
clsChain[ipl][ccl].ClsIndex.begin(),
clsChain[ipl][ccl].ClsIndex.end());
3115 std::reverse(
clsChain[ipl][ccl].Order.begin(),
clsChain[ipl][ccl].Order.end());
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) {
3149 trkHits[ipl][indx + iht] = clusterhits[iht];
3155 for (ii = 0; ii < clusterhits.size(); ++ii) {
3156 iht = clusterhits.size() - 1 - ii;
3158 trkHits[ipl][indx + ii] = clusterhits[iht];
3164 mf::LogVerbatim(
"CCTM") <<
"plane " << ipl <<
" first p " <<
trkHits[ipl][0]->WireID().Plane
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 <<
":"
3169 << (int)
trkHits[ipl][ii]->PeakTime();
3182 mf::LogVerbatim myprt(
"CCTM");
3183 myprt <<
"********* PrintTracks \n";
3184 myprt <<
"vtx Index X Y Z\n";
3185 for (
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
3186 myprt <<
std::right << std::setw(4) << ivx << std::setw(4) <<
vtx[ivx].EvtIndex;
3187 myprt << std::fixed;
3188 myprt <<
std::right << std::setw(10) << std::setprecision(1) <<
vtx[ivx].X;
3189 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
vtx[ivx].Y;
3190 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
vtx[ivx].Z;
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) {
3199 myprt <<
std::right << std::setw(3) << itr << std::setw(4) <<
trk[itr].ID;
3200 myprt <<
std::right << std::setw(5) << std::setw(4) <<
trk[itr].Proc;
3201 unsigned short nht = 0;
3202 for (
unsigned short ii = 0; ii < 3; ++ii)
3203 nht +=
trk[itr].TrkHits[ii].
size();
3205 myprt << std::setw(4) <<
trk[itr].TrjPos.size();
3206 myprt << std::fixed;
3207 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[0](0);
3208 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[0](1);
3209 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[0](2);
3210 unsigned short itj =
trk[itr].TrjPos.size() - 1;
3211 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[itj](0);
3212 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[itj](1);
3213 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
trk[itr].TrjPos[itj](2);
3214 myprt << std::setw(4) <<
trk[itr].VtxIndex[0] << std::setw(4) <<
trk[itr].VtxIndex[1];
3215 myprt << std::setw(4) <<
trk[itr].GoodEnd[0];
3216 myprt << std::setw(4) <<
trk[itr].GoodEnd[1];
3217 myprt << std::setw(4) <<
trk[itr].ChgOrder;
3218 myprt <<
std::right << std::setw(10) << std::setprecision(3) <<
trk[itr].TrjDir[itj](2);
3220 myprt <<
std::right << std::setw(5) <<
trk[itr].PDGCode <<
" ";
3221 for (
unsigned short ii = 0; ii <
trk[itr].ClsEvtIndices.size(); ++ii)
3222 myprt <<
" " <<
trk[itr].ClsEvtIndices[ii];
3233 unsigned short iTime;
3234 mf::LogVerbatim myprt(
"CCTM");
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) {
3238 myprt <<
std::right << std::setw(3) << ivx << std::setw(7) << ivx;
3239 myprt << std::fixed;
3240 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
vtx[ivx].X;
3241 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
vtx[ivx].Y;
3242 myprt <<
std::right << std::setw(7) << std::setprecision(1) <<
vtx[ivx].Z;
3243 myprt <<
std::right << std::setw(5) <<
vtx[ivx].nClusInPln[0];
3244 myprt <<
std::right << std::setw(5) <<
vtx[ivx].nClusInPln[1];
3245 myprt <<
std::right << std::setw(5) <<
vtx[ivx].nClusInPln[2];
3247 for (
unsigned short ipl = 0; ipl <
nplanes; ++ipl) {
3250 myprt <<
std::right << std::setw(7) << wire <<
":" << time;
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) {
3268 << std::setprecision(1) << iTime;
3269 if (iTime < 10) { myprt <<
" "; }
3270 else if (iTime < 100) {
3273 else if (iTime < 1000)
3275 myprt <<
std::right << std::setw(7) << std::setprecision(2)
3279 myprt << std::fixed <<
std::right << std::setw(6) << std::setprecision(1)
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];
3289 if (fPrintAllClusters) {
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) {
3296 myprt <<
std::right << std::setw(5) <<
cls[ipl][icl].EvtIndex;
3297 myprt <<
std::right << std::setw(6) <<
cls[ipl][icl].Length;
3298 myprt <<
std::right << std::setw(8) << (int)
cls[ipl][icl].TotChg;
3299 for (
unsigned short end = 0;
end < 2; ++
end) {
3300 iTime =
cls[ipl][icl].Time[
end];
3301 myprt <<
std::right << std::setw(5) << (int)
cls[ipl][icl].Wire[
end] <<
":" << iTime;
3302 if (iTime < 10) { myprt <<
" "; }
3303 else if (iTime < 100) {
3306 else if (iTime < 1000)
3308 myprt <<
std::right << std::setw(7) << std::setprecision(2) <<
cls[ipl][icl].Angle[
end];
3311 myprt << std::fixed <<
std::right << std::setw(5) << std::setprecision(1)
3312 <<
cls[ipl][icl].ChgNear[
end];
3314 myprt << std::fixed;
3315 myprt <<
std::right << std::setw(5) <<
cls[ipl][icl].InTrack;
3316 myprt <<
std::right << std::setw(5) << (int)
cls[ipl][icl].BrkIndex[0];
3317 myprt <<
std::right << std::setw(7) << std::setprecision(1)
3318 <<
cls[ipl][icl].MergeError[0];
3319 myprt <<
std::right << std::setw(5) << (int)
cls[ipl][icl].BrkIndex[1];
3320 myprt <<
std::right << std::setw(7) << std::setprecision(1)
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;
3411 mf::LogError(
"CCTM") <<
"Invalid WireID().Wire " <<
allhits[
hit]->WireID().Wire;
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)
3447 int sflag, nwires, wire;
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;
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) {
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)
3542 <<
allhits[ii]->WireID().Wire <<
" " << (int)
allhits[ii]->PeakTime() <<
"\n";
std::string fHitModuleLabel
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
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
Declaration of signal hit object.
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)
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
std::size_t size(FixedBins< T, C > const &) noexcept
TrackTrajectoryAlg fTrackTrajectoryAlg
std::array< float, 2 > ChgNear
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.
process_name use argoneut_mc_hitfinder track
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)
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
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
std::array< bool, 2 > EndInTPC
void AngMatch(art::FindManyP< recob::Hit > const &fmCluHits)
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 DupMatch(MatchPars &match)
void FillTrkHits(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat)
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)
CCTrackMaker(fhicl::ParameterSet const &pset)
std::vector< unsigned short > Order
float AngleFactor(float slope)
std::array< short, 2 > VtxIndex
std::array< short, 2 > mVtxIndex
auto end(FixedBins< T, C > const &) noexcept
std::vector< short > DtrID
double ConvertXToTicks(double X, int p, int t, int c) const
std::vector< vtxPar > vtx
std::array< float, 2 > MergeError
void produce(art::Event &evt) override
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::array< bool, 2 > GoodEnd
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
std::array< float, 2 > Wire
Declaration of cluster object.
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
Provides recob::Track data product.
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
std::array< unsigned int, 3 > lastWire
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
auto begin(FixedBins< T, C > const &) noexcept
bool greaterThan(CluLen c1, CluLen c2)
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
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
std::array< short, 2 > VtxIndex
void PrintClusters(detinfo::DetectorPropertiesData const &detProp) const
std::array< unsigned int, 3 > lastHit
bool lessThan(CluLen c1, CluLen c2)
std::array< short, 2 > Dir
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
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
art framework interface to geometry description
BEGIN_PROLOG could also be cout
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
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