43 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 44 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 142 std::array<float, 2>
X;
159 std::array<std::vector<clPar>, 3>
cls;
164 std::array<float, 2>
X;
195 std::array<std::vector<unsigned short>, 3>
vxCls;
200 std::array< std::vector<art::Ptr<recob::Hit>>, 3>
TrkHits;
216 std::array< std::vector<art::Ptr<recob::Hit>>, 3>
trkHits;
218 std::array< std::vector<art::Ptr<recob::Hit>>, 3>
seedHits;
230 std::array<unsigned short, 3>
End;
249 void PrintTracks()
const;
252 float dXClTraj(
art::FindManyP<recob::Hit> const& fmCluHits,
unsigned short ipl,
unsigned short icl1,
unsigned short end1,
unsigned short icl2);
258 void FindMaybeVertices();
277 float ChargeAsym(std::array<float, 3>& mChg);
279 void FindMidPointMatch(
art::FindManyP<recob::Hit> const& fmCluHits,
MatchPars& match,
unsigned short kkpl,
unsigned short kkcl,
unsigned short kkend,
float& kkWir,
float& kkX);
281 bool FindMissingCluster(
unsigned short kpl,
short& kcl,
unsigned short& kend,
float kWir,
float kX,
float okWir,
float okX);
297 float ChargeNear(
unsigned short ipl,
unsigned short wire1,
float time1,
unsigned short wire2,
float time2);
300 float AngleFactor(
float slope);
307 this->reconfigure(pset);
308 produces< std::vector<recob::PFParticle> >();
309 produces< art::Assns<recob::PFParticle, recob::Track> >();
310 produces< art::Assns<recob::PFParticle, recob::Cluster> >();
311 produces< art::Assns<recob::PFParticle, recob::Seed> >();
312 produces< art::Assns<recob::PFParticle, recob::Vertex> >();
313 produces< std::vector<recob::Vertex> >();
314 produces< std::vector<recob::Track> >();
315 produces< art::Assns<recob::Track, recob::Hit> >();
316 produces<std::vector<recob::Seed> >();
323 fHitModuleLabel = pset.
get< std::string >(
"HitModuleLabel");
324 fClusterModuleLabel = pset.
get< std::string >(
"ClusterModuleLabel");
325 fVertexModuleLabel = pset.
get< std::string >(
"VertexModuleLabel");
327 fMatchAlgs = pset.
get< std::vector<short> >(
"MatchAlgs");
328 fXMatchErr = pset.
get< std::vector<float> >(
"XMatchErr");
329 fAngleMatchErr = pset.
get< std::vector<float> >(
"AngleMatchErr");
330 fChgAsymFactor = pset.
get< std::vector<float> >(
"ChgAsymFactor");
331 fMatchMinLen = pset.
get< std::vector<float> >(
"MatchMinLen");
332 fMakeAlgTracks = pset.
get< std::vector<bool> >(
"MakeAlgTracks");
334 fMaxDAng = pset.
get<
float >(
"MaxDAng");
335 fChainMaxdX = pset.
get<
float >(
"ChainMaxdX");
336 fChainVtxAng = pset.
get<
float >(
"ChainVtxAng");
337 fMergeChgAsym = pset.
get<
float >(
"MergeChgAsym");
339 fFiducialCut = pset.
get<
float >(
"FiducialCut");
340 fDeltaRayCut = pset.
get<
float >(
"DeltaRayCut");
342 fMakePFPs = pset.
get<
bool >(
"MakePFPs");
344 fNVtxTrkHitsFit = pset.
get<
unsigned short >(
"NVtxTrkHitsFit");
345 fHitFitErrFac = pset.
get<
float >(
"HitFitErrFac");
347 fuBCode = pset.
get<
bool >(
"uBCode");
349 fDebugAlg = pset.
get<
short >(
"DebugAlg");
350 fDebugPlane = pset.
get<
short >(
"DebugPlane");
351 fDebugCluster = pset.
get<
short >(
"DebugCluster");
352 fPrintAllClusters = pset.
get<
bool >(
"PrintAllClusters");
355 if(fMatchAlgs.size() > fXMatchErr.size() || fMatchAlgs.size() > fAngleMatchErr.size()
356 || fMatchAlgs.size() > fChgAsymFactor.size() || fMatchAlgs.size() > fMatchMinLen.size()
357 || fMatchAlgs.size() > fMakeAlgTracks.size()) {
358 mf::LogError(
"CCTM")<<
"Incompatible fcl input vector sizes";
362 for(
unsigned short ii = 0; ii < fMatchAlgs.size(); ++ii) {
363 if(fAngleMatchErr[ii] <= 0 || fXMatchErr[ii] <= 0) {
364 mf::LogError(
"CCTM")<<
"Invalid matching parameters "<<fAngleMatchErr[ii]<<
" "<<fXMatchErr[ii];
372 CCTrackMaker::~CCTrackMaker()
391 detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
393 fWirePitch = geom->WirePitch();
397 std::unique_ptr<std::vector<recob::Track>> tcol(
new std::vector<recob::Track>);
400 std::unique_ptr<std::vector<recob::Vertex>> vcol(
new std::vector<recob::Vertex>);
402 std::unique_ptr<std::vector<recob::PFParticle>> pcol(
new std::vector<recob::PFParticle>);
410 std::unique_ptr<std::vector<recob::Seed>> scol(
new std::vector<recob::Seed>);
417 std::vector<art::Ptr<recob::Cluster>> clusterlist;
420 std::vector<art::Ptr<recob::Vertex>> vtxlist;
424 if (evt.
getByLabel(fHitModuleLabel, allhitsListHandle))
428 if (evt.
getByLabel(fClusterModuleLabel, clusterListHandle))
430 if(clusterlist.size() == 0)
return;
436 if (evt.
getByLabel(fVertexModuleLabel, VtxListHandle))
440 std::vector<CluLen> clulens;
442 unsigned short ipl, icl,
end, itr, tID, tIndex;
451 std::vector< std::vector<double> > dQdx;
455 for(
unsigned short ii = 0; ii < 5; ++ii) cov(ii, ii) = 1;
456 std::vector<TMatrixD> tmpCov;
457 tmpCov.push_back(cov);
458 tmpCov.push_back(cov);
459 std::vector< art::Ptr<recob::Hit > > tmpHits;
460 std::vector< art::Ptr<recob::Cluster > > tmpCls;
461 std::vector< art::Ptr<recob::Vertex > > tmpVtx;
464 std::vector<size_t> dtrIndices;
467 double sPos[3], sDir[3];
468 double sErr[3] = {0,0,0};
471 std::vector<art::Ptr<recob::Hit>> clusterhits;
472 for(icl = 0; icl < clusterlist.size(); ++icl) {
473 ipl = clusterlist[icl]->Plane().Plane;
474 clusterhits = fmCluHits.at(icl);
475 if(clusterhits[0]->WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
476 std::cout<<
"CCTM Cluster-Hit End wire mis-match "<<clusterhits[0]->WireID().Wire<<
" vs "<<std::nearbyint(clusterlist[icl]->EndWire())<<
" Bail out! \n";
479 for(
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
480 if(clusterhits[iht]->WireID().Plane != ipl) {
481 std::cout<<
"CCTM Cluster-Hit plane mis-match "<<ipl<<
" vs "<<clusterhits[iht]->WireID().Plane<<
" on hit "<<iht<<
" Bail out! \n";
492 for(cstat = 0; cstat < geom->Ncryostats(); ++cstat) {
493 for(tpc = 0; tpc < geom->Cryostat(cstat).NTPC(); ++tpc) {
494 nplanes = geom->Cryostat(cstat).TPC(tpc).Nplanes();
495 if(nplanes > 3)
continue;
496 for(ipl = 0; ipl < 3; ++ipl) {
498 clsChain[ipl].clear();
499 trkHits[ipl].clear();
503 for(ipl = 0; ipl < nplanes; ++ipl) {
506 for(icl = 0; icl < clusterlist.size(); ++icl) {
507 if(clusterlist[icl]->
Plane().Cryostat != cstat)
continue;
508 if(clusterlist[icl]->
Plane().TPC != tpc)
continue;
509 if(clusterlist[icl]->
Plane().
Plane != ipl)
continue;
512 clulen.
length = clusterlist[icl]->EndWire();
513 clulens.push_back(clulen);
515 if(clulens.size() == 0)
continue;
517 std::sort (clulens.begin(),clulens.end(),
lessThan);
518 if(clulens.size() == 0)
continue;
519 for(
unsigned short ii = 0; ii < clulens.size(); ++ii) {
520 const unsigned short icl = clulens[ii].index;
527 clstr.
X[1] = (float)detprop->ConvertTicksToX(cluster.
StartTick(), ipl, tpc, cstat);
542 clstr.
X[0] = (float)detprop->ConvertTicksToX(cluster.
EndTick(), ipl, tpc, cstat);
548 clstr.
Dir[0] = 1; clstr.
Dir[1] = -1;
550 clstr.
Dir[0] = -1; clstr.
Dir[1] = 1;
561 clstr.
Length = (
unsigned short)(0.5 + clstr.
Wire[1] - clstr.
Wire[0]);
564 clusterhits = fmCluHits.at(icl);
565 if(clusterhits.size() == 0) {
566 mf::LogError(
"CCTM")<<
"No associated cluster hits "<<icl;
570 clstr.
TotChg *= clstr.
Length / (float)clusterhits.size();
571 cls[ipl].push_back(clstr);
581 for(
unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
585 vtxlist[ivx]->XYZ(xyz);
592 std::vector<art::Ptr<recob::Cluster>>
const& vtxCls = fmVtxCls.at(ivx);
593 std::vector<const unsigned short*>
const& vtxClsEnd = fmVtxCls.
data(ivx);
594 for(
unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
595 icl = vtxCls[vcass].key();
597 ipl = vtxCls[vcass]->Plane().Plane;
598 end = *vtxClsEnd[vcass];
599 if(end > 1)
throw cet::exception(
"CCTM")<<
"Invalid end data from vertex - cluster association"<<
end;
603 for(
unsigned short jcl = 0; jcl < cls[ipl].size(); ++jcl) {
604 if(cls[ipl][jcl].EvtIndex == icl) {
605 cls[ipl][jcl].VtxIndex[
end] = ivx;
611 if(!gotit)
throw cet::exception(
"CCTM")<<
"Bad index from vertex - cluster association"<<icl;
616 MakeClusterChains(fmCluHits);
621 for(algIndex = 0; algIndex < fMatchAlgs.size(); ++algIndex) {
622 if(fMatchAlgs[algIndex] == 1) {
623 prt = (fDebugAlg == 1);
625 if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 1);
627 if(fMatchAlgs[algIndex] == 2) {
628 prt = (fDebugAlg == 2);
630 if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 2);
644 for(
unsigned short ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
646 tID = pfpToTrkID[ipf];
647 if(tID >
trk.size()+1) {
654 for(
unsigned short jpf = 0; jpf < pfpToTrkID.size(); ++jpf) {
655 itr = pfpToTrkID[jpf] - 1;
656 if(
trk[itr].MomID == tID) dtrIndices.push_back(jpf);
659 unsigned short parentIndex = USHRT_MAX;
663 pcol->emplace_back(std::move(pfp));
664 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
665 if(!vtx[ivx].Neutrino)
continue;
670 size_t vStart = vcol->size();
672 vcol->emplace_back(std::move(vertex));
673 size_t vEnd = vcol->size();
676 vtx[ivx].ID = -vtx[ivx].ID;
684 for(
unsigned short ii = 0; ii < pfpToTrkID.size(); ++ii) {
685 if(pfpToTrkID[ii] ==
trk[tIndex].MomID) {
691 mf::LogVerbatim(
"CCTM")<<
"daughters tID "<<tID<<
" pdg "<<
trk[tIndex].PDGCode<<
" ipf "<<ipf<<
" parentIndex "<<parentIndex<<
" dtr size "<<dtrIndices.size();
693 pcol->emplace_back(std::move(pfp));
696 size_t tStart = tcol->size();
698 tcol->emplace_back(std::move(track));
699 size_t tEnd = tcol->size();
703 trk[tIndex].ID = -
trk[tIndex].ID;
706 for(ipl = 0; ipl < nplanes; ++ipl)
707 tmpHits.insert(tmpHits.end(),
trk[tIndex].TrkHits[ipl].begin(),
trk[tIndex].TrkHits[ipl].end());
712 unsigned short itj = 0;
713 if(end > 0) itj =
trk[tIndex].TrjPos.size() - 1;
714 for(
unsigned short ii = 0; ii < 3; ++ii) {
715 sPos[ii] =
trk[tIndex].TrjPos[itj](ii);
716 sDir[ii] =
trk[tIndex].TrjDir[itj](ii);
718 size_t sStart = scol->size();
720 scol->emplace_back(std::move(seed));
721 size_t sEnd = scol->size();
726 for(ipl = 0; ipl < nplanes; ++ipl)
727 tmpHits.insert(tmpHits.end(), seedHits[ipl].begin(), seedHits[ipl].end());
732 for(
unsigned short ii = 0; ii <
trk[tIndex].ClsEvtIndices.size(); ++ii) {
733 icl =
trk[tIndex].ClsEvtIndices[ii];
734 tmpCls.push_back(clusterlist[icl]);
740 for(
unsigned short itr = 0; itr <
trk.size(); ++itr) {
742 if(
trk[itr].ID < 0)
continue;
744 tcol->emplace_back(std::move(track));
746 for(ipl = 0; ipl < nplanes; ++ipl)
747 tmpHits.insert(tmpHits.end(),
trk[itr].TrkHits[ipl].begin(),
trk[itr].TrkHits[ipl].end());
751 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
752 if(vtx[ivx].ID < 0)
continue;
757 vcol->emplace_back(std::move(vertex));
759 if(fDebugAlg > 0) PrintTracks();
761 double orphanLen = 0;
762 for(ipl = 0; ipl < nplanes; ++ipl) {
763 for(icl = 0; icl < cls[ipl].size(); ++icl) {
764 if(cls[ipl][icl].Length > 40 && cls[ipl][icl].InTrack < 0) {
765 orphanLen += cls[ipl][icl].Length;
767 mf::LogVerbatim(
"CCTM")<<
"Orphan long cluster "<<ipl<<
":"<<icl<<
":"<<cls[ipl][icl].Wire[0]
768 <<
":"<<(int)cls[ipl][icl].Time[0]<<
" length "<<cls[ipl][icl].Length;
773 clsChain[ipl].clear();
775 std::cout<<
"Total orphan length "<<orphanLen<<
"\n";
776 trkHits[ipl].clear();
777 seedHits[ipl].clear();
782 evt.
put(std::move(pcol));
783 evt.
put(std::move(ptassn));
784 evt.
put(std::move(pcassn));
785 evt.
put(std::move(pvassn));
786 evt.
put(std::move(psassn));
787 evt.
put(std::move(tcol));
788 evt.
put(std::move(thassn));
789 evt.
put(std::move(scol));
790 evt.
put(std::move(vcol));
854 void CCTrackMaker::FitVertices()
857 std::vector<std::vector<geo::WireID>> hitWID;
858 std::vector<std::vector<double>> hitX;
859 std::vector<std::vector<double>> hitXErr;
860 TVector3 pos, posErr;
861 std::vector<TVector3> trkDir;
862 std::vector<TVector3> trkDirErr;
865 if(fNVtxTrkHitsFit == 0)
return;
867 unsigned short indx, indx2, iht, nHitsFit;
871 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
872 if(!vtx[ivx].Neutrino)
continue;
878 unsigned int thePln, theTPC, theCst;
879 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
880 for(
unsigned short end = 0;
end < 2; ++
end) {
881 if(
trk[itk].VtxIndex[
end] != ivx)
continue;
882 unsigned short itj = 0;
883 if(
end == 1) itj =
trk[itk].TrjPos.size() - 1;
888 hitWID.resize(indx + 1);
889 hitX.resize(indx + 1);
890 hitXErr.resize(indx + 1);
891 trkDir.resize(indx + 1);
892 trkDir[indx] =
trk[itk].TrjDir[itj];
893 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
894 if(
trk[itk].TrkHits[ipl].size() < 2)
continue;
896 nHitsFit =
trk[itk].TrkHits[ipl].size();
897 if(nHitsFit > fNVtxTrkHitsFit) nHitsFit = fNVtxTrkHitsFit;
898 indx2 = hitWID[indx].size();
899 hitWID[indx].resize(indx2 + nHitsFit);
900 hitX[indx].resize(indx2 + nHitsFit);
901 hitXErr[indx].resize(indx2 + nHitsFit);
902 for(
unsigned short ii = 0; ii < nHitsFit; ++ii) {
906 iht =
trk[itk].TrkHits[ipl].size() - ii - 1;
908 hitWID[indx][indx2 + ii] =
trk[itk].TrkHits[ipl][iht]->WireID();
909 thePln =
trk[itk].TrkHits[ipl][iht]->WireID().Plane;
910 theTPC =
trk[itk].TrkHits[ipl][iht]->WireID().TPC;
911 theCst =
trk[itk].TrkHits[ipl][iht]->WireID().Cryostat;
912 hitX[indx][indx2 + ii] = detprop->ConvertTicksToX(
trk[itk].TrkHits[ipl][iht]->PeakTime(), thePln, theTPC, theCst);
913 hitXErr[indx][indx2 + ii] = fHitFitErrFac *
trk[itk].TrkHits[ipl][iht]->RMS();
921 if(hitX.size() < 2) {
928 fVertexFitAlg.VertexFit(hitWID, hitX, hitXErr, pos, posErr, trkDir, trkDirErr, ChiDOF);
934 if(ChiDOF > 3000)
continue;
940 unsigned short fitTrk = 0;
941 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
942 for(
unsigned short end = 0;
end < 2; ++
end) {
943 if(
trk[itk].VtxIndex[
end] != ivx)
continue;
944 unsigned short itj = 0;
945 if(
end == 1) itj =
trk[itk].TrjPos.size() - 1;
946 trk[itk].TrjDir[itj] = trkDir[fitTrk];
954 void CCTrackMaker::FillChgNear()
958 unsigned short wire, nwires, indx;
959 float dir, ctime, cx, chgWinLo, chgWinHi;
962 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
963 for(
unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
965 nwires = cls[ipl][icl].Length / 2;
966 if(nwires < 2)
continue;
968 if(nwires > 30) nwires = 30;
969 for(
unsigned short end = 0;
end < 2; ++
end) {
973 for(
unsigned short w = 0;
w < nwires; ++
w) {
974 wire = cls[ipl][icl].Wire[
end] + dir *
w;
975 cx = cls[ipl][icl].X[
end] + dir * w * cls[ipl][icl].Slope[
end] * fWirePitch;
976 ctime = detprop->ConvertXToTicks(cx, ipl, tpc, cstat);
977 chgWinLo = ctime - fChgWindow;
978 chgWinHi = ctime + fChgWindow;
979 indx = wire - firstWire[ipl];
980 if(WireHitRange[ipl][indx].first < 0)
continue;
981 unsigned int firhit = WireHitRange[ipl][indx].first;
982 unsigned int lashit = WireHitRange[ipl][indx].second;
983 for(
unsigned int hit = firhit;
hit < lashit; ++
hit) {
984 if(
hit > allhits.size() - 1) {
985 mf::LogError(
"CCTM")<<
"FillChgNear bad lashit "<<lashit<<
" size "<<allhits.size()<<
"\n";
988 if(allhits[
hit]->PeakTime() < chgWinLo)
continue;
989 if(allhits[
hit]->PeakTime() > chgWinHi)
continue;
990 cnear += allhits[
hit]->Integral();
993 cnear /= (float)(nwires-1);
994 if(cnear > cls[ipl][icl].Charge[
end]) {
995 cls[ipl][icl].ChgNear[
end] = ChgNorm[ipl] * cnear / cls[ipl][icl].Charge[
end];
997 cls[ipl][icl].ChgNear[
end] = 0;
1007 void CCTrackMaker::MakeFamily()
1011 unsigned short ivx, itr, ipl, ii, jtr;
1012 unsigned short nus, nds, nuhs, ndhs;
1013 float longUSTrk, longDSTrk, qual;
1017 float tgMuonCut2 = 9;
1021 unsigned short VtxIndex;
1022 unsigned short nUSTk;
1023 unsigned short nDSTk;
1024 unsigned short nUSHit;
1025 unsigned short nDSHit;
1030 std::vector<NuVtx> nuVtxCand;
1035 float best = 999, dx, dy, dz, dr;
1039 for(ivx = 0; ivx < vtx.size(); ++ivx) {
1040 vtx[ivx].Neutrino =
false;
1041 nus = 0; nds = 0; nuhs = 0; ndhs = 0;
1042 longUSTrk = 0; longDSTrk = 0;
1045 for(itr = 0; itr <
trk.size(); ++itr) {
1046 if(
trk[itr].ID < 0)
continue;
1047 if(
trk[itr].PDGCode != 13)
continue;
1048 for(itj = 0; itj <
trk[itr].TrjPos.size(); ++itj) {
1049 dx =
trk[itr].TrjPos[itj](0) - vtx[ivx].
X;
1050 dy =
trk[itr].TrjPos[itj](1) - vtx[ivx].
Y;
1051 dz =
trk[itr].TrjPos[itj](2) - vtx[ivx].
Z;
1052 dr = dx * dx + dy * dy + dz * dz;
1053 if(dr < tgMuonCut2) {
1061 if(skipVtx)
continue;
1062 for(itr = 0; itr <
trk.size(); ++itr) {
1063 if(
trk[itr].ID < 0)
continue;
1064 if(
trk[itr].VtxIndex[0] == ivx) {
1067 if(
trk[itr].Length > longDSTrk) longDSTrk =
trk[itr].Length;
1068 for(ipl = 0; ipl < nplanes; ++ipl) ndhs +=
trk[itr].TrkHits[ipl].size();
1073 if(
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] >= 0) {
1077 if(
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] < 0) {
1080 if(
trk[itr].Length > longUSTrk) longUSTrk =
trk[itr].Length;
1081 for(ipl = 0; ipl < nplanes; ++ipl) nuhs +=
trk[itr].TrkHits[ipl].size();
1085 if(skipVtx)
continue;
1086 if(nds == 0)
continue;
1087 qual = 1 / (float)nds;
1088 qual /= (float)ndhs;
1089 if(nus > 0) qual *= (float)nuhs / (
float)ndhs;
1094 if(nds > 0 && longDSTrk > 5) {
1096 aNuVtx.VtxIndex = ivx;
1099 aNuVtx.nUSHit = nuhs;
1100 aNuVtx.nDSHit = ndhs;
1101 aNuVtx.longUSTrk = longUSTrk;
1102 aNuVtx.longDSTrk = longDSTrk;
1104 nuVtxCand.push_back(aNuVtx);
1114 if(imbest < 0)
return;
1118 vtx[ivx].Neutrino =
true;
1121 pfpToTrkID.push_back(0);
1126 std::vector<unsigned short> dtrGen;
1127 std::vector<unsigned short> dtrNextGen;
1128 for(itr = 0; itr <
trk.size(); ++itr) {
1129 if(
trk[itr].ID < 0)
continue;
1130 if(
trk[itr].VtxIndex[0] == ivx) {
1134 trk[itr].PDGCode = 2212;
1135 pfpToTrkID.push_back(
trk[itr].ID);
1136 dtrGen.push_back(itr);
1138 if(
trk[itr].VtxIndex[1] == ivx) {
1142 trk[itr].PDGCode = 2212;
1143 pfpToTrkID.push_back(
trk[itr].ID);
1145 std::reverse(
trk[itr].TrjPos.begin(),
trk[itr].TrjPos.end());
1146 for(ii = 0; ii <
trk[itr].TrjDir.size(); ++ii)
1147 trk[itr].TrjDir[ii] = -
trk[itr].TrjDir[ii];
1151 if(dtrGen.size() == 0)
return;
1153 unsigned short tmp, indx;
1154 unsigned short nit = 0;
1162 for(ii = 0; ii < dtrGen.size(); ++ii) {
1164 if(
trk[itr].VtxIndex[1] >= 0) {
1166 ivx =
trk[itr].VtxIndex[1];
1168 for(jtr = 0; jtr <
trk.size(); ++jtr) {
1169 if(jtr == itr)
continue;
1170 if(
trk[jtr].VtxIndex[0] == ivx) {
1172 indx =
trk[itr].DtrID.size();
1173 trk[itr].DtrID.resize(indx + 1);
1174 trk[itr].DtrID[indx] = jtr;
1176 trk[jtr].MomID =
trk[itr].ID;
1178 trk[jtr].PDGCode = 211;
1179 dtrNextGen.push_back(jtr);
1180 pfpToTrkID.push_back(
trk[jtr].ID);
1182 if(
trk[jtr].VtxIndex[1] == ivx) {
1184 indx =
trk[itr].DtrID.size();
1185 trk[itr].DtrID.resize(indx + 1);
1186 trk[itr].DtrID[indx] = jtr;
1188 trk[jtr].MomID =
trk[itr].ID;
1190 trk[jtr].PDGCode = 211;
1191 dtrNextGen.push_back(jtr);
1192 pfpToTrkID.push_back(
trk[jtr].ID);
1194 std::reverse(
trk[jtr].TrjPos.begin(),
trk[jtr].TrjPos.end());
1195 for(
unsigned short jj = 0; jj <
trk[jtr].TrjDir.size(); ++jj)
1196 trk[jtr].TrjDir[jj] = -
trk[jtr].TrjDir[jj];
1198 tmp =
trk[jtr].VtxIndex[0];
1199 trk[jtr].VtxIndex[0] =
trk[jtr].VtxIndex[1];
1200 trk[jtr].VtxIndex[1] =
tmp;
1206 if(dtrNextGen.size() == 0)
break;
1207 dtrGen = dtrNextGen;
1213 void CCTrackMaker::TagCosmics()
1216 unsigned short ipf, itj;
1220 double local[3] = {0.,0.,0.};
1221 double world[3] = {0.,0.,0.};
1223 const geo::TPCGeo &thetpc = geom->TPC(tpc, cstat);
1225 float XLo = world[0] - geom->DetHalfWidth(tpc,cstat) + fFiducialCut;
1226 float XHi = world[0] + geom->DetHalfWidth(tpc,cstat) - fFiducialCut;
1227 float YLo = world[1] - geom->DetHalfHeight(tpc,cstat) + fFiducialCut;
1228 float YHi = world[1] + geom->DetHalfHeight(tpc,cstat) - fFiducialCut;
1229 float ZLo = world[2] - geom->DetLength(tpc,cstat)/2 + fFiducialCut;
1230 float ZHi = world[2] + geom->DetLength(tpc,cstat)/2 - fFiducialCut;
1232 bool startsIn, endsIn;
1234 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1236 if(
trk[itk].ID < 0)
continue;
1238 if(
trk[itk].Length < 10)
continue;
1241 for(ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
1242 if(pfpToTrkID[ipf] ==
trk[itk].ID) {
1247 if(skipit)
continue;
1249 if(
trk[itk].TrjPos[0](0) < XLo ||
trk[itk].TrjPos[0](0) > XHi) startsIn =
false;
1250 if(
trk[itk].TrjPos[0](1) < YLo ||
trk[itk].TrjPos[0](1) > YHi) startsIn =
false;
1251 if(
trk[itk].TrjPos[0](2) < ZLo ||
trk[itk].TrjPos[0](2) > ZHi) startsIn =
false;
1253 if(startsIn)
continue;
1255 itj =
trk[itk].TrjPos.size() - 1;
1256 if(
trk[itk].TrjPos[itj](0) < XLo ||
trk[itk].TrjPos[itj](0) > XHi) endsIn =
false;
1257 if(
trk[itk].TrjPos[itj](1) < YLo ||
trk[itk].TrjPos[itj](1) > YHi) endsIn =
false;
1258 if(
trk[itk].TrjPos[itj](2) < ZLo ||
trk[itk].TrjPos[itj](2) > ZHi) endsIn =
false;
1260 if(endsIn)
continue;
1262 trk[itk].PDGCode = 13;
1263 pfpToTrkID.push_back(
trk[itk].ID);
1266 if(fDeltaRayCut <= 0)
return;
1268 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1270 if(
trk[itk].PDGCode != 13)
continue;
1280 unsigned short ivx, ii, ipl, icl, jj, jpl, jcl, kk, kpl, kcl;
1281 short idir, iend, jdir, jend, kdir, kend, ioend;
1283 for(ivx = 0; ivx < vtx.size(); ++ivx) {
1286 for(ipl = 0; ipl < nplanes; ++ipl) {
1288 for(icl = 0; icl < clsChain[ipl].size(); ++icl) {
1289 if(clsChain[ipl][icl].InTrack >= 0)
continue;
1290 for(iend = 0; iend < 2; ++iend) {
1291 if(clsChain[ipl][icl].VtxIndex[iend] == vtx[ivx].EvtIndex) vxCls[ipl].push_back(icl);
1298 myprt<<
"VtxMatch: Vertex ID "<<vtx[ivx].EvtIndex<<
"\n";
1299 for(ipl = 0; ipl < nplanes; ++ipl) {
1300 myprt<<
"ipl "<<ipl<<
" cls";
1301 for(
unsigned short ii = 0; ii < vxCls[ipl].size(); ++ii) myprt<<
" "<<vxCls[ipl][ii];
1309 for(ipl = 0; ipl < nplanes; ++ipl) {
1310 if(nplanes == 2 && ipl > 0)
continue;
1311 for(ii = 0; ii < vxCls[ipl].size(); ++ii) {
1312 icl = vxCls[ipl][ii];
1314 if(clsChain[ipl][icl].InTrack >= 0)
continue;
1315 jpl = (ipl + 1) % nplanes;
1316 kpl = (jpl + 1) % nplanes;
1317 for(jj = 0; jj < vxCls[jpl].size(); ++jj) {
1318 jcl = vxCls[jpl][jj];
1319 if(clsChain[jpl][jcl].InTrack >= 0)
continue;
1320 for(iend = 0; iend < 2; ++iend) {
1321 if(clsChain[ipl][icl].VtxIndex[iend] != vtx[ivx].EvtIndex)
continue;
1323 idir = clsChain[ipl][icl].Dir[iend];
1324 for(jend = 0; jend < 2; ++jend) {
1325 if(clsChain[jpl][jcl].VtxIndex[jend] != vtx[ivx].EvtIndex)
continue;
1326 jdir = clsChain[jpl][jcl].Dir[jend];
1327 if(idir != 0 && jdir != 0 && idir != jdir)
continue;
1329 if(fabs(clsChain[jpl][jcl].
X[1 - jend] - clsChain[ipl][icl].
X[ioend]) > 50)
continue;
1331 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
1332 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
1333 match.
Vtx = ivx; match.
oVtx = -1;
1335 match.
Err = 1E6; match.
oErr = 1E6;
1338 FillEndMatch2(match);
1340 if(match.
Err + match.
oErr > 100)
continue;
1341 if(DupMatch(match))
continue;
1342 matcomb.push_back(match);
1345 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
1346 if(prt)
mf::LogVerbatim(
"CCTM")<<
"VtxMatch: check "<<ipl<<
":"<<icl<<
":"<<iend<<
" and "<<jpl<<
":"<<jcl<<
":"<<jend<<
" for cluster in kpl "<<kpl;
1348 for(kk = 0; kk < vxCls[kpl].size(); ++kk) {
1349 kcl = vxCls[kpl][kk];
1350 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
1351 for(kend = 0; kend < 2; ++kend) {
1352 kdir = clsChain[kpl][kcl].Dir[kend];
1353 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
1354 if(clsChain[kpl][kcl].VtxIndex[kend] != vtx[ivx].EvtIndex)
continue;
1357 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
1359 if(DupMatch(match))
continue;
1360 FillEndMatch(match);
1363 if(match.
Chg[kpl] <= 0)
continue;
1364 if(match.
Err + match.
oErr > 100)
continue;
1366 if(DupMatch(match))
continue;
1367 matcomb.push_back(match);
1372 if(gotkcl)
continue;
1376 unsigned short kbend = 0;
1377 if(prt)
mf::LogVerbatim(
"CCTM")<<
"VtxMatch: look for missed cluster chain in kpl";
1378 for(kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
1379 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
1380 for(kend = 0; kend < 2; ++kend) {
1381 kdir = clsChain[kpl][kcl].Dir[kend];
1382 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
1383 if(clsChain[kpl][kcl].VtxIndex[kend] >= 0)
continue;
1385 if(fabs(clsChain[kpl][kcl].
X[kend] - vtx[ivx].
X) > 5)
continue;
1387 if(fabs(clsChain[kpl][kcl].X[1 - kend] - clsChain[ipl][icl].X[ioend]) > 50)
continue;
1389 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
1390 if(DupMatch(match))
continue;
1391 FillEndMatch(match);
1392 totErr = match.
Err + match.
oErr;
1395 myprt<<
"VtxMatch: Chk missing cluster match ";
1396 for(
unsigned short ii = 0; ii < nplanes; ++ii)
1397 myprt<<
" "<<ii<<
":"<<match.
Cls[ii]<<
":"<<match.
End[ii];
1398 myprt<<
" Err "<<match.
Err<<
"\n";
1400 if(totErr > 100)
continue;
1410 match.
Cls[kpl] = kbst; match.
End[kpl] = kbend;
1411 FillEndMatch(match);
1412 matcomb.push_back(match);
1414 clsChain[kpl][kbst].VtxIndex[kbend] = ivx;
1416 vxCls[kpl].push_back(kbst);
1419 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
1420 if(DupMatch(match))
continue;
1421 FillEndMatch(match);
1422 if(match.
Err + match.
oErr < 100) matcomb.push_back(match);
1430 if(matcomb.size() == 0)
continue;
1431 SortMatches(fmCluHits, 1);
1435 for(ipl = 0; ipl < 3; ++ipl) vxCls[ipl].
clear();
1440 void CCTrackMaker::FindMaybeVertices()
1445 unsigned short ipl, icl,
end, ivx, oend;
1446 float best, dWire, dX;
1449 if(vtx.size() == 0)
return;
1451 for(ipl = 0; ipl < nplanes; ++ipl) {
1452 for(icl = 0; icl < cls[ipl].size(); ++icl) {
1453 for(end = 0; end < 2; ++
end) {
1455 if(cls[ipl][icl].VtxIndex[end] >= 0)
continue;
1460 for(ivx = 0; ivx < vtx.size(); ++ ivx) {
1462 if(cls[ipl][icl].VtxIndex[oend] == ivx)
continue;
1463 dWire = geom->WireCoordinate(vtx[ivx].
Y, vtx[ivx].
Z, ipl, tpc, cstat) - cls[ipl][icl].Wire[
end];
1471 if(dWire > 30 || dWire < -2)
continue;
1473 if(dWire < -30 || dWire > 2)
continue;
1476 dX = fabs(cls[ipl][icl].
X[end] + cls[ipl][icl].Slope[end] * fWirePitch * dWire - vtx[ivx].
X);
1485 cls[ipl][icl].VtxIndex[
end] = ibstvx;
1486 cls[ipl][icl].mVtxIndex[
end] = ibstvx;
1498 unsigned short ipl, icl, icl1, icl2;
1499 float dw, dx, dWCut, dw1Max, dw2Max;
1500 float dA, dA2, dACut = fMaxDAng, chgAsymCut;
1501 float dXCut, chgasym, mrgErr;
1504 bool gotprt =
false;
1505 for(ipl = 0; ipl < nplanes; ++ipl) {
1506 if(cls[ipl].size() > 1) {
1507 for(icl1 = 0; icl1 < cls[ipl].size() - 1; ++icl1) {
1508 prt = (fDebugAlg == 666 && ipl == fDebugPlane && icl1 == fDebugCluster);
1509 if(prt) gotprt =
true;
1511 dw1Max = 0.6 * cls[ipl][icl1].Length;
1512 ls1 = (cls[ipl][icl1].Length > 100 && fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl1].Angle[1]) < 0.04);
1513 for(icl2 = icl1 + 1; icl2 < cls[ipl].size(); ++icl2) {
1514 ls2 = (cls[ipl][icl2].Length > 100 && fabs(cls[ipl][icl2].Angle[0] - cls[ipl][icl2].Angle[1]) < 0.04);
1515 dw2Max = 0.6 * cls[ipl][icl2].Length;
1518 if(dw2Max < dWCut) dWCut = dw2Max;
1520 if(dWCut > 100) dWCut = 100;
1521 if(dWCut < 2) dWCut = 2;
1522 chgAsymCut = fMergeChgAsym;
1525 if(prt)
mf::LogVerbatim(
"CCTM")<<
"MCC P:C:W icl1 "<<ipl<<
":"<<icl1<<
":"<<cls[ipl][icl1].Wire[1]<<
" vtx "<<cls[ipl][icl1].VtxIndex[1]<<
" ls1 "<<ls1<<
" icl2 "<<ipl<<
":"<<icl2<<
":"<<cls[ipl][icl2].Wire[0]<<
" vtx "<<cls[ipl][icl2].VtxIndex[0]<<
" ls2 "<<ls2<<
" dWCut "<<dWCut;
1526 if(std::abs(cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]) > dWCut)
continue;
1530 float af = AngleFactor(cls[ipl][icl1].Slope[1]);
1531 dACut = fMaxDAng * af;
1532 dXCut = fChainMaxdX * 5 * af;
1533 dA = fabs(cls[ipl][icl1].Angle[1] - cls[ipl][icl2].Angle[0]);
1536 dA2 = fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl2].Angle[1]);
1538 if(prt)
mf::LogVerbatim(
"CCTM")<<
" dA "<<dA<<
" dA2 "<<dA2<<
" DACut "<<dACut<<
" dXCut "<<dXCut;
1540 if(dA2 < dA) dA = dA2;
1543 if(dA < fChainVtxAng && cls[ipl][icl1].VtxIndex[1] >= 0) {
1544 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1545 dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1546 unsigned short ivx = cls[ipl][icl1].VtxIndex[1];
1547 if(vtx[ivx].nClusInPln[ipl] == 2 && fabs(dx) < 1) {
1548 cls[ipl][icl1].VtxIndex[1] = -2;
1549 cls[ipl][icl2].VtxIndex[0] = -2;
1550 vtx[ivx].nClusInPln[ipl] = 0;
1556 if(cls[ipl][icl1].VtxIndex[1] >= 0)
continue;
1557 if(cls[ipl][icl2].VtxIndex[0] >= 0)
continue;
1560 if(cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1] < 3 &&
1561 (cls[ipl][icl1].Length < 3 || cls[ipl][icl2].Length < 3) ) {
1569 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1571 dx = cls[ipl][icl2].X[0] - cls[ipl][icl1].X[1];
1572 float dA3 = std::abs(atan(dx / dw) - cls[ipl][icl1].Angle[1]);
1574 if(dA3 > dA) dA = dA3;
1578 if(dA > dACut)
continue;
1580 if(prt)
mf::LogVerbatim(
"CCTM")<<
" rough dX "<<fabs(cls[ipl][icl1].
X[1] - cls[ipl][icl2].
X[0])<<
" cut = 20";
1583 if(fabs(cls[ipl][icl1].X[1] - cls[ipl][icl2].X[0]) > 20)
continue;
1588 if(dA > fChainVtxAng)
continue;
1590 chgasym = fabs(cls[ipl][icl1].Charge[1] - cls[ipl][icl2].Charge[0]);
1591 chgasym /= cls[ipl][icl1].Charge[1] + cls[ipl][icl2].Charge[0];
1592 if(prt)
mf::LogVerbatim(
"CCTM")<<
" chgasym "<<chgasym<<
" cut "<<chgAsymCut;
1593 if(chgasym > chgAsymCut)
continue;
1596 if(cls[ipl][icl1].Length > cls[ipl][icl2].Length) {
1597 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1598 dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1600 dw = fWirePitch * (cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]);
1601 dx = cls[ipl][icl2].X[0] + cls[ipl][icl2].Slope[0] * dw * fWirePitch - cls[ipl][icl1].X[1];
1605 if(dA2 < 0.01 && abs(dx) > dXCut && dx < -1) {
1606 dx = dXClTraj(fmCluHits, ipl, icl1, 1, icl2);
1610 if(prt)
mf::LogVerbatim(
"CCTM")<<
" X0 "<<cls[ipl][icl1].X[1]<<
" slp "<<cls[ipl][icl1].Slope[1]<<
" dw "<<dw<<
" oX "<<cls[ipl][icl2].X[0]<<
" dx "<<dx<<
" cut "<<dXCut;
1612 if(fabs(dx) > dXCut)
continue;
1615 float xerr = dx / dXCut;
1616 float aerr = dA / dACut;
1617 mrgErr = xerr * xerr + aerr * aerr;
1619 if(prt)
mf::LogVerbatim(
"CCTM")<<
"icl1 mrgErr "<<mrgErr<<
" MergeError "<<cls[ipl][icl1].MergeError[1]<<
" 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;
1631 cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1633 if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1634 cls[ipl][ocl].BrkIndex[1] = -1;
1635 cls[ipl][ocl].MergeError[1] = fMaxMergeError;
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;
1647 cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1649 if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1650 cls[ipl][ocl].BrkIndex[1] = -1;
1651 cls[ipl][ocl].MergeError[1] = fMaxMergeError;
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;
1674 if(fabs(cls[ipl][icl1].Angle[
end]) < 1)
continue;
1676 if(fabs(cls[ipl][icl2].Angle[end]) < 1)
continue;
1677 if(prt)
mf::LogVerbatim(
"CCTM")<<
"BrokenC: clusters "<<cls[ipl][icl1].Wire[
end]<<
":"<<(int)cls[ipl][icl1].Time[end]<<
" "<<cls[ipl][icl2].Wire[end]<<
":"<<(
int)cls[ipl][icl2].Time[
end]<<
" angles "<<cls[ipl][icl1].Angle[
end]<<
" "<<cls[ipl][icl2].Angle[
end]<<
" dWire "<<fabs(cls[ipl][icl1].Wire[end] - cls[ipl][icl2].Wire[end]);
1678 if(fabs(cls[ipl][icl1].Wire[end] - cls[ipl][icl2].Wire[end]) > 5)
continue;
1681 float dsl = cls[ipl][icl2].Slope[
end] - cls[ipl][icl1].Slope[
end];
1682 float fvw = (cls[ipl][icl1].X[
end] - cls[ipl][icl1].Wire[
end] * cls[ipl][icl1].Slope[
end] - cls[ipl][icl2].X[
end] + cls[ipl][icl2].Wire[
end] * cls[ipl][icl2].Slope[
end]) / dsl;
1684 if(fabs(cls[ipl][icl1].Wire[end] - fvw) > 4)
continue;
1685 if(fabs(cls[ipl][icl2].Wire[end] - fvw) > 4)
continue;
1686 cls[ipl][icl1].BrkIndex[
end] = icl2;
1688 cls[ipl][icl1].MergeError[
end] = 1;
1689 cls[ipl][icl2].BrkIndex[
end] = icl1;
1690 cls[ipl][icl2].MergeError[
end] = 1;
1692 dx = fabs(cls[ipl][icl1].
X[end] - cls[ipl][icl2].
X[end]);
1693 if(prt)
mf::LogVerbatim(
"CCTM")<<
"BrokenC: icl1:W "<<icl1<<
":"<<cls[ipl][icl1].Wire[
end]<<
" icl2:W "<<icl2<<
":"<<cls[ipl][icl2].Wire[
end]<<
" end "<<end<<
" dx "<<dx;
1702 unsigned short end, mom, momBrkEnd, dtrBrkEnd, nit;
1705 std::vector<bool> gotcl(cls[ipl].size());
1706 for(icl = 0; icl < cls[ipl].size(); ++icl) gotcl[icl] =
false;
1707 if(prt)
mf::LogVerbatim(
"CCTM")<<
"ipl "<<ipl<<
" cls.size() "<<cls[ipl].size()<<
"\n";
1709 std::vector<unsigned short> sCluster;
1710 std::vector<unsigned short> sOrder;
1711 for(icl = 0; icl < cls[ipl].size(); ++icl) {
1714 if(gotcl[icl])
continue;
1716 if(cls[ipl][icl].BrkIndex[0] >= 0 && cls[ipl][icl].BrkIndex[1] >= 0)
continue;
1717 for(end = 0; end < 2; ++
end) {
1718 if(cls[ipl][icl].BrkIndex[end] < 0)
continue;
1719 if(cls[ipl][icl].MergeError[end] > fMergeErrorCut)
continue;
1724 sCluster.push_back(mom);
1725 if(momBrkEnd == 1) {
1727 sOrder.push_back(0);
1730 sOrder.push_back(1);
1732 dtr = cls[ipl][icl].BrkIndex[
end];
1735 while(dtr >= 0 && dtr < (
short)cls[ipl].size() && nit < cls[ipl].size()) {
1737 for(dtrBrkEnd = 0; dtrBrkEnd < 2; ++dtrBrkEnd)
if(cls[ipl][dtr].BrkIndex[dtrBrkEnd] == mom)
break;
1738 if(dtrBrkEnd == 2) {
1744 if(cls[ipl][dtr].MergeError[dtrBrkEnd] < fMergeErrorCut) {
1745 sCluster.push_back(dtr);
1746 sOrder.push_back(dtrBrkEnd);
1754 momBrkEnd = 1 - dtrBrkEnd;
1756 dtr = cls[ipl][mom].BrkIndex[momBrkEnd];
1759 if(dtrBrkEnd == 2)
continue;
1764 sCluster.push_back(icl);
1765 sOrder.push_back(0);
1768 if(sCluster.size() == 0) {
1769 mf::LogError(
"CCTM")<<
"MakeClusterChains error in plane "<<ipl<<
" cluster "<<icl;
1779 unsigned short jcl = sCluster[0];
1780 if(jcl > cls[ipl].size()) std::cout<<
"oops MCC\n";
1781 unsigned short oend;
1782 for(end = 0; end < 2; ++
end) {
1784 if(sOrder[0] > 0) oend = 1 -
end;
1785 ccp.
Wire[
end] = cls[ipl][jcl].Wire[oend];
1786 ccp.
Time[
end] = cls[ipl][jcl].Time[oend];
1787 ccp.
X[
end] = cls[ipl][jcl].X[oend];
1788 ccp.
Slope[
end] = cls[ipl][jcl].Slope[oend];
1789 ccp.
Angle[
end] = cls[ipl][jcl].Angle[oend];
1790 ccp.
Dir[
end] = cls[ipl][icl].Dir[oend];
1792 ccp.
ChgNear[
end] = cls[ipl][jcl].ChgNear[oend];
1795 ccp.
Length = cls[ipl][icl].Length;
1796 ccp.
TotChg = cls[ipl][icl].TotChg;
1800 for(
unsigned short ii = 1; ii < sCluster.size(); ++ii) {
1802 if(jcl > cls[ipl].size()) std::cout<<
"oops MCC\n";
1805 if(end > 1) std::cout<<
"oops2 MCC\n";
1808 ccp.
Wire[1] = cls[ipl][jcl].Wire[oend];
1809 ccp.
Time[1] = cls[ipl][jcl].Time[oend];
1810 ccp.
X[1] = cls[ipl][jcl].X[oend];
1811 ccp.
Slope[1] = cls[ipl][jcl].Slope[oend];
1812 ccp.
Angle[1] = cls[ipl][jcl].Angle[oend];
1813 ccp.
Dir[1] = cls[ipl][jcl].Dir[oend];
1814 ccp.
VtxIndex[1] = cls[ipl][jcl].VtxIndex[oend];
1815 ccp.
ChgNear[1] = cls[ipl][jcl].ChgNear[oend];
1816 ccp.
mBrkIndex[1] = cls[ipl][jcl].BrkIndex[oend];
1817 ccp.
Length += cls[ipl][jcl].Length;
1818 ccp.
TotChg += cls[ipl][jcl].TotChg;
1825 ccp.
Dir[0] = 1; ccp.
Dir[1] = -1;
1827 ccp.
Dir[0] = -1; ccp.
Dir[1] = 1;
1829 clsChain[ipl].push_back(ccp);
1834 unsigned short brkCls;
1836 for(
unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
1837 for(
unsigned short end = 0; end < 2; ++
end) {
1838 if(clsChain[ipl][ccl].mBrkIndex[end] < 0)
continue;
1839 brkCls = clsChain[ipl][ccl].mBrkIndex[
end];
1842 for(
unsigned short ccl2 = 0; ccl2 < clsChain[ipl].size(); ++ccl2) {
1843 if(ccl2 == ccl)
continue;
1844 if(std::find(clsChain[ipl][ccl2].ClsIndex.begin(), clsChain[ipl][ccl2].ClsIndex.end(), brkCls) == clsChain[ipl][ccl2].ClsIndex.end())
continue;
1846 clsChain[ipl][ccl].mBrkIndex[
end] = ccl2;
1851 if(!gotit)
mf::LogError(
"CCTM")<<
"MCC: Cluster chain "<<ccl<<
" end "<<end<<
" Failed to find brkCls "<<brkCls<<
" in plane "<<ipl;
1864 float CCTrackMaker::dXClTraj(
art::FindManyP<recob::Hit> const& fmCluHits,
unsigned short ipl,
unsigned short icl1,
unsigned short end1,
unsigned short icl2)
1867 float dw, dx, best = 999;
1868 std::vector<art::Ptr<recob::Hit>> clusterhits = fmCluHits.at(cls[ipl][icl1].EvtIndex);
1869 for(
unsigned short hit = 0;
hit < clusterhits.size(); ++
hit) {
1870 dw = clusterhits[
hit]->WireID().Wire - cls[ipl][icl1].Wire[end1];
1871 dx = fabs(cls[ipl][icl1].Time[end1] + dw * fWirePitch * cls[ipl][icl1].Slope[end1] - clusterhits[
hit]->PeakTime());
1872 if(dx < best) best = dx;
1873 if(dx < 0.01)
break;
1880 unsigned short imat,
unsigned short procCode)
1886 if(imat > matcomb.size() - 1) {
1892 unsigned short nhitinpl = 0;
1893 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl)
if(trkHits[ipl].size() > 1) ++nhitinpl;
1895 mf::LogError(
"CCTM")<<
"StoreTrack: Not enough hits in each plane\n";
1898 if(prt)
mf::LogVerbatim(
"CCTM")<<
"In StoreTrack: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
1901 std::array<std::vector<geo::WireID>,3> trkWID;
1902 std::array<std::vector<double>,3> trkX;
1903 std::array<std::vector<double>,3> trkXErr;
1906 std::vector<TVector3> trkPos;
1907 std::vector<TVector3> trkDir;
1909 newtrk.
ID =
trk.size() + 1;
1910 newtrk.
Proc = procCode;
1919 newtrk.
EndInTPC = {{
false,
false}};
1920 newtrk.
GoodEnd = {{
false,
false}};
1924 unsigned short ipl, icl, iht;
1926 if(prt)
mf::LogVerbatim(
"CCTM")<<
"CCTM: Make traj for track "<<newtrk.
ID<<
" procCode "<<procCode<<
" nhits in planes "<<trkHits[0].size()<<
" "<<trkHits[1].size()<<
" "<<trkHits[2].size();
1929 trkWID[2].resize(0);
1931 trkXErr[2].resize(0);
1933 for(ipl = 0; ipl < nplanes; ++ipl) {
1934 trkWID[ipl].resize(trkHits[ipl].size());
1935 trkX[ipl].resize(trkHits[ipl].size());
1936 trkXErr[ipl].resize(trkHits[ipl].size());
1937 for(iht = 0; iht < trkHits[ipl].size(); ++iht) {
1938 trkWID[ipl][iht] = trkHits[ipl][iht]->WireID();
1939 trkX[ipl][iht] = detprop->ConvertTicksToX(trkHits[ipl][iht]->PeakTime(),ipl, tpc, cstat);
1940 trkXErr[ipl][iht] = fHitFitErrFac * trkHits[ipl][iht]->RMS() * trkHits[ipl][iht]->Multiplicity();
1944 fTrackTrajectoryAlg.TrackTrajectory(trkWID, trkX, trkXErr, trkPos, trkDir);
1945 if(trkPos.size() < 2) {
1946 mf::LogError(
"CCTM")<<
"StoreTrack: No trajectory points on failed track "<<newtrk.
ID 1947 <<
" in StoreTrack: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
1957 if(prt)
mf::LogVerbatim(
"CCTM")<<
" number of traj points "<<trkPos.size();
1961 unsigned short end, nClose, indx, jndx;
1963 for(end = 0; end < 2; ++
end) {
1965 for(ipl = 0; ipl < nplanes - 1; ++ipl) {
1966 if(trkX[ipl].size() == 0)
continue;
1967 for(
unsigned short jpl = ipl + 1; jpl < nplanes; ++jpl) {
1968 if(trkX[jpl].size() == 0)
continue;
1973 indx = trkXErr[ipl].size() - 1;
1974 jndx = trkXErr[jpl].size() - 1;
1976 xErr = 3 * (trkXErr[ipl][indx] + trkXErr[jpl][jndx]);
1977 if(std::abs(trkX[ipl][indx] - trkX[jpl][jndx]) < xErr) ++nClose;
1980 if(nClose == nplanes) newtrk.
GoodEnd[
end] =
true;
1984 unsigned short ivx, itj, ccl;
1985 float dx, dy, dz, dr0, dr1;
1986 unsigned short attachEnd;
1987 for(end = 0; end < 2; ++
end) {
1989 if(end == 0 && matcomb[imat].Vtx >= 0) ivx = matcomb[imat].Vtx;
1990 if(end == 1 && matcomb[imat].oVtx >= 0) ivx = matcomb[imat].oVtx;
1991 if(ivx == USHRT_MAX)
continue;
1994 dx = vtx[ivx].X - newtrk.
TrjPos[itj](0);
1995 dy = vtx[ivx].Y - newtrk.
TrjPos[itj](1);
1996 dz = vtx[ivx].Z - newtrk.
TrjPos[itj](2);
1997 dr0 = dx*dx + dy*dy + dz*dz;
1998 itj = newtrk.
TrjPos.size() - 1;
1999 dx = vtx[ivx].X - newtrk.
TrjPos[itj](0);
2000 dy = vtx[ivx].Y - newtrk.
TrjPos[itj](1);
2001 dz = vtx[ivx].Z - newtrk.
TrjPos[itj](2);
2002 dr1 = dx*dx + dy*dy + dz*dz;
2013 newtrk.
TrjPos[itj](0) = vtx[ivx].
X;
2014 newtrk.
TrjPos[itj](1) = vtx[ivx].
Y;
2015 newtrk.
TrjPos[itj](2) = vtx[ivx].
Z;
2021 newtrk.
TrjDir[0] = dir.Unit();
2024 newtrk.
TrjDir[itj] = dir.Unit();
2029 mf::LogError(
"CCTM")<<
"StoreTrack: Trying to attach a vertex to both ends of a track. imat = "<<imat;
2037 for(
unsigned short itj = 1; itj < newtrk.
TrjPos.size(); ++itj) {
2041 norm = sqrt(X*X + Y*Y + Z*Z);
2047 for(ipl = 0; ipl < nplanes; ++ipl) {
2048 if(matcomb[imat].Cls[ipl] < 0)
continue;
2049 ccl = matcomb[imat].Cls[ipl];
2050 if(ccl > clsChain[ipl].size()) std::cout<<
"oops StoreTrack\n";
2051 clsChain[ipl][ccl].InTrack = newtrk.
ID;
2052 for(
unsigned short icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
2053 icl = clsChain[ipl][ccl].ClsIndex[icc];
2054 if(icl > cls[ipl].size()) std::cout<<
"oops StoreTrack\n";
2055 cls[ipl][icl].InTrack = newtrk.
ID;
2056 if(cls[ipl][icl].EvtIndex > fmCluHits.size() - 1) {
2057 std::cout<<
"ooops2 store track EvtIndex "<<cls[ipl][icl].EvtIndex<<
" size "<<fmCluHits.size()<<
" icl "<<icl<<
"\n";
2064 if(prt)
mf::LogVerbatim(
"CCTM")<<
" track ID "<<newtrk.
ID<<
" stored in StoreTrack";
2066 trk.push_back(newtrk);
2186 float kSlp, kAng,
kX, kWir, okWir;
2187 short idir, ioend, jdir, joend, kdir;
2190 float tpcSizeY = geom->DetHalfWidth();
2191 float tpcSizeZ = geom->DetLength();
2203 std::array<float, 3> mchg;
2205 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2206 for(
unsigned short icl = 0; icl < clsChain[ipl].size(); ++icl) {
2207 if(clsChain[ipl][icl].InTrack >= 0)
continue;
2209 if(clsChain[ipl][icl].Length < fMatchMinLen[algIndex])
continue;
2210 unsigned short jpl = (ipl + 1) % nplanes;
2211 unsigned short kpl = (jpl + 1) % nplanes;
2212 for(
unsigned short jcl = 0; jcl < clsChain[jpl].size(); ++jcl) {
2213 if(clsChain[jpl][jcl].InTrack >= 0)
continue;
2215 if(clsChain[jpl][jcl].Length < fMatchMinLen[algIndex])
continue;
2217 mchg[0] = clsChain[ipl][icl].TotChg;
2218 mchg[1] = clsChain[jpl][jcl].TotChg;
2220 if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5)
continue;
2221 for(
unsigned short iend = 0; iend < 2; ++iend) {
2222 idir = clsChain[ipl][icl].Dir[iend];
2223 for(
unsigned short jend = 0; jend < 2; ++jend) {
2224 jdir = clsChain[jpl][jcl].Dir[jend];
2225 if(idir != 0 && jdir != 0 && idir != jdir)
continue;
2227 if(fabs(clsChain[ipl][icl].
X[iend] - clsChain[jpl][jcl].
X[jend]) > dxcut)
continue;
2228 ioend = 1 - iend; joend = 1 - jend;
2230 kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2233 geom->IntersectionPoint((
unsigned int)(0.5+clsChain[ipl][icl].Wire[iend]),
2234 (
unsigned int)(0.5+clsChain[jpl][jcl].Wire[jend]),
2235 ipl, jpl, cstat, tpc, yp, zp);
2236 if(yp > tpcSizeY || yp < -tpcSizeY)
continue;
2237 if(zp < 0 || zp > tpcSizeZ)
continue;
2238 kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2239 kWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2241 geom->IntersectionPoint((
unsigned int)(0.5+clsChain[ipl][icl].Wire[ioend]),
2242 (
unsigned int)(0.5+clsChain[jpl][jcl].Wire[joend]),
2243 ipl, jpl, cstat, tpc, yp, zp);
2244 if(yp > tpcSizeY || yp < -tpcSizeY)
continue;
2245 if(zp < 0 || zp > tpcSizeZ)
continue;
2246 okWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2247 if(prt)
mf::LogVerbatim(
"CCTM")<<
"PlnMatch: chk i "<<ipl<<
":"<<icl<<
":"<<iend
2248 <<
" idir "<<idir<<
" X "<<clsChain[ipl][icl].X[iend]<<
" j "<<jpl<<
":"<<jcl<<
":"<<jend
2249 <<
" jdir "<<jdir<<
" X "<<clsChain[jpl][jcl].X[jend];
2251 if(prt)
mf::LogVerbatim(
"CCTM")<<
"PlnMatch: chk j "<<ipl<<
":"<<icl<<
":"<<iend
2252 <<
" "<<jpl<<
":"<<jcl<<
":"<<jend<<
" iSlp "<<std::setprecision(2)<<clsChain[ipl][icl].Slope[iend]
2253 <<
" jSlp "<<std::setprecision(2)<<clsChain[jpl][jcl].Slope[jend]<<
" kWir "<<(int)kWir
2254 <<
" okWir "<<(
int)okWir<<
" kSlp "<<std::setprecision(2)<<kSlp<<
" kAng " 2255 <<std::setprecision(2)<<kAng<<
" kX "<<std::setprecision(1)<<
kX;
2259 ignoreSign = (fabs(kSlp) > 1.5);
2260 if(ignoreSign) kAng = fabs(kAng);
2261 dxkcut = dxcut * AngleFactor(kSlp);
2262 bool gotkcl =
false;
2263 for(
unsigned short kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
2264 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
2266 mchg[0] = clsChain[ipl][icl].TotChg;
2267 mchg[1] = clsChain[jpl][jcl].TotChg;
2268 mchg[2] = clsChain[kpl][kcl].TotChg;
2269 if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5)
continue;
2270 for(
unsigned short kend = 0; kend < 2; ++kend) {
2271 kdir = clsChain[kpl][kcl].Dir[kend];
2272 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
2274 <<
" dx "<<std::abs(clsChain[kpl][kcl].
X[kend] - kX)<<
" dxkcut "<<dxkcut;
2275 if(std::abs(clsChain[kpl][kcl].
X[kend] - kX) > dxkcut)
continue;
2278 <<
" dw "<<(clsChain[kpl][kcl].Wire[kend] - kWir)<<
" ignoreSign "<<ignoreSign;
2279 if(fabs(clsChain[kpl][kcl].Wire[kend] - kWir) > dwcut)
continue;
2282 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
2283 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
2284 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
2286 if(DupMatch(match))
continue;
2287 match.
Chg[ipl] = 0; match.
Chg[jpl] = 0; match.
Chg[kpl] = 0;
2288 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2290 FillEndMatch(match);
2292 <<
":"<<match.
End[kpl]<<
" oChg "<<match.
Chg[kpl]<<
" mErr "<<match.
Err<<
" oErr "<<match.
oErr;
2293 if(match.
Chg[kpl] == 0)
continue;
2294 if(match.
Err > 10 || match.
oErr > 10)
continue;
2296 if(DupMatch(match))
continue;
2297 matcomb.push_back(match);
2305 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
2306 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
2307 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
2309 if(DupMatch(match))
continue;
2310 match.
Chg[ipl] = 0; match.
Chg[jpl] = 0; match.
Chg[kpl] = 0;
2311 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2313 FillEndMatch(match);
2314 if(prt)
mf::LogVerbatim(
"CCTM")<<
" Tried 2-plane match"<<
" k "<<kpl<<
":"<<match.
Cls[kpl]
2315 <<
":"<<match.
End[kpl]<<
" Chg "<<match.
Chg[kpl]<<
" Err "<<match.
Err<<
" match.oErr "<<match.
oErr;
2316 if(match.
Chg[kpl] <= 0)
continue;
2317 if(match.
Err > 10 || match.
oErr > 10)
continue;
2318 matcomb.push_back(match);
2326 if(matcomb.size() == 0)
return;
2334 unsigned short nMatCl, nMiss;
2335 float toterr = match.
Err + match.
oErr;
2336 for(
unsigned int imat = 0; imat < matcomb.size(); ++imat) {
2338 if(match.
Cls[0] == matcomb[imat].Cls[0] &&
2339 match.
Cls[1] == matcomb[imat].Cls[1] &&
2340 match.
Cls[2] == matcomb[imat].Cls[2]) {
2343 if(toterr < matcomb[imat].Err + matcomb[imat].oErr) {
2345 matcomb[imat].End[0] = match.
End[0];
2346 matcomb[imat].End[1] = match.
End[1];
2347 matcomb[imat].End[2] = match.
End[2];
2348 matcomb[imat].Vtx = match.
Vtx;
2349 matcomb[imat].dWir = match.
dWir;
2350 matcomb[imat].dAng = match.
dAng;
2351 matcomb[imat].dX = match.
dX;
2352 matcomb[imat].Err = match.
Err;
2353 matcomb[imat].oVtx = match.
oVtx;
2354 matcomb[imat].odWir = match.
odWir;
2355 matcomb[imat].odAng = match.
odAng;
2356 matcomb[imat].odX = match.
odX;
2357 matcomb[imat].oErr = match.
oErr;
2364 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2365 if(match.
Cls[ipl] >= 0) {
2366 if(match.
Cls[ipl] == matcomb[imat].Cls[ipl] && (match.
End[0] == matcomb[imat].End[0] || match.
End[1] == matcomb[imat].End[1])) ++nMatCl;
2371 if(nMatCl == 2 && nMiss == 1)
return true;
2382 std::vector<CluLen> materr;
2383 unsigned int ii, im;
2385 if(matcomb.size() == 0)
return;
2388 for(ii = 0; ii < matcomb.size(); ++ii) {
2390 merr.
length = matcomb[ii].Err + matcomb[ii].oErr;
2391 materr.push_back(merr);
2393 std::sort(materr.begin(), materr.end(),
lessThan);
2397 myprt<<
"SortMatches\n";
2398 myprt<<
" ii im Vx Err dW dA dX oVx oErr odW odA odX Asym icl jcl kcl \n";
2399 for(ii = 0; ii < materr.size(); ++ii) {
2400 im = materr[ii].index;
2401 float asym = fabs(matcomb[im].Chg[0] - matcomb[im].Chg[1]) /
2402 (matcomb[im].Chg[0] + matcomb[im].Chg[1]);
2403 asym *= fabs(matcomb[im].Chg[1] - matcomb[im].Chg[2]) /
2404 (matcomb[im].Chg[1] + matcomb[im].Chg[2]);
2406 <<std::setw(5)<<ii<<std::setw(5)<<im
2407 <<std::setw(4)<<matcomb[im].Vtx
2408 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].Err
2409 <<std::setw(7)<<std::setprecision(1)<<matcomb[im].dWir
2410 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dAng
2411 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dX
2412 <<std::setw(4)<<matcomb[im].oVtx
2413 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].oErr
2414 <<std::setw(7)<<std::setprecision(1)<<matcomb[im].odWir
2415 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odAng
2416 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odX
2417 <<std::setw(7)<<std::setprecision(3)<<asym
2418 <<
" 0:"<<matcomb[im].Cls[0]<<
":"<<matcomb[im].End[0]
2419 <<
" 1:"<<matcomb[im].Cls[1]<<
":"<<matcomb[im].End[1];
2420 if(nplanes > 2) myprt<<
" 2:"<<matcomb[im].Cls[2]<<
":"<<matcomb[im].End[2];
2426 std::array<std::vector<bool>, 3> pclUsed;
2428 for(ipl = 0; ipl < nplanes; ++ipl) {
2429 pclUsed[ipl].resize(clsChain[ipl].size());
2434 unsigned short matcombTotCl = 0;
2435 float matcombTotLen = 0;
2437 for(ii = 0; ii < matcomb.size(); ++ii) {
2438 for(ipl = 0; ipl < nplanes; ++ipl) {
2439 if(matcomb[ii].Cls[ipl] < 0)
continue;
2440 icl = matcomb[ii].Cls[ipl];
2442 matcombTotLen += clsChain[ipl][icl].Length;
2446 if(prt)
mf::LogVerbatim(
"CCTM")<<
"Number of clusters to match "<<matcombTotCl <<
" total length "<<matcombTotLen;
2448 if(matcombTotLen <= 0) {
2449 mf::LogError(
"CCTM")<<
"SortMatches: bad matcomb total length "<<matcombTotLen;
2454 std::vector<unsigned short> matIndex;
2456 std::vector<unsigned short> bestMatIndex;
2457 float totLen, totErr, bestTotErr = 9999;
2459 unsigned short jj, jm, nused, jcl;
2463 for(ii = 0; ii < materr.size(); ++ii) {
2464 im = materr[ii].index;
2467 if(matcomb[im].Err > bestTotErr)
continue;
2471 for(ipl = 0; ipl < nplanes; ++ipl) {
2475 if(matcomb[im].Cls[ipl] < 0)
continue;
2476 icl = matcomb[im].Cls[ipl];
2477 pclUsed[ipl][icl] =
true;
2478 totLen += clsChain[ipl][icl].Length;
2481 totErr = matcomb[im].Err;
2483 matIndex.push_back(im);
2485 for(jj = 0; jj < materr.size(); ++jj) {
2486 if(jj == ii)
continue;
2487 jm = materr[jj].index;
2489 if(matcomb[jm].Err > bestTotErr)
continue;
2493 for(ipl = 0; ipl < nplanes; ++ipl) {
2494 if(matcomb[jm].Cls[ipl] < 0)
continue;
2495 jcl = matcomb[jm].Cls[ipl];
2496 if(pclUsed[ipl][jcl]) ++nused;
2498 if(nused > 0)
break;
2499 totLen += clsChain[ipl][jcl].Length;
2502 if(nused != 0)
continue;
2504 totErr += matcomb[jm].Err;
2505 matIndex.push_back(jm);
2507 for(ipl = 0; ipl < nplanes; ++ipl) {
2508 if(matcomb[jm].Cls[ipl] < 0)
continue;
2509 jcl = matcomb[jm].Cls[ipl];
2510 pclUsed[ipl][jcl] =
true;
2513 if(totLen == 0)
continue;
2515 for(ipl = 0; ipl < nplanes; ++ipl) {
2516 for(
unsigned short indx = 0; indx < pclUsed[ipl].size(); ++indx)
if(pclUsed[ipl][indx]) ++nused;
2518 if(totLen > matcombTotLen) std::cout<<
"Oops "<<totLen<<
" "<<matcombTotLen<<
"\n";
2520 fracLen = totLen / matcombTotLen;
2526 myprt<<
"match "<<im<<
" totErr "<<totErr<<
" nused "<<nused<<
" fracLen "<<fracLen<<
" totLen "<<totLen<<
" mat: ";
2527 for(
unsigned short indx = 0; indx < matIndex.size(); ++indx) myprt<<
" "<<matIndex[indx];
2531 if(totErr < bestTotErr) {
2532 bestTotErr = totErr;
2533 bestMatIndex = matIndex;
2534 if(nused == matcombTotCl)
break;
2537 myprt<<
"bestTotErr "<<bestTotErr<<
" nused "<<nused<<
" matcombTotCl "<<matcombTotCl<<
" mat: ";
2538 for(
unsigned short indx = 0; indx < bestMatIndex.size(); ++indx) myprt<<
" "<<bestMatIndex[indx];
2541 if(fracLen > 0.999)
break;
2545 if(bestTotErr > 9000)
return;
2547 for(ii = 0; ii < bestMatIndex.size(); ++ii) {
2548 im = bestMatIndex[ii];
2551 FillTrkHits(fmCluHits, im);
2554 StoreTrack(fmCluHits, im, procCode);
2570 unsigned short ipl = 0;
2571 unsigned short jpl = 1;
2574 if(match.
Cls[0] < 0 || match.
Cls[1] < 0)
return;
2576 unsigned short icl = match.
Cls[ipl];
2577 unsigned short iend = match.
End[ipl];
2578 match.
Chg[ipl] = clsChain[ipl][icl].TotChg;
2580 float miX = clsChain[ipl][icl].X[iend];
2582 unsigned short oiend = 1 - iend;
2583 float oiX = clsChain[ipl][icl].X[oiend];
2585 unsigned short jcl = match.
Cls[jpl];
2586 unsigned short jend = match.
End[jpl];
2587 match.
Chg[jpl] = clsChain[jpl][jcl].TotChg;
2589 float mjX = clsChain[jpl][jcl].X[jend];
2591 unsigned short ojend = 1 - jend;
2592 float ojX = clsChain[jpl][jcl].X[ojend];
2596 if(clsChain[ipl][icl].VtxIndex[iend] >= 0 &&
2597 clsChain[ipl][icl].VtxIndex[iend] == clsChain[jpl][jcl].VtxIndex[jend]) {
2598 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2599 miX = vtx[match.
Vtx].X;
2600 mjX = vtx[match.
Vtx].X;
2605 if(clsChain[ipl][icl].VtxIndex[oiend] >= 0 &&
2606 clsChain[ipl][icl].VtxIndex[oiend] == clsChain[jpl][jcl].VtxIndex[ojend]) {
2607 match.
oVtx = clsChain[ipl][icl].VtxIndex[oiend];
2608 oiX = vtx[match.
oVtx].X;
2609 ojX = vtx[match.
oVtx].X;
2614 if(fChgAsymFactor[algIndex] > 0) {
2615 chgAsym = fabs(match.
Chg[ipl] - match.
Chg[jpl]) / (match.
Chg[ipl] + match.
Chg[jpl]);
2616 if(chgAsym > 0.5)
return;
2617 chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2621 float maxSlp = fabs(clsChain[ipl][icl].Slope[iend]);
2622 if(fabs(clsChain[jpl][jcl].Slope[jend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[jend]);
2623 float sigmaX = fXMatchErr[algIndex] +
std::max(maxSlp, (
float)20);
2624 match.
dX = fabs(miX - mjX);
2625 match.
Err = chgAsym * match.
dX / sigmaX;
2629 maxSlp = fabs(clsChain[ipl][icl].Slope[oiend]);
2630 if(fabs(clsChain[jpl][jcl].Slope[ojend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[ojend]);
2631 sigmaX = fXMatchErr[algIndex] +
std::max(maxSlp, (
float)20);
2632 match.
odX = fabs(oiX - ojX);
2633 match.
oErr = chgAsym * match.
odX / sigmaX;
2635 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM2: m "<<ipl<<
":"<<icl<<
":"<<iend<<
" miX "<<miX
2636 <<
" - "<<jpl<<
":"<<jcl<<
":"<<jend<<
" mjX "<<mjX<<
" match.dX "<<match.
dX 2637 <<
" match.Err "<<match.
Err<<
" chgAsym "<<chgAsym<<
" o "<<
" oiX "<<oiX
2638 <<
" ojX "<<ojX<<
" match.odX "<<match.
odX<<
" match.oErr "<<match.
oErr<<
"\n";
2654 FillEndMatch2(match);
2658 std::array<short, 3> mVtx;
2659 std::array<short, 3> oVtx;
2660 std::array<float, 3> oWir;
2661 std::array<float, 3> oSlp;
2662 std::array<float, 3> oAng;
2663 std::array<float, 3> oX;
2665 std::array<float, 3> mChg;
2667 unsigned short ii, ipl, iend, jpl, jend, kpl, kend, oend;
2668 short icl, jcl, kcl;
2670 for(ipl = 0; ipl < 3; ++ipl) {
2671 mVtx[ipl] = -1; oVtx[ipl] = -1;
2672 oWir[ipl] = -66; oSlp[ipl] = -66; oAng[ipl] = -66; oX[ipl] = -66;
2677 match.
dWir = 0; match.
dAng = 0; match.
dX = 0; match.
Err = 100;
2684 for(ipl = 0; ipl < nplanes; ++ipl) {
2685 myprt<<
" "<<ipl<<
":"<<match.
Cls[ipl]<<
":"<<match.
End[ipl];
2689 short missingPlane = -1;
2690 unsigned short nClInPln = 0;
2693 unsigned short novxmat = 0;
2695 unsigned short nvxmat = 0;
2696 unsigned short nShortCl = 0;
2698 for(ipl = 0; ipl < nplanes; ++ipl) {
2699 if(match.
Cls[ipl] < 0) {
2704 icl = match.
Cls[ipl];
2705 match.
Chg[ipl] = clsChain[ipl][icl].TotChg;
2706 mChg[ipl] = clsChain[ipl][icl].TotChg;
2707 iend = match.
End[ipl];
2708 mVtx[ipl] = clsChain[ipl][icl].VtxIndex[iend];
2709 if(clsChain[ipl][icl].Length < 6) ++nShortCl;
2710 if(mVtx[ipl] >= 0) {
2711 if(aVtx < 0) aVtx = mVtx[ipl];
2712 if(mVtx[ipl] == aVtx) ++nvxmat;
2714 if(prt )
mf::LogVerbatim(
"CCTM")<<
"FEM: m "<<ipl<<
":"<<icl<<
":"<<iend<<
" Vtx "<<mVtx[ipl]<<
" Wir "<<clsChain[ipl][icl].Wire[iend]<<std::fixed<<std::setprecision(3)<<
" Slp "<<clsChain[ipl][icl].Slope[iend]<<std::fixed<<std::setprecision(1)<<
" X "<<clsChain[ipl][icl].X[iend];
2717 oWir[ipl] = clsChain[ipl][icl].Wire[oend];
2718 oAng[ipl] = clsChain[ipl][icl].Angle[oend];
2719 oSlp[ipl] = clsChain[ipl][icl].Slope[oend];
2720 oX[ipl] = clsChain[ipl][icl].X[oend];
2721 oVtx[ipl] = clsChain[ipl][icl].VtxIndex[oend];
2722 if(oVtx[ipl] >= 0) {
2723 if(aoVtx < 0) aoVtx = oVtx[ipl];
2724 if(oVtx[ipl] == aoVtx) ++novxmat;
2727 if(prt)
mf::LogVerbatim(
"CCTM")<<
" o "<<ipl<<
":"<<icl<<
":"<<oend<<
" oVtx "<<oVtx[ipl]<<
" oWir "<<oWir[ipl]<<std::fixed<<std::setprecision(3)<<
" oSlp "<<oSlp[ipl]<<std::fixed<<std::setprecision(1)<<
" oX "<<oX[ipl]<<
" Chg "<<(int)mChg[ipl];
2731 bool isShort = (nShortCl > 1);
2738 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: Vtx m "<<aVtx<<
" count "<<nvxmat
2739 <<
" o "<<aoVtx<<
" count "<<novxmat
2740 <<
" missingPlane "<<missingPlane
2741 <<
" nClInPln "<<nClInPln;
2744 if(nvxmat == 3 && novxmat == 3) {
2745 match.
Vtx = aVtx; match.
Err = 0;
2746 match.
oVtx = aoVtx; match.
oErr = 0;
2753 float ovxFactor = 1;
2758 match.
Vtx = aVtx; vxFactor = 0.33;
2762 match.
oVtx = aoVtx; ovxFactor = 0.33;
2767 match.
Vtx = aVtx; vxFactor = 0.5;
2770 match.
oVtx = aoVtx; ovxFactor = 0.5;
2782 float kSlp, okSlp, kAng, okAng, okX,
kX, kTim, okTim;
2785 ipl = 0; jpl = 1; kpl = 2;
2791 }
else if(kpl == 1) {
2797 iend = match.
End[ipl]; jend = match.
End[jpl];
2798 icl = match.
Cls[ipl]; jcl = match.
Cls[jpl];
2800 kcl = match.
Cls[kpl];
2801 kend = match.
End[kpl];
2805 okSlp = geom->ThirdPlaneSlope(ipl, oSlp[ipl], jpl, oSlp[jpl], tpc, cstat);
2806 okAng = atan(okSlp);
2809 bool ignoreSign = (fabs(okSlp) > 10);
2810 if(ignoreSign) okAng = fabs(okAng);
2811 if(match.
oVtx >= 0) {
2813 okWir = geom->WireCoordinate(vtx[match.
oVtx].Y, vtx[match.
oVtx].Z, kpl, tpc, cstat);
2814 okX = vtx[match.
oVtx].X;
2817 geom->IntersectionPoint(oWir[ipl], oWir[jpl],ipl, jpl, cstat, tpc, ypos, zpos);
2818 okWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2819 okX = 0.5 * (oX[ipl] + oX[jpl]);
2821 okTim = detprop->ConvertXToTicks(okX, kpl, tpc, cstat);
2822 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: oEnd"<<
" kpl "<<kpl<<
" okSlp "<<okSlp<<
" okAng " 2823 <<okAng<<
" okWir "<<(int)okWir<<
" okX "<<okX;
2828 kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2830 if(ignoreSign) kAng = fabs(kAng);
2831 if(match.
Vtx >= 0) {
2832 if(vtx.size() == 0 || (
unsigned int)match.
Vtx > vtx.size() - 1) {
2833 mf::LogError(
"CCTM")<<
"FEM: Bad match.Vtx "<<match.
Vtx<<
" vtx size "<<vtx.size();
2837 kWir = geom->WireCoordinate(vtx[match.
Vtx].Y, vtx[match.
Vtx].Z, kpl, tpc, cstat);
2838 kX = vtx[match.
Vtx].X;
2841 geom->IntersectionPoint(clsChain[ipl][icl].Wire[iend], clsChain[jpl][jcl].Wire[jend], ipl, jpl, cstat, tpc, ypos, zpos);
2842 kWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2843 kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2845 kTim = detprop->ConvertXToTicks(kX, kpl, tpc, cstat);
2846 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: mEnd"<<
" kpl "<<kpl<<
" kSlp "<<kSlp<<
" kAng "<<kAng<<
" kX "<<
kX;
2849 if(nClInPln < 3 && FindMissingCluster(kpl, kcl, kend, kWir, kX, okWir, okX)) {
2852 match.
Cls[kpl] = kcl;
2853 match.
End[kpl] = kend;
2854 match.
Chg[kpl] = clsChain[kpl][kcl].TotChg;
2855 mChg[kpl] = clsChain[kpl][kcl].TotChg;
2857 oWir[kpl] = clsChain[kpl][kcl].Wire[oend];
2858 oX[kpl] = clsChain[kpl][kcl].X[oend];
2859 oAng[kpl] = clsChain[kpl][kcl].Angle[oend];
2860 oSlp[kpl] = clsChain[kpl][kcl].Slope[oend];
2865 if(nClInPln == 2 && fabs(okWir - kWir) > 3)
return;
2871 if(nClInPln < 3 && mChg[missingPlane] <= 0) {
2872 if(missingPlane != kpl)
mf::LogError(
"CCTM")<<
"FEM bad missingPlane "<<missingPlane<<
" "<<kpl<<
"\n";
2873 mChg[kpl] = ChargeNear(kpl, (
unsigned short)kWir, kTim, (
unsigned short)okWir, okTim);
2874 match.
Chg[kpl] = mChg[kpl];
2875 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: Missing cluster in "<<kpl<<
" ChargeNear "<<(int)kWir<<
":"<<(
int)kTim
2876 <<
" "<<(int)okWir<<
":"<<(
int)okTim<<
" chg "<<mChg[kpl];
2877 if(mChg[kpl] <= 0)
return;
2880 if(fChgAsymFactor[algIndex] > 0) {
2881 chgAsym = ChargeAsym(mChg);
2882 if(chgAsym > 0.5)
return;
2883 chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2886 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: charge asymmetry factor "<<chgAsym;
2887 float sigmaX, sigmaA;
2893 bool allPlnVtxMatch =
false;
2895 unsigned short nmvtx = 0;
2896 for(ii = 0; ii < nplanes; ++ii) {
2898 if(aVtx < 0) aVtx = mVtx[ii];
2903 if(nmvtx ) allPlnVtxMatch =
true;
2907 sigmaX = fXMatchErr[algIndex] +
std::max(kSlp, (
float)20);
2908 sigmaA = fAngleMatchErr[algIndex] * AngleFactor(kSlp);
2909 if(prt)
mf::LogVerbatim(
"CCTM")<<
"bb "<<algIndex<<
" "<<fXMatchErr[algIndex]<<
" "<<fAngleMatchErr[algIndex]<<
" kslp "<<kSlp;
2912 kcl = match.
Cls[kpl];
2913 kend = match.
End[kpl];
2914 dw = kWir - clsChain[kpl][kcl].Wire[kend];
2916 if(fabs(match.
dWir) > 100)
return;
2917 if(match.
Vtx >= 0) {
2918 match.
dX = kX - clsChain[kpl][kcl].X[kend];
2920 match.
dX = std::abs(clsChain[ipl][icl].
X[iend] - clsChain[jpl][jcl].
X[jend]) +
2921 std::abs(clsChain[ipl][icl].
X[iend] - clsChain[kpl][kcl].
X[kend]);
2927 match.
dAng = kAng - fabs(clsChain[kpl][kcl].Angle[kend]);
2929 match.
dAng = kAng - clsChain[kpl][kcl].Angle[kend];
2932 da = fabs(match.
dAng) / sigmaA;
2933 dx = fabs(match.
dX) / sigmaX;
2934 if(allPlnVtxMatch) {
2936 match.
Err = vxFactor * chgAsym * da / 3;
2941 match.
Err = vxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2948 match.
dX = clsChain[ipl][icl].X[iend] - clsChain[jpl][jcl].X[jend];
2950 match.
Err = 3 + vxFactor * chgAsym * fabs(match.
dX) / sigmaX;
2957 dw = okWir - oWir[kpl];
2959 if(match.
oVtx >= 0) {
2960 match.
odX = okX - oX[kpl];
2962 match.
odX = std::abs(oX[ipl] - oX[jpl]) + std::abs(oX[ipl] - oX[kpl]);
2968 match.
odAng = okAng - fabs(oAng[kpl]);
2970 match.
odAng = okAng - oAng[kpl];
2973 da = match.
odAng / sigmaA;
2974 dx = fabs(match.
odX) / sigmaX;
2978 match.
oErr = ovxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2982 match.
odX = (oX[ipl] - oX[jpl]) / sigmaX;
2983 match.
oErr = 3 + ovxFactor * chgAsym * fabs(match.
odX);
3009 kkX = clsChain[kkpl][kkcl].X[kkend];
3010 float matchTime = detprop->ConvertXToTicks(kkX, kkpl, tpc, cstat);
3013 std::vector<unsigned int> wirs;
3014 std::vector<unsigned int> plns;
3015 std::vector<art::Ptr<recob::Hit>> clusterhits;
3016 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3017 if(ipl == kkpl)
continue;
3019 if(match.
Cls[ipl] < 0)
continue;
3020 float dTime, best = 99999;
3021 unsigned short wire = 0;
3022 unsigned short icl, ccl = match.
Cls[ipl];
3024 for(
unsigned short ii = 0; ii < clsChain[kkpl][ccl].ClsIndex.size(); ++ii) {
3025 icl = clsChain[kkpl][ccl].ClsIndex[ii];
3026 if(cls[ipl][icl].EvtIndex > fmCluHits.size() -1) {
3027 std::cout<<
"Bad ClsIndex in FMPM\n";
3030 clusterhits = fmCluHits.at(cls[ipl][icl].EvtIndex);
3032 for(
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
3033 dTime = fabs(clusterhits[iht]->PeakTime() - matchTime);
3036 wire = clusterhits[iht]->WireID().Wire;
3040 wirs.push_back(wire);
3041 plns.push_back(ipl);
3044 if(wirs.size() != 2)
return;
3046 geom->IntersectionPoint(wirs[0], wirs[1], plns[0], plns[1], cstat, tpc, Y, Z);
3047 kkWir = geom->WireCoordinate(Y, Z, kkpl, tpc, cstat);
3052 bool CCTrackMaker::FindMissingCluster(
unsigned short kpl,
short& kcl,
unsigned short& kend,
float kWir,
float kX,
float okWir,
float okX)
3056 unsigned short okend;
3059 if(kcl >= 0)
return false;
3062 float kslp = fabs((okX - kX) / (okWir - kWir));
3063 if(kslp > 20) kslp = 20;
3065 dxcut = 3 * fXMatchErr[algIndex] + kslp;
3066 unsigned short nfound = 0;
3067 unsigned short foundCl = 0, foundEnd = 0;
3068 for(
unsigned short ccl = 0; ccl < clsChain[kpl].size(); ++ccl) {
3069 if(clsChain[kpl][ccl].InTrack >= 0)
continue;
3071 for(
unsigned short end = 0;
end < 2; ++
end) {
3073 if(fabs(clsChain[kpl][ccl].Wire[
end] - kWir) > 4)
continue;
3074 if(fabs(clsChain[kpl][ccl].Wire[okend] - okWir) > 4)
continue;
3077 if(fabs(clsChain[kpl][ccl].
X[
end] - kX) > dxcut && fabs(clsChain[kpl][ccl].
X[okend] - okX) > dxcut)
continue;
3083 if(nfound == 0)
return false;
3085 mf::LogVerbatim(
"CCTM")<<
"FindMissingCluster: Found too many matches. Write some code "<<nfound;
3095 float CCTrackMaker::ChargeAsym(std::array<float, 3>& mChg)
3099 float big = 0, small = 1.E9;
3100 for(
unsigned short ii = 0; ii < 3; ++ii) {
3101 if(mChg[ii] < small) small = mChg[ii];
3102 if(mChg[ii] > big) big = mChg[ii];
3105 return (big - small) / (big + small);
3116 for(ipl = 0; ipl < 3; ++ipl) trkHits[ipl].
clear();
3118 if(imat > matcomb.size())
return;
3120 unsigned short indx;
3121 std::vector<art::Ptr<recob::Hit>> clusterhits;
3122 unsigned short icc, ccl, icl, ecl, iht, ii;
3123 short endOrder, fillOrder;
3125 if(prt)
mf::LogVerbatim(
"CCTM")<<
"In FillTrkHits: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
3127 for(ipl = 0; ipl < nplanes; ++ipl) {
3128 if(matcomb[imat].Cls[ipl] < 0)
continue;
3130 ccl = matcomb[imat].Cls[ipl];
3132 endOrder = 1 - 2 * matcomb[imat].End[ipl];
3135 std::reverse(clsChain[ipl][ccl].ClsIndex.begin(), clsChain[ipl][ccl].ClsIndex.end());
3136 std::reverse(clsChain[ipl][ccl].Order.begin(), clsChain[ipl][ccl].Order.end());
3137 for(ii = 0; ii < clsChain[ipl][ccl].Order.size(); ++ii) clsChain[ipl][ccl].Order[ii] = 1 - clsChain[ipl][ccl].Order[ii];
3139 if(ccl > clsChain[ipl].size() - 1) {
3140 mf::LogError(
"CCTM")<<
"Bad cluster chain index "<<ccl<<
" in plane "<<ipl;
3144 for(icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
3145 icl = clsChain[ipl][ccl].ClsIndex[icc];
3146 if(icl > fmCluHits.size() - 1) {
3147 std::cout<<
"oops in FTH "<<icl<<
" clsChain size "<<clsChain[ipl].size()<<
"\n";
3150 ecl = cls[ipl][icl].EvtIndex;
3151 if(ecl > fmCluHits.size() - 1) {
3152 std::cout<<
"FTH bad EvtIndex "<<ecl<<
" fmCluHits size "<<fmCluHits.size()<<
"\n";
3155 clusterhits = fmCluHits.at(ecl);
3156 if(clusterhits.size() == 0) {
3157 std::cout<<
"FTH no cluster hits for EvtIndex "<<cls[ipl][icl].EvtIndex<<
"\n";
3160 indx = trkHits[ipl].size();
3161 trkHits[ipl].resize(indx + clusterhits.size());
3163 fillOrder = 1 - 2 * clsChain[ipl][ccl].Order[icc];
3165 if(fillOrder == 1) {
3167 for(iht = 0; iht < clusterhits.size(); ++iht) {
3168 if(indx + iht > trkHits[ipl].size() - 1) std::cout<<
"FTH oops3\n";
3169 trkHits[ipl][indx + iht] = clusterhits[iht];
3174 for(ii = 0; ii < clusterhits.size(); ++ii) {
3175 iht = clusterhits.size() - 1 - ii;
3176 if(indx + ii > trkHits[ipl].size() - 1) std::cout<<
"FTH oops4\n";
3177 trkHits[ipl][indx + ii] = clusterhits[iht];
3181 ii = trkHits[ipl].size() - 1;
3182 if(prt)
mf::LogVerbatim(
"CCTM")<<
"plane "<<ipl<<
" first p "<<trkHits[ipl][0]->WireID().Plane<<
" w "<<trkHits[ipl][0]->WireID().Wire<<
":"<<(int)trkHits[ipl][0]->PeakTime()<<
" last p "<<trkHits[ipl][ii]->WireID().Plane<<
" w "<<trkHits[ipl][ii]->WireID().Wire<<
":"<<(int)trkHits[ipl][ii]->PeakTime();
3192 void CCTrackMaker::PrintTracks()
const 3195 myprt<<
"********* PrintTracks \n";
3196 myprt<<
"vtx Index X Y Z\n";
3197 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3198 myprt<<
std::right<<std::setw(4)<<ivx<<std::setw(4)<<vtx[ivx].EvtIndex;
3200 myprt<<
std::right<<std::setw(10)<<std::setprecision(1)<<vtx[ivx].X;
3201 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3202 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3203 if(vtx[ivx].Neutrino) myprt<<
" Neutrino vertex";
3207 myprt<<
">>>>>>>>>> Tracks \n";
3208 myprt<<
"trk ID Proc nht nTrj sX sY sZ eX eY eZ sVx eVx sGd eGd ChgOrd dirZ Mom PDG ClsIndices\n";
3209 for(
unsigned short itr = 0; itr <
trk.size(); ++itr) {
3210 myprt<<
std::right<<std::setw(3)<<itr<<std::setw(4)<<
trk[itr].ID;
3211 myprt<<
std::right<<std::setw(5)<<std::setw(4)<<
trk[itr].Proc;
3212 unsigned short nht = 0;
3213 for(
unsigned short ii = 0; ii < 3; ++ii) nht +=
trk[itr].TrkHits[ii].size();
3215 myprt<<std::setw(4)<<
trk[itr].TrjPos.size();
3217 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](0);
3218 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](1);
3219 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](2);
3220 unsigned short itj =
trk[itr].TrjPos.size() - 1;
3221 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](0);
3222 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](1);
3223 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](2);
3224 myprt<<std::setw(4)<<
trk[itr].VtxIndex[0]<<std::setw(4)<<
trk[itr].VtxIndex[1];
3225 myprt<<std::setw(4)<<
trk[itr].GoodEnd[0];
3226 myprt<<std::setw(4)<<
trk[itr].GoodEnd[1];
3227 myprt<<std::setw(4)<<
trk[itr].ChgOrder;
3228 myprt<<
std::right<<std::setw(10)<<std::setprecision(3)<<
trk[itr].TrjDir[itj](2);
3231 for(
unsigned short ii = 0; ii <
trk[itr].ClsEvtIndices.size(); ++ii) myprt<<
" "<<
trk[itr].ClsEvtIndices[ii];
3242 unsigned short iTime;
3244 myprt<<
"******* PrintClusters ********* Num_Clusters_in Wire:Time\n";
3245 myprt<<
"vtx Index X Y Z Pln0 Pln1 Pln2 Pln0 Pln1 Pln2\n";
3246 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3247 myprt<<
std::right<<std::setw(3)<<ivx<<std::setw(7)<<ivx;
3249 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].X;
3250 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3251 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3252 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[0];
3253 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[1];
3254 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[2];
3256 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3257 int time = (0.5 + detprop->ConvertXToTicks(vtx[ivx].
X, ipl, tpc, cstat));
3258 int wire = geom->WireCoordinate(vtx[ivx].
Y, vtx[ivx].
Z, ipl, tpc, cstat);
3259 myprt<<
std::right<<std::setw(7)<<wire<<
":"<<time;
3265 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3266 myprt<<
">>>>>>>>>> Cluster chains in Plane "<<ipl<<
"\n";
3267 myprt<<
"ipl ccl Len Chg W0:T0 Ang0 Dir0 Vx0 mBk0 W1:T1 Ang1 Dir1 Vx1 mBk1 InTk cls:Order \n";
3268 for(
unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
3271 myprt<<
std::right<<std::setw(6)<<clsChain[ipl][ccl].Length;
3272 myprt<<
std::right<<std::setw(8)<<(int)clsChain[ipl][ccl].TotChg;
3273 for(
unsigned short end = 0;
end < 2; ++
end) {
3274 iTime = clsChain[ipl][ccl].Time[
end];
3275 myprt<<
std::right<<std::setw(5)<<(int)clsChain[ipl][ccl].Wire[
end]
3276 <<
":"<<std::setprecision(1)<<iTime;
3279 }
else if(iTime < 100) {
3281 }
else if(iTime < 1000) myprt<<
" ";
3282 myprt<<
std::right<<std::setw(7)<<std::setprecision(2)<<clsChain[ipl][ccl].Angle[
end];
3283 myprt<<
std::right<<std::setw(5)<<clsChain[ipl][ccl].Dir[
end];
3284 myprt<<
std::right<<std::setw(5)<<clsChain[ipl][ccl].VtxIndex[
end];
3285 myprt<<std::fixed<<
std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].mBrkIndex[
end];
3288 myprt<<
std::right<<std::setw(7)<<clsChain[ipl][ccl].InTrack;
3290 for(
unsigned short ii = 0; ii < clsChain[ipl][ccl].ClsIndex.size(); ++ii)
3291 myprt<<
" "<<clsChain[ipl][ccl].ClsIndex[ii]<<
":"<<clsChain[ipl][ccl].Order[ii];
3294 if(fPrintAllClusters) {
3295 myprt<<
">>>>>>>>>> Clusters in Plane "<<ipl<<
"\n";
3296 myprt<<
"ipl icl Evt Len Chg W0:T0 Ang0 Dir0 Vx0 CN0 W1:T1 Ang1 Dir1 Vx1 CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
3297 for(
unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
3300 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].EvtIndex;
3301 myprt<<
std::right<<std::setw(6)<<cls[ipl][icl].Length;
3302 myprt<<
std::right<<std::setw(8)<<(int)cls[ipl][icl].TotChg;
3303 for(
unsigned short end = 0;
end < 2; ++
end) {
3304 iTime = cls[ipl][icl].Time[
end];
3305 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].Wire[
end]<<
":"<<iTime;
3308 }
else if(iTime < 100) {
3310 }
else if(iTime < 1000) myprt<<
" ";
3311 myprt<<
std::right<<std::setw(7)<<std::setprecision(2)<<cls[ipl][icl].Angle[
end];
3313 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].VtxIndex[
end];
3314 myprt<<std::fixed<<
std::right<<std::setw(5)<<std::setprecision(1)<<cls[ipl][icl].ChgNear[
end];
3317 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].InTrack;
3318 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[0];
3319 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[0];
3320 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[1];
3321 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[1];
3329 float CCTrackMaker::AngleFactor(
float slope)
3331 float slp = fabs(slope);
3332 if(slp > 10.) slp = 30.;
3334 return 1 + 0.05 * slp * slp;
3338 float CCTrackMaker::ChargeNear(
unsigned short ipl,
unsigned short wire1,
float time1,
unsigned short wire2,
float time2)
3344 unsigned short w1 = wire1;
3345 unsigned short w2 = wire2;
3358 slp = (t2 -
t1) / (w2 - w1);
3361 unsigned short wire;
3364 for(
unsigned short hit = 0;
hit < allhits.size(); ++
hit) {
3365 if(allhits[
hit]->WireID().Cryostat != cstat)
continue;
3366 if(allhits[
hit]->WireID().TPC != tpc)
continue;
3367 if(allhits[
hit]->WireID().Plane != ipl)
continue;
3368 wire = allhits[
hit]->WireID().Wire;
3369 if(wire < w1)
continue;
3370 if(wire > w2)
continue;
3371 prtime = t1 + (wire - w1) * slp;
3373 if(prtime > allhits[
hit]->PeakTimePlusRMS(3))
continue;
3374 if(prtime < allhits[
hit]->PeakTimeMinusRMS(3))
continue;
3375 chg += ChgNorm[ipl] * allhits[
hit]->Integral();
3388 for(ipl = 0; ipl < 3; ++ipl) {
3389 firstWire[ipl] = INT_MAX;
3391 firstHit[ipl] = INT_MAX;
3393 WireHitRange[ipl].clear();
3398 unsigned short oldipl = 0;
3399 for(
unsigned int hit = 0;
hit < allhits.size(); ++
hit) {
3400 if(allhits[
hit]->WireID().Cryostat != cstat)
continue;
3401 if(allhits[
hit]->WireID().TPC != tpc)
continue;
3402 ipl = allhits[
hit]->WireID().Plane;
3403 if(allhits[
hit]->WireID().Wire > geom->Nwires(ipl, tpc, cstat)) {
3404 if(lastWire[ipl] < firstWire[ipl]) {
3405 mf::LogError(
"CCTM")<<
"Invalid WireID().Wire "<<allhits[
hit]->WireID().Wire;
3411 mf::LogError(
"CCTM")<<
"Hits are not in increasing-plane order\n";
3415 if(firstHit[ipl] == INT_MAX) {
3416 firstHit[ipl] =
hit;
3417 firstWire[ipl] = allhits[
hit]->WireID().Wire;
3420 lastWire[ipl] = allhits[
hit]->WireID().Wire;
3424 for(ipl = 0; ipl < nplanes; ++ipl) {
3425 if(lastWire[ipl] < firstWire[ipl]) {
3426 mf::LogError(
"CCTM")<<
"Invalid first/last wire in plane "<<ipl;
3433 for(ipl = 0; ipl < nplanes; ++ipl) ChgNorm[ipl] = 1;
3440 int sflag, nwires, wire;
3441 unsigned int indx, thisWire, thisHit, lastFirstHit;
3443 for(ipl = 0; ipl < nplanes; ++ipl) {
3444 nwires = lastWire[ipl] - firstWire[ipl] + 1;
3445 WireHitRange[ipl].resize(nwires);
3448 for(wire = 0; wire < nwires; ++wire) WireHitRange[ipl][wire] = std::make_pair(sflag, sflag);
3451 for(wire = 0; wire < nwires; ++wire) {
3459 lastWire[ipl] = firstWire[ipl];
3460 thisHit = firstHit[ipl];
3461 lastFirstHit = firstHit[ipl];
3462 for(
unsigned int hit = firstHit[ipl];
hit <= lastHit[ipl]; ++
hit) {
3463 thisWire = allhits[
hit]->WireID().Wire;
3464 if(thisWire > lastWire[ipl]) {
3465 indx = lastWire[ipl] - firstWire[ipl];
3466 int tmp1 = lastFirstHit;
3468 WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3469 lastWire[ipl] = thisWire;
3470 lastFirstHit = thisHit;
3471 }
else if(thisWire < lastWire[ipl]) {
3472 mf::LogError(
"CCTM")<<
"Hit not in proper order in plane "<<ipl;
3478 indx = lastWire[ipl] - firstWire[ipl];
3479 int tmp1 = lastFirstHit;
3481 int tmp2 = lastHit[ipl];
3482 WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3488 for(ipl = 0; ipl < nplanes; ++ipl) {
3489 if(firstWire[ipl] < INT_MAX)
continue;
3490 if(lastWire[ipl] > 0)
continue;
3491 if(firstHit[ipl] < INT_MAX)
continue;
3492 if(lastHit[ipl] > 0)
continue;
3493 std::cout<<
"FWHR problem\n";
3497 unsigned int nht = 0;
3498 std::vector<bool> hchk(allhits.size());
3499 for(
unsigned int ii = 0; ii < hchk.size(); ++ii) hchk[ii] =
false;
3500 for(ipl = 0; ipl < nplanes; ++ipl) {
3501 for(
unsigned int w = firstWire[ipl];
w < lastWire[ipl]; ++
w) {
3502 indx =
w - firstWire[ipl];
3503 if(indx > lastWire[ipl]) {
3504 std::cout<<
"FWHR bad index "<<indx<<
"\n";
3508 if(WireHitRange[ipl][indx].first < 0)
continue;
3509 unsigned int firhit = WireHitRange[ipl][indx].first;
3510 unsigned int lashit = WireHitRange[ipl][indx].second;
3511 for(
unsigned int hit = firhit;
hit < lashit; ++
hit) {
3513 if(
hit > allhits.size() -1) {
3514 std::cout<<
"FWHR: Bad hchk "<<
hit<<
" size "<<allhits.size()<<
"\n";
3518 if(allhits[
hit]->WireID().
Plane != ipl || allhits[
hit]->WireID().Wire !=
w) {
3519 std::cout<<
"FWHR bad plane "<<allhits[
hit]->WireID().Plane<<
" "<<ipl<<
" or wire "<<allhits[
hit]->WireID().Wire<<
" "<<
w<<
"\n";
3526 if(nht != allhits.size()) {
3527 std::cout<<
"FWHR hit count problem "<<nht<<
" "<<allhits.size()<<
"\n";
3528 for(
unsigned int ii = 0; ii < hchk.size(); ++ii)
if(!hchk[ii]) std::cout<<
" "<<ii<<
" "<<allhits[ii]->WireID().Plane<<
" "<<allhits[ii]->WireID().Wire<<
" "<<(int)allhits[ii]->PeakTime()<<
"\n";
std::string fHitModuleLabel
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::array< short, 2 > VtxIndex
std::vector< MatchPars > matcomb
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > TrkHits
std::string fVertexModuleLabel
std::vector< float > fChgAsymFactor
std::array< unsigned short, 3 > End
Declaration of signal hit object.
std::array< unsigned int, 3 > firstWire
Planes which measure X direction.
Geometry information for a single TPC.
std::vector< art::Ptr< recob::Hit > > allhits
std::array< short, 2 > Dir
float StartWire() const
Returns the wire coordinate of the start of the cluster.
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
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
data_const_reference data(size_type i) const
std::vector< TVector3 > TrjPos
std::vector< TrkPar > trk
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
std::array< float, 3 > ChgNorm
std::vector< float > fAngleMatchErr
std::array< float, 2 > ChgNear
std::array< std::vector< clPar >, 3 > cls
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
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
ProductID put(std::unique_ptr< PROD > &&product)
std::array< std::vector< ClsChainPar >, 3 > clsChain
float EndCharge() const
Returns the charge on the last wire of the cluster.
#define DEFINE_ART_MODULE(klass)
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
std::vector< float > fMatchMinLen
T get(std::string const &key) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::vector< unsigned short > Order
std::array< short, 2 > VtxIndex
std::array< short, 2 > mVtxIndex
std::vector< short > DtrID
std::vector< vtxPar > vtx
std::array< float, 2 > MergeError
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
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::array< float, 2 > Wire
Declaration of cluster object.
Provides recob::Track data product.
std::array< unsigned int, 3 > firstHit
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
std::array< float, 2 > Charge
std::vector< unsigned short > ClsIndex
std::vector< unsigned short > ClsEvtIndices
Detector simulation of raw signals on wires.
std::array< unsigned int, 3 > lastWire
Class defining a plane for tracking. It provides various functionalities to convert track parameters ...
Encapsulate the geometry of a wire.
bool greaterThan(CluLen c1, CluLen c2)
Hierarchical representation of particle flow.
Utility object to perform functions of association.
bool FillWireHitRange(TjStuff &tjs, const geo::TPCID &tpcid)
Encapsulate the construction of a single detector plane.
std::array< float, 2 > Time
float StartCharge() const
Returns the charge on the first wire of the cluster.
std::array< float, 2 > Slope
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
std::array< short, 2 > VtxIndex
std::array< unsigned int, 3 > lastHit
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
art::ServiceHandle< geo::Geometry > geom
bool lessThan(CluLen c1, CluLen c2)
std::array< short, 2 > Dir
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
constexpr double kBogusD
obviously bogus double value
std::vector< TVector3 > TrjDir
std::array< float, 2 > Angle
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
std::array< float, 2 > Wire
std::array< short, 3 > Cls
float StartTick() const
Returns the tick coordinate of the start of the cluster.
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
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
const detinfo::DetectorProperties * detprop
Encapsulate the construction of a single detector plane.
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