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;
450 std::vector< art::Ptr<recob::Hit > > tmpHits;
451 std::vector< art::Ptr<recob::Cluster > > tmpCls;
452 std::vector< art::Ptr<recob::Vertex > > tmpVtx;
455 std::vector<size_t> dtrIndices;
458 double sPos[3], sDir[3];
459 double sErr[3] = {0,0,0};
462 std::vector<art::Ptr<recob::Hit>> clusterhits;
463 for(icl = 0; icl < clusterlist.size(); ++icl) {
464 ipl = clusterlist[icl]->Plane().Plane;
465 clusterhits = fmCluHits.at(icl);
466 if(clusterhits[0]->WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
467 std::cout<<
"CCTM Cluster-Hit End wire mis-match "<<clusterhits[0]->WireID().Wire<<
" vs "<<std::nearbyint(clusterlist[icl]->EndWire())<<
" Bail out! \n";
470 for(
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
471 if(clusterhits[iht]->WireID().Plane != ipl) {
472 std::cout<<
"CCTM Cluster-Hit plane mis-match "<<ipl<<
" vs "<<clusterhits[iht]->WireID().Plane<<
" on hit "<<iht<<
" Bail out! \n";
483 for(cstat = 0; cstat < geom->Ncryostats(); ++cstat) {
484 for(tpc = 0; tpc < geom->Cryostat(cstat).NTPC(); ++tpc) {
485 nplanes = geom->Cryostat(cstat).TPC(tpc).Nplanes();
486 if(nplanes > 3)
continue;
487 for(ipl = 0; ipl < 3; ++ipl) {
489 clsChain[ipl].clear();
490 trkHits[ipl].clear();
494 for(ipl = 0; ipl < nplanes; ++ipl) {
497 for(icl = 0; icl < clusterlist.size(); ++icl) {
498 if(clusterlist[icl]->
Plane().Cryostat != cstat)
continue;
499 if(clusterlist[icl]->
Plane().TPC != tpc)
continue;
500 if(clusterlist[icl]->
Plane().
Plane != ipl)
continue;
503 clulen.
length = clusterlist[icl]->EndWire();
504 clulens.push_back(clulen);
506 if(clulens.size() == 0)
continue;
508 std::sort (clulens.begin(),clulens.end(),
lessThan);
509 if(clulens.size() == 0)
continue;
510 for(
unsigned short ii = 0; ii < clulens.size(); ++ii) {
511 const unsigned short icl = clulens[ii].index;
518 clstr.
X[1] = (float)detprop->ConvertTicksToX(cluster.
StartTick(), ipl, tpc, cstat);
533 clstr.
X[0] = (float)detprop->ConvertTicksToX(cluster.
EndTick(), ipl, tpc, cstat);
539 clstr.
Dir[0] = 1; clstr.
Dir[1] = -1;
541 clstr.
Dir[0] = -1; clstr.
Dir[1] = 1;
552 clstr.
Length = (
unsigned short)(0.5 + clstr.
Wire[1] - clstr.
Wire[0]);
555 clusterhits = fmCluHits.at(icl);
556 if(clusterhits.size() == 0) {
557 mf::LogError(
"CCTM")<<
"No associated cluster hits "<<icl;
561 clstr.
TotChg *= clstr.
Length / (float)clusterhits.size();
562 cls[ipl].push_back(clstr);
572 for(
unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
576 vtxlist[ivx]->XYZ(xyz);
583 std::vector<art::Ptr<recob::Cluster>>
const& vtxCls = fmVtxCls.at(ivx);
584 std::vector<const unsigned short*>
const& vtxClsEnd = fmVtxCls.
data(ivx);
585 for(
unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
586 icl = vtxCls[vcass].key();
588 ipl = vtxCls[vcass]->Plane().Plane;
589 end = *vtxClsEnd[vcass];
590 if(end > 1)
throw cet::exception(
"CCTM")<<
"Invalid end data from vertex - cluster association"<<
end;
594 for(
unsigned short jcl = 0; jcl < cls[ipl].size(); ++jcl) {
595 if(cls[ipl][jcl].EvtIndex == icl) {
596 cls[ipl][jcl].VtxIndex[
end] = ivx;
602 if(!gotit)
throw cet::exception(
"CCTM")<<
"Bad index from vertex - cluster association"<<icl;
607 MakeClusterChains(fmCluHits);
612 for(algIndex = 0; algIndex < fMatchAlgs.size(); ++algIndex) {
613 if(fMatchAlgs[algIndex] == 1) {
614 prt = (fDebugAlg == 1);
616 if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 1);
618 if(fMatchAlgs[algIndex] == 2) {
619 prt = (fDebugAlg == 2);
621 if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 2);
635 for(
unsigned short ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
637 tID = pfpToTrkID[ipf];
638 if(tID >
trk.size()+1) {
645 for(
unsigned short jpf = 0; jpf < pfpToTrkID.size(); ++jpf) {
646 itr = pfpToTrkID[jpf] - 1;
647 if(
trk[itr].MomID == tID) dtrIndices.push_back(jpf);
650 unsigned short parentIndex = USHRT_MAX;
654 pcol->emplace_back(std::move(pfp));
655 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
656 if(!vtx[ivx].Neutrino)
continue;
661 size_t vStart = vcol->size();
663 vcol->emplace_back(std::move(vertex));
664 size_t vEnd = vcol->size();
667 vtx[ivx].ID = -vtx[ivx].ID;
675 for(
unsigned short ii = 0; ii < pfpToTrkID.size(); ++ii) {
676 if(pfpToTrkID[ii] ==
trk[tIndex].MomID) {
682 mf::LogVerbatim(
"CCTM")<<
"daughters tID "<<tID<<
" pdg "<<
trk[tIndex].PDGCode<<
" ipf "<<ipf<<
" parentIndex "<<parentIndex<<
" dtr size "<<dtrIndices.size();
684 pcol->emplace_back(std::move(pfp));
687 size_t tStart = tcol->size();
692 tcol->emplace_back(std::move(
track));
693 size_t tEnd = tcol->size();
697 trk[tIndex].ID = -
trk[tIndex].ID;
700 for(ipl = 0; ipl < nplanes; ++ipl)
701 tmpHits.insert(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)
721 tmpHits.insert(tmpHits.end(), seedHits[ipl].begin(), seedHits[ipl].end());
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;
741 tcol->emplace_back(std::move(
track));
743 for(ipl = 0; ipl < nplanes; ++ipl)
744 tmpHits.insert(tmpHits.end(),
trk[itr].TrkHits[ipl].begin(),
trk[itr].TrkHits[ipl].end());
748 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
749 if(vtx[ivx].ID < 0)
continue;
754 vcol->emplace_back(std::move(vertex));
756 if(fDebugAlg > 0) PrintTracks();
758 double orphanLen = 0;
759 for(ipl = 0; ipl < nplanes; ++ipl) {
760 for(icl = 0; icl < cls[ipl].size(); ++icl) {
761 if(cls[ipl][icl].Length > 40 && cls[ipl][icl].InTrack < 0) {
762 orphanLen += cls[ipl][icl].Length;
764 mf::LogVerbatim(
"CCTM")<<
"Orphan long cluster "<<ipl<<
":"<<icl<<
":"<<cls[ipl][icl].Wire[0]
765 <<
":"<<(int)cls[ipl][icl].Time[0]<<
" length "<<cls[ipl][icl].Length;
770 clsChain[ipl].clear();
772 std::cout<<
"Total orphan length "<<orphanLen<<
"\n";
773 trkHits[ipl].clear();
774 seedHits[ipl].clear();
779 evt.
put(std::move(pcol));
780 evt.
put(std::move(ptassn));
781 evt.
put(std::move(pcassn));
782 evt.
put(std::move(pvassn));
783 evt.
put(std::move(psassn));
784 evt.
put(std::move(tcol));
785 evt.
put(std::move(thassn));
786 evt.
put(std::move(scol));
787 evt.
put(std::move(vcol));
851 void CCTrackMaker::FitVertices()
854 std::vector<std::vector<geo::WireID>> hitWID;
855 std::vector<std::vector<double>> hitX;
856 std::vector<std::vector<double>> hitXErr;
857 TVector3 pos, posErr;
858 std::vector<TVector3> trkDir;
859 std::vector<TVector3> trkDirErr;
862 if(fNVtxTrkHitsFit == 0)
return;
864 unsigned short indx, indx2, iht, nHitsFit;
868 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
869 if(!vtx[ivx].Neutrino)
continue;
875 unsigned int thePln, theTPC, theCst;
876 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
877 for(
unsigned short end = 0;
end < 2; ++
end) {
878 if(
trk[itk].VtxIndex[
end] != ivx)
continue;
879 unsigned short itj = 0;
880 if(
end == 1) itj =
trk[itk].TrjPos.size() - 1;
885 hitWID.resize(indx + 1);
886 hitX.resize(indx + 1);
887 hitXErr.resize(indx + 1);
888 trkDir.resize(indx + 1);
889 trkDir[indx] =
trk[itk].TrjDir[itj];
890 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
891 if(
trk[itk].TrkHits[ipl].size() < 2)
continue;
893 nHitsFit =
trk[itk].TrkHits[ipl].size();
894 if(nHitsFit > fNVtxTrkHitsFit) nHitsFit = fNVtxTrkHitsFit;
895 indx2 = hitWID[indx].size();
896 hitWID[indx].resize(indx2 + nHitsFit);
897 hitX[indx].resize(indx2 + nHitsFit);
898 hitXErr[indx].resize(indx2 + nHitsFit);
899 for(
unsigned short ii = 0; ii < nHitsFit; ++ii) {
903 iht =
trk[itk].TrkHits[ipl].size() - ii - 1;
905 hitWID[indx][indx2 + ii] =
trk[itk].TrkHits[ipl][iht]->WireID();
906 thePln =
trk[itk].TrkHits[ipl][iht]->WireID().Plane;
907 theTPC =
trk[itk].TrkHits[ipl][iht]->WireID().TPC;
908 theCst =
trk[itk].TrkHits[ipl][iht]->WireID().Cryostat;
909 hitX[indx][indx2 + ii] = detprop->ConvertTicksToX(
trk[itk].TrkHits[ipl][iht]->PeakTime(), thePln, theTPC, theCst);
910 hitXErr[indx][indx2 + ii] = fHitFitErrFac *
trk[itk].TrkHits[ipl][iht]->RMS();
918 if(hitX.size() < 2) {
925 fVertexFitAlg.VertexFit(hitWID, hitX, hitXErr, pos, posErr, trkDir, trkDirErr, ChiDOF);
931 if(ChiDOF > 3000)
continue;
937 unsigned short fitTrk = 0;
938 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
939 for(
unsigned short end = 0;
end < 2; ++
end) {
940 if(
trk[itk].VtxIndex[
end] != ivx)
continue;
941 unsigned short itj = 0;
942 if(
end == 1) itj =
trk[itk].TrjPos.size() - 1;
943 trk[itk].TrjDir[itj] = trkDir[fitTrk];
951 void CCTrackMaker::FillChgNear()
955 unsigned short wire, nwires, indx;
956 float dir, ctime, cx, chgWinLo, chgWinHi;
959 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
960 for(
unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
962 nwires = cls[ipl][icl].Length / 2;
963 if(nwires < 2)
continue;
965 if(nwires > 30) nwires = 30;
966 for(
unsigned short end = 0;
end < 2; ++
end) {
970 for(
unsigned short w = 0;
w < nwires; ++
w) {
971 wire = cls[ipl][icl].Wire[
end] + dir *
w;
972 cx = cls[ipl][icl].X[
end] + dir * w * cls[ipl][icl].Slope[
end] * fWirePitch;
973 ctime = detprop->ConvertXToTicks(cx, ipl, tpc, cstat);
974 chgWinLo = ctime - fChgWindow;
975 chgWinHi = ctime + fChgWindow;
976 indx = wire - firstWire[ipl];
977 if(WireHitRange[ipl][indx].first < 0)
continue;
978 unsigned int firhit = WireHitRange[ipl][indx].first;
979 unsigned int lashit = WireHitRange[ipl][indx].second;
980 for(
unsigned int hit = firhit;
hit < lashit; ++
hit) {
981 if(
hit > allhits.size() - 1) {
982 mf::LogError(
"CCTM")<<
"FillChgNear bad lashit "<<lashit<<
" size "<<allhits.size()<<
"\n";
985 if(allhits[
hit]->PeakTime() < chgWinLo)
continue;
986 if(allhits[
hit]->PeakTime() > chgWinHi)
continue;
987 cnear += allhits[
hit]->Integral();
990 cnear /= (float)(nwires-1);
991 if(cnear > cls[ipl][icl].Charge[
end]) {
992 cls[ipl][icl].ChgNear[
end] = ChgNorm[ipl] * cnear / cls[ipl][icl].Charge[
end];
994 cls[ipl][icl].ChgNear[
end] = 0;
1004 void CCTrackMaker::MakeFamily()
1008 unsigned short ivx, itr, ipl, ii, jtr;
1009 unsigned short nus, nds, nuhs, ndhs;
1010 float longUSTrk, longDSTrk, qual;
1014 float tgMuonCut2 = 9;
1018 unsigned short VtxIndex;
1019 unsigned short nUSTk;
1020 unsigned short nDSTk;
1021 unsigned short nUSHit;
1022 unsigned short nDSHit;
1027 std::vector<NuVtx> nuVtxCand;
1032 float best = 999, dx, dy, dz, dr;
1036 for(ivx = 0; ivx < vtx.size(); ++ivx) {
1037 vtx[ivx].Neutrino =
false;
1038 nus = 0; nds = 0; nuhs = 0; ndhs = 0;
1039 longUSTrk = 0; longDSTrk = 0;
1042 for(itr = 0; itr <
trk.size(); ++itr) {
1043 if(
trk[itr].ID < 0)
continue;
1044 if(
trk[itr].PDGCode != 13)
continue;
1045 for(itj = 0; itj <
trk[itr].TrjPos.size(); ++itj) {
1046 dx =
trk[itr].TrjPos[itj](0) - vtx[ivx].
X;
1047 dy =
trk[itr].TrjPos[itj](1) - vtx[ivx].
Y;
1048 dz =
trk[itr].TrjPos[itj](2) - vtx[ivx].
Z;
1049 dr = dx * dx + dy * dy + dz * dz;
1050 if(dr < tgMuonCut2) {
1058 if(skipVtx)
continue;
1059 for(itr = 0; itr <
trk.size(); ++itr) {
1060 if(
trk[itr].ID < 0)
continue;
1061 if(
trk[itr].VtxIndex[0] == ivx) {
1064 if(
trk[itr].Length > longDSTrk) longDSTrk =
trk[itr].Length;
1065 for(ipl = 0; ipl < nplanes; ++ipl) ndhs +=
trk[itr].TrkHits[ipl].size();
1070 if(
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] >= 0) {
1074 if(
trk[itr].VtxIndex[1] == ivx &&
trk[itr].VtxIndex[0] < 0) {
1077 if(
trk[itr].Length > longUSTrk) longUSTrk =
trk[itr].Length;
1078 for(ipl = 0; ipl < nplanes; ++ipl) nuhs +=
trk[itr].TrkHits[ipl].size();
1082 if(skipVtx)
continue;
1083 if(nds == 0)
continue;
1084 qual = 1 / (float)nds;
1085 qual /= (float)ndhs;
1086 if(nus > 0) qual *= (float)nuhs / (
float)ndhs;
1091 if(nds > 0 && longDSTrk > 5) {
1093 aNuVtx.VtxIndex = ivx;
1096 aNuVtx.nUSHit = nuhs;
1097 aNuVtx.nDSHit = ndhs;
1098 aNuVtx.longUSTrk = longUSTrk;
1099 aNuVtx.longDSTrk = longDSTrk;
1101 nuVtxCand.push_back(aNuVtx);
1111 if(imbest < 0)
return;
1115 vtx[ivx].Neutrino =
true;
1118 pfpToTrkID.push_back(0);
1123 std::vector<unsigned short> dtrGen;
1124 std::vector<unsigned short> dtrNextGen;
1125 for(itr = 0; itr <
trk.size(); ++itr) {
1126 if(
trk[itr].ID < 0)
continue;
1127 if(
trk[itr].VtxIndex[0] == ivx) {
1131 trk[itr].PDGCode = 2212;
1132 pfpToTrkID.push_back(
trk[itr].ID);
1133 dtrGen.push_back(itr);
1135 if(
trk[itr].VtxIndex[1] == ivx) {
1139 trk[itr].PDGCode = 2212;
1140 pfpToTrkID.push_back(
trk[itr].ID);
1142 std::reverse(
trk[itr].TrjPos.begin(),
trk[itr].TrjPos.end());
1143 for(ii = 0; ii <
trk[itr].TrjDir.size(); ++ii)
1144 trk[itr].TrjDir[ii] = -
trk[itr].TrjDir[ii];
1148 if(dtrGen.size() == 0)
return;
1150 unsigned short tmp, indx;
1151 unsigned short nit = 0;
1159 for(ii = 0; ii < dtrGen.size(); ++ii) {
1161 if(
trk[itr].VtxIndex[1] >= 0) {
1163 ivx =
trk[itr].VtxIndex[1];
1165 for(jtr = 0; jtr <
trk.size(); ++jtr) {
1166 if(jtr == itr)
continue;
1167 if(
trk[jtr].VtxIndex[0] == ivx) {
1169 indx =
trk[itr].DtrID.size();
1170 trk[itr].DtrID.resize(indx + 1);
1171 trk[itr].DtrID[indx] = jtr;
1173 trk[jtr].MomID =
trk[itr].ID;
1175 trk[jtr].PDGCode = 211;
1176 dtrNextGen.push_back(jtr);
1177 pfpToTrkID.push_back(
trk[jtr].ID);
1179 if(
trk[jtr].VtxIndex[1] == ivx) {
1181 indx =
trk[itr].DtrID.size();
1182 trk[itr].DtrID.resize(indx + 1);
1183 trk[itr].DtrID[indx] = jtr;
1185 trk[jtr].MomID =
trk[itr].ID;
1187 trk[jtr].PDGCode = 211;
1188 dtrNextGen.push_back(jtr);
1189 pfpToTrkID.push_back(
trk[jtr].ID);
1191 std::reverse(
trk[jtr].TrjPos.begin(),
trk[jtr].TrjPos.end());
1192 for(
unsigned short jj = 0; jj <
trk[jtr].TrjDir.size(); ++jj)
1193 trk[jtr].TrjDir[jj] = -
trk[jtr].TrjDir[jj];
1195 tmp =
trk[jtr].VtxIndex[0];
1196 trk[jtr].VtxIndex[0] =
trk[jtr].VtxIndex[1];
1197 trk[jtr].VtxIndex[1] =
tmp;
1203 if(dtrNextGen.size() == 0)
break;
1204 dtrGen = dtrNextGen;
1210 void CCTrackMaker::TagCosmics()
1213 unsigned short ipf, itj;
1217 double local[3] = {0.,0.,0.};
1218 double world[3] = {0.,0.,0.};
1220 const geo::TPCGeo &thetpc = geom->TPC(tpc, cstat);
1222 float XLo = world[0] - geom->DetHalfWidth(tpc,cstat) + fFiducialCut;
1223 float XHi = world[0] + geom->DetHalfWidth(tpc,cstat) - fFiducialCut;
1224 float YLo = world[1] - geom->DetHalfHeight(tpc,cstat) + fFiducialCut;
1225 float YHi = world[1] + geom->DetHalfHeight(tpc,cstat) - fFiducialCut;
1226 float ZLo = world[2] - geom->DetLength(tpc,cstat)/2 + fFiducialCut;
1227 float ZHi = world[2] + geom->DetLength(tpc,cstat)/2 - fFiducialCut;
1229 bool startsIn, endsIn;
1231 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1233 if(
trk[itk].ID < 0)
continue;
1235 if(
trk[itk].Length < 10)
continue;
1238 for(ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
1239 if(pfpToTrkID[ipf] ==
trk[itk].ID) {
1244 if(skipit)
continue;
1246 if(
trk[itk].TrjPos[0](0) < XLo ||
trk[itk].TrjPos[0](0) > XHi) startsIn =
false;
1247 if(
trk[itk].TrjPos[0](1) < YLo ||
trk[itk].TrjPos[0](1) > YHi) startsIn =
false;
1248 if(
trk[itk].TrjPos[0](2) < ZLo ||
trk[itk].TrjPos[0](2) > ZHi) startsIn =
false;
1250 if(startsIn)
continue;
1252 itj =
trk[itk].TrjPos.size() - 1;
1253 if(
trk[itk].TrjPos[itj](0) < XLo ||
trk[itk].TrjPos[itj](0) > XHi) endsIn =
false;
1254 if(
trk[itk].TrjPos[itj](1) < YLo ||
trk[itk].TrjPos[itj](1) > YHi) endsIn =
false;
1255 if(
trk[itk].TrjPos[itj](2) < ZLo ||
trk[itk].TrjPos[itj](2) > ZHi) endsIn =
false;
1257 if(endsIn)
continue;
1259 trk[itk].PDGCode = 13;
1260 pfpToTrkID.push_back(
trk[itk].ID);
1263 if(fDeltaRayCut <= 0)
return;
1265 for(
unsigned short itk = 0; itk <
trk.size(); ++itk) {
1267 if(
trk[itk].PDGCode != 13)
continue;
1277 unsigned short ivx, ii, ipl, icl, jj, jpl, jcl, kk, kpl, kcl;
1278 short idir, iend, jdir, jend, kdir, kend, ioend;
1280 for(ivx = 0; ivx < vtx.size(); ++ivx) {
1283 for(ipl = 0; ipl < nplanes; ++ipl) {
1285 for(icl = 0; icl < clsChain[ipl].size(); ++icl) {
1286 if(clsChain[ipl][icl].InTrack >= 0)
continue;
1287 for(iend = 0; iend < 2; ++iend) {
1288 if(clsChain[ipl][icl].VtxIndex[iend] == vtx[ivx].EvtIndex) vxCls[ipl].push_back(icl);
1295 myprt<<
"VtxMatch: Vertex ID "<<vtx[ivx].EvtIndex<<
"\n";
1296 for(ipl = 0; ipl < nplanes; ++ipl) {
1297 myprt<<
"ipl "<<ipl<<
" cls";
1298 for(
unsigned short ii = 0; ii < vxCls[ipl].size(); ++ii) myprt<<
" "<<vxCls[ipl][ii];
1306 for(ipl = 0; ipl < nplanes; ++ipl) {
1307 if(nplanes == 2 && ipl > 0)
continue;
1308 for(ii = 0; ii < vxCls[ipl].size(); ++ii) {
1309 icl = vxCls[ipl][ii];
1311 if(clsChain[ipl][icl].InTrack >= 0)
continue;
1312 jpl = (ipl + 1) % nplanes;
1313 kpl = (jpl + 1) % nplanes;
1314 for(jj = 0; jj < vxCls[jpl].size(); ++jj) {
1315 jcl = vxCls[jpl][jj];
1316 if(clsChain[jpl][jcl].InTrack >= 0)
continue;
1317 for(iend = 0; iend < 2; ++iend) {
1318 if(clsChain[ipl][icl].VtxIndex[iend] != vtx[ivx].EvtIndex)
continue;
1320 idir = clsChain[ipl][icl].Dir[iend];
1321 for(jend = 0; jend < 2; ++jend) {
1322 if(clsChain[jpl][jcl].VtxIndex[jend] != vtx[ivx].EvtIndex)
continue;
1323 jdir = clsChain[jpl][jcl].Dir[jend];
1324 if(idir != 0 && jdir != 0 && idir != jdir)
continue;
1326 if(fabs(clsChain[jpl][jcl].
X[1 - jend] - clsChain[ipl][icl].
X[ioend]) > 50)
continue;
1328 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
1329 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
1330 match.
Vtx = ivx; match.
oVtx = -1;
1332 match.
Err = 1E6; match.
oErr = 1E6;
1335 FillEndMatch2(match);
1337 if(match.
Err + match.
oErr > 100)
continue;
1338 if(DupMatch(match))
continue;
1339 matcomb.push_back(match);
1342 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
1343 if(prt)
mf::LogVerbatim(
"CCTM")<<
"VtxMatch: check "<<ipl<<
":"<<icl<<
":"<<iend<<
" and "<<jpl<<
":"<<jcl<<
":"<<jend<<
" for cluster in kpl "<<kpl;
1345 for(kk = 0; kk < vxCls[kpl].size(); ++kk) {
1346 kcl = vxCls[kpl][kk];
1347 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
1348 for(kend = 0; kend < 2; ++kend) {
1349 kdir = clsChain[kpl][kcl].Dir[kend];
1350 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
1351 if(clsChain[kpl][kcl].VtxIndex[kend] != vtx[ivx].EvtIndex)
continue;
1354 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
1356 if(DupMatch(match))
continue;
1357 FillEndMatch(match);
1360 if(match.
Chg[kpl] <= 0)
continue;
1361 if(match.
Err + match.
oErr > 100)
continue;
1363 if(DupMatch(match))
continue;
1364 matcomb.push_back(match);
1369 if(gotkcl)
continue;
1373 unsigned short kbend = 0;
1374 if(prt)
mf::LogVerbatim(
"CCTM")<<
"VtxMatch: look for missed cluster chain in kpl";
1375 for(kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
1376 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
1377 for(kend = 0; kend < 2; ++kend) {
1378 kdir = clsChain[kpl][kcl].Dir[kend];
1379 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
1380 if(clsChain[kpl][kcl].VtxIndex[kend] >= 0)
continue;
1382 if(fabs(clsChain[kpl][kcl].
X[kend] - vtx[ivx].
X) > 5)
continue;
1384 if(fabs(clsChain[kpl][kcl].X[1 - kend] - clsChain[ipl][icl].X[ioend]) > 50)
continue;
1386 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
1387 if(DupMatch(match))
continue;
1388 FillEndMatch(match);
1389 totErr = match.
Err + match.
oErr;
1392 myprt<<
"VtxMatch: Chk missing cluster match ";
1393 for(
unsigned short ii = 0; ii < nplanes; ++ii)
1394 myprt<<
" "<<ii<<
":"<<match.
Cls[ii]<<
":"<<match.
End[ii];
1395 myprt<<
" Err "<<match.
Err<<
"\n";
1397 if(totErr > 100)
continue;
1407 match.
Cls[kpl] = kbst; match.
End[kpl] = kbend;
1408 FillEndMatch(match);
1409 matcomb.push_back(match);
1411 clsChain[kpl][kbst].VtxIndex[kbend] = ivx;
1413 vxCls[kpl].push_back(kbst);
1416 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
1417 if(DupMatch(match))
continue;
1418 FillEndMatch(match);
1419 if(match.
Err + match.
oErr < 100) matcomb.push_back(match);
1427 if(matcomb.size() == 0)
continue;
1428 SortMatches(fmCluHits, 1);
1432 for(ipl = 0; ipl < 3; ++ipl) vxCls[ipl].
clear();
1437 void CCTrackMaker::FindMaybeVertices()
1442 unsigned short ipl, icl,
end, ivx, oend;
1443 float best, dWire, dX;
1446 if(vtx.size() == 0)
return;
1448 for(ipl = 0; ipl < nplanes; ++ipl) {
1449 for(icl = 0; icl < cls[ipl].size(); ++icl) {
1450 for(end = 0; end < 2; ++
end) {
1452 if(cls[ipl][icl].VtxIndex[end] >= 0)
continue;
1457 for(ivx = 0; ivx < vtx.size(); ++ ivx) {
1459 if(cls[ipl][icl].VtxIndex[oend] == ivx)
continue;
1460 dWire = geom->WireCoordinate(vtx[ivx].
Y, vtx[ivx].
Z, ipl, tpc, cstat) - cls[ipl][icl].Wire[
end];
1468 if(dWire > 30 || dWire < -2)
continue;
1470 if(dWire < -30 || dWire > 2)
continue;
1473 dX = fabs(cls[ipl][icl].
X[end] + cls[ipl][icl].Slope[end] * fWirePitch * dWire - vtx[ivx].
X);
1482 cls[ipl][icl].VtxIndex[
end] = ibstvx;
1483 cls[ipl][icl].mVtxIndex[
end] = ibstvx;
1495 unsigned short ipl, icl, icl1, icl2;
1496 float dw, dx, dWCut, dw1Max, dw2Max;
1497 float dA, dA2, dACut = fMaxDAng, chgAsymCut;
1498 float dXCut, chgasym, mrgErr;
1501 bool gotprt =
false;
1502 for(ipl = 0; ipl < nplanes; ++ipl) {
1503 if(cls[ipl].size() > 1) {
1504 for(icl1 = 0; icl1 < cls[ipl].size() - 1; ++icl1) {
1505 prt = (fDebugAlg == 666 && ipl == fDebugPlane && icl1 == fDebugCluster);
1506 if(prt) gotprt =
true;
1508 dw1Max = 0.6 * cls[ipl][icl1].Length;
1509 ls1 = (cls[ipl][icl1].Length > 100 && fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl1].Angle[1]) < 0.04);
1510 for(icl2 = icl1 + 1; icl2 < cls[ipl].size(); ++icl2) {
1511 ls2 = (cls[ipl][icl2].Length > 100 && fabs(cls[ipl][icl2].Angle[0] - cls[ipl][icl2].Angle[1]) < 0.04);
1512 dw2Max = 0.6 * cls[ipl][icl2].Length;
1515 if(dw2Max < dWCut) dWCut = dw2Max;
1517 if(dWCut > 100) dWCut = 100;
1518 if(dWCut < 2) dWCut = 2;
1519 chgAsymCut = fMergeChgAsym;
1522 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;
1523 if(std::abs(cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]) > dWCut)
continue;
1527 float af = AngleFactor(cls[ipl][icl1].Slope[1]);
1528 dACut = fMaxDAng * af;
1529 dXCut = fChainMaxdX * 5 * af;
1530 dA = fabs(cls[ipl][icl1].Angle[1] - cls[ipl][icl2].Angle[0]);
1533 dA2 = fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl2].Angle[1]);
1535 if(prt)
mf::LogVerbatim(
"CCTM")<<
" dA "<<dA<<
" dA2 "<<dA2<<
" DACut "<<dACut<<
" dXCut "<<dXCut;
1537 if(dA2 < dA) dA = dA2;
1540 if(dA < fChainVtxAng && cls[ipl][icl1].VtxIndex[1] >= 0) {
1541 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1542 dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1543 unsigned short ivx = cls[ipl][icl1].VtxIndex[1];
1544 if(vtx[ivx].nClusInPln[ipl] == 2 && fabs(dx) < 1) {
1545 cls[ipl][icl1].VtxIndex[1] = -2;
1546 cls[ipl][icl2].VtxIndex[0] = -2;
1547 vtx[ivx].nClusInPln[ipl] = 0;
1553 if(cls[ipl][icl1].VtxIndex[1] >= 0)
continue;
1554 if(cls[ipl][icl2].VtxIndex[0] >= 0)
continue;
1557 if(cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1] < 3 &&
1558 (cls[ipl][icl1].Length < 3 || cls[ipl][icl2].Length < 3) ) {
1566 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1568 dx = cls[ipl][icl2].X[0] - cls[ipl][icl1].X[1];
1569 float dA3 = std::abs(atan(dx / dw) - cls[ipl][icl1].Angle[1]);
1571 if(dA3 > dA) dA = dA3;
1575 if(dA > dACut)
continue;
1577 if(prt)
mf::LogVerbatim(
"CCTM")<<
" rough dX "<<fabs(cls[ipl][icl1].
X[1] - cls[ipl][icl2].
X[0])<<
" cut = 20";
1580 if(fabs(cls[ipl][icl1].X[1] - cls[ipl][icl2].X[0]) > 20)
continue;
1585 if(dA > fChainVtxAng)
continue;
1587 chgasym = fabs(cls[ipl][icl1].Charge[1] - cls[ipl][icl2].Charge[0]);
1588 chgasym /= cls[ipl][icl1].Charge[1] + cls[ipl][icl2].Charge[0];
1589 if(prt)
mf::LogVerbatim(
"CCTM")<<
" chgasym "<<chgasym<<
" cut "<<chgAsymCut;
1590 if(chgasym > chgAsymCut)
continue;
1593 if(cls[ipl][icl1].Length > cls[ipl][icl2].Length) {
1594 dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1595 dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1597 dw = fWirePitch * (cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]);
1598 dx = cls[ipl][icl2].X[0] + cls[ipl][icl2].Slope[0] * dw * fWirePitch - cls[ipl][icl1].X[1];
1602 if(dA2 < 0.01 && abs(dx) > dXCut && dx < -1) {
1603 dx = dXClTraj(fmCluHits, ipl, icl1, 1, icl2);
1607 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;
1609 if(fabs(dx) > dXCut)
continue;
1612 float xerr = dx / dXCut;
1613 float aerr = dA / dACut;
1614 mrgErr = xerr * xerr + aerr * aerr;
1616 if(prt)
mf::LogVerbatim(
"CCTM")<<
"icl1 mrgErr "<<mrgErr<<
" MergeError "<<cls[ipl][icl1].MergeError[1]<<
" icl2 MergeError "<<cls[ipl][icl2].MergeError[0];
1619 if(mrgErr > cls[ipl][icl1].MergeError[1])
continue;
1620 if(mrgErr > cls[ipl][icl2].MergeError[0])
continue;
1623 if(cls[ipl][icl1].BrkIndex[1] >= 0) {
1624 unsigned short ocl = cls[ipl][icl1].BrkIndex[1];
1626 if(cls[ipl][ocl].BrkIndex[0] == icl1) {
1627 cls[ipl][ocl].BrkIndex[0] = -1;
1628 cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1630 if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1631 cls[ipl][ocl].BrkIndex[1] = -1;
1632 cls[ipl][ocl].MergeError[1] = fMaxMergeError;
1635 cls[ipl][icl1].BrkIndex[1] = icl2;
1636 cls[ipl][icl1].MergeError[1] = mrgErr;
1639 if(cls[ipl][icl2].BrkIndex[0] >= 0) {
1640 unsigned short ocl = cls[ipl][icl2].BrkIndex[0];
1642 if(cls[ipl][ocl].BrkIndex[0] == icl1) {
1643 cls[ipl][ocl].BrkIndex[0] = -1;
1644 cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1646 if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1647 cls[ipl][ocl].BrkIndex[1] = -1;
1648 cls[ipl][ocl].MergeError[1] = fMaxMergeError;
1651 cls[ipl][icl2].BrkIndex[0] = icl1;
1652 cls[ipl][icl2].MergeError[0] = mrgErr;
1661 for(icl1 = 0; icl1 < cls[ipl].size() - 1; ++icl1) {
1663 for(icl2 = icl1 + 1; icl2 < cls[ipl].size(); ++icl2) {
1665 for(
unsigned short end = 0;
end < 2; ++
end) {
1667 if(cls[ipl][icl1].BrkIndex[
end] >= 0)
continue;
1668 if(cls[ipl][icl2].BrkIndex[
end] >= 0)
continue;
1671 if(fabs(cls[ipl][icl1].Angle[
end]) < 1)
continue;
1673 if(fabs(cls[ipl][icl2].Angle[end]) < 1)
continue;
1674 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]);
1675 if(fabs(cls[ipl][icl1].Wire[end] - cls[ipl][icl2].Wire[end]) > 5)
continue;
1678 float dsl = cls[ipl][icl2].Slope[
end] - cls[ipl][icl1].Slope[
end];
1679 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;
1681 if(fabs(cls[ipl][icl1].Wire[end] - fvw) > 4)
continue;
1682 if(fabs(cls[ipl][icl2].Wire[end] - fvw) > 4)
continue;
1683 cls[ipl][icl1].BrkIndex[
end] = icl2;
1685 cls[ipl][icl1].MergeError[
end] = 1;
1686 cls[ipl][icl2].BrkIndex[
end] = icl1;
1687 cls[ipl][icl2].MergeError[
end] = 1;
1689 dx = fabs(cls[ipl][icl1].
X[end] - cls[ipl][icl2].
X[end]);
1690 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;
1699 unsigned short end, mom, momBrkEnd, dtrBrkEnd, nit;
1702 std::vector<bool> gotcl(cls[ipl].size());
1703 for(icl = 0; icl < cls[ipl].size(); ++icl) gotcl[icl] =
false;
1704 if(prt)
mf::LogVerbatim(
"CCTM")<<
"ipl "<<ipl<<
" cls.size() "<<cls[ipl].size()<<
"\n";
1706 std::vector<unsigned short> sCluster;
1707 std::vector<unsigned short> sOrder;
1708 for(icl = 0; icl < cls[ipl].size(); ++icl) {
1711 if(gotcl[icl])
continue;
1713 if(cls[ipl][icl].BrkIndex[0] >= 0 && cls[ipl][icl].BrkIndex[1] >= 0)
continue;
1714 for(end = 0; end < 2; ++
end) {
1715 if(cls[ipl][icl].BrkIndex[end] < 0)
continue;
1716 if(cls[ipl][icl].MergeError[end] > fMergeErrorCut)
continue;
1721 sCluster.push_back(mom);
1722 if(momBrkEnd == 1) {
1724 sOrder.push_back(0);
1727 sOrder.push_back(1);
1729 dtr = cls[ipl][icl].BrkIndex[
end];
1732 while(dtr >= 0 && dtr < (
short)cls[ipl].size() && nit < cls[ipl].size()) {
1734 for(dtrBrkEnd = 0; dtrBrkEnd < 2; ++dtrBrkEnd)
if(cls[ipl][dtr].BrkIndex[dtrBrkEnd] == mom)
break;
1735 if(dtrBrkEnd == 2) {
1741 if(cls[ipl][dtr].MergeError[dtrBrkEnd] < fMergeErrorCut) {
1742 sCluster.push_back(dtr);
1743 sOrder.push_back(dtrBrkEnd);
1751 momBrkEnd = 1 - dtrBrkEnd;
1753 dtr = cls[ipl][mom].BrkIndex[momBrkEnd];
1756 if(dtrBrkEnd == 2)
continue;
1761 sCluster.push_back(icl);
1762 sOrder.push_back(0);
1765 if(sCluster.size() == 0) {
1766 mf::LogError(
"CCTM")<<
"MakeClusterChains error in plane "<<ipl<<
" cluster "<<icl;
1776 unsigned short jcl = sCluster[0];
1777 if(jcl > cls[ipl].size()) std::cout<<
"oops MCC\n";
1778 unsigned short oend;
1779 for(end = 0; end < 2; ++
end) {
1781 if(sOrder[0] > 0) oend = 1 -
end;
1782 ccp.
Wire[
end] = cls[ipl][jcl].Wire[oend];
1783 ccp.
Time[
end] = cls[ipl][jcl].Time[oend];
1784 ccp.
X[
end] = cls[ipl][jcl].X[oend];
1785 ccp.
Slope[
end] = cls[ipl][jcl].Slope[oend];
1786 ccp.
Angle[
end] = cls[ipl][jcl].Angle[oend];
1787 ccp.
Dir[
end] = cls[ipl][icl].Dir[oend];
1789 ccp.
ChgNear[
end] = cls[ipl][jcl].ChgNear[oend];
1792 ccp.
Length = cls[ipl][icl].Length;
1793 ccp.
TotChg = cls[ipl][icl].TotChg;
1797 for(
unsigned short ii = 1; ii < sCluster.size(); ++ii) {
1799 if(jcl > cls[ipl].size()) std::cout<<
"oops MCC\n";
1802 if(end > 1) std::cout<<
"oops2 MCC\n";
1805 ccp.
Wire[1] = cls[ipl][jcl].Wire[oend];
1806 ccp.
Time[1] = cls[ipl][jcl].Time[oend];
1807 ccp.
X[1] = cls[ipl][jcl].X[oend];
1808 ccp.
Slope[1] = cls[ipl][jcl].Slope[oend];
1809 ccp.
Angle[1] = cls[ipl][jcl].Angle[oend];
1810 ccp.
Dir[1] = cls[ipl][jcl].Dir[oend];
1811 ccp.
VtxIndex[1] = cls[ipl][jcl].VtxIndex[oend];
1812 ccp.
ChgNear[1] = cls[ipl][jcl].ChgNear[oend];
1813 ccp.
mBrkIndex[1] = cls[ipl][jcl].BrkIndex[oend];
1814 ccp.
Length += cls[ipl][jcl].Length;
1815 ccp.
TotChg += cls[ipl][jcl].TotChg;
1822 ccp.
Dir[0] = 1; ccp.
Dir[1] = -1;
1824 ccp.
Dir[0] = -1; ccp.
Dir[1] = 1;
1826 clsChain[ipl].push_back(ccp);
1831 unsigned short brkCls;
1833 for(
unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
1834 for(
unsigned short end = 0; end < 2; ++
end) {
1835 if(clsChain[ipl][ccl].mBrkIndex[end] < 0)
continue;
1836 brkCls = clsChain[ipl][ccl].mBrkIndex[
end];
1839 for(
unsigned short ccl2 = 0; ccl2 < clsChain[ipl].size(); ++ccl2) {
1840 if(ccl2 == ccl)
continue;
1841 if(std::find(clsChain[ipl][ccl2].ClsIndex.begin(), clsChain[ipl][ccl2].ClsIndex.end(), brkCls) == clsChain[ipl][ccl2].ClsIndex.end())
continue;
1843 clsChain[ipl][ccl].mBrkIndex[
end] = ccl2;
1848 if(!gotit)
mf::LogError(
"CCTM")<<
"MCC: Cluster chain "<<ccl<<
" end "<<end<<
" Failed to find brkCls "<<brkCls<<
" in plane "<<ipl;
1861 float CCTrackMaker::dXClTraj(
art::FindManyP<recob::Hit> const& fmCluHits,
unsigned short ipl,
unsigned short icl1,
unsigned short end1,
unsigned short icl2)
1864 float dw, dx, best = 999;
1865 std::vector<art::Ptr<recob::Hit>> clusterhits = fmCluHits.at(cls[ipl][icl1].EvtIndex);
1866 for(
unsigned short hit = 0;
hit < clusterhits.size(); ++
hit) {
1867 dw = clusterhits[
hit]->WireID().Wire - cls[ipl][icl1].Wire[end1];
1868 dx = fabs(cls[ipl][icl1].Time[end1] + dw * fWirePitch * cls[ipl][icl1].Slope[end1] - clusterhits[
hit]->PeakTime());
1869 if(dx < best) best = dx;
1870 if(dx < 0.01)
break;
1877 unsigned short imat,
unsigned short procCode)
1883 if(imat > matcomb.size() - 1) {
1889 unsigned short nhitinpl = 0;
1890 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl)
if(trkHits[ipl].size() > 1) ++nhitinpl;
1892 mf::LogError(
"CCTM")<<
"StoreTrack: Not enough hits in each plane\n";
1895 if(prt)
mf::LogVerbatim(
"CCTM")<<
"In StoreTrack: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
1898 std::array<std::vector<geo::WireID>,3> trkWID;
1899 std::array<std::vector<double>,3> trkX;
1900 std::array<std::vector<double>,3> trkXErr;
1903 std::vector<TVector3> trkPos;
1904 std::vector<TVector3> trkDir;
1906 newtrk.
ID =
trk.size() + 1;
1907 newtrk.
Proc = procCode;
1916 newtrk.
EndInTPC = {{
false,
false}};
1917 newtrk.
GoodEnd = {{
false,
false}};
1921 unsigned short ipl, icl, iht;
1923 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();
1926 trkWID[2].resize(0);
1928 trkXErr[2].resize(0);
1930 for(ipl = 0; ipl < nplanes; ++ipl) {
1931 trkWID[ipl].resize(trkHits[ipl].size());
1932 trkX[ipl].resize(trkHits[ipl].size());
1933 trkXErr[ipl].resize(trkHits[ipl].size());
1934 for(iht = 0; iht < trkHits[ipl].size(); ++iht) {
1935 trkWID[ipl][iht] = trkHits[ipl][iht]->WireID();
1936 trkX[ipl][iht] = detprop->ConvertTicksToX(trkHits[ipl][iht]->PeakTime(),ipl, tpc, cstat);
1937 trkXErr[ipl][iht] = fHitFitErrFac * trkHits[ipl][iht]->RMS() * trkHits[ipl][iht]->Multiplicity();
1941 fTrackTrajectoryAlg.TrackTrajectory(trkWID, trkX, trkXErr, trkPos, trkDir);
1942 if(trkPos.size() < 2) {
1943 mf::LogError(
"CCTM")<<
"StoreTrack: No trajectory points on failed track "<<newtrk.
ID 1944 <<
" in StoreTrack: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
1954 if(prt)
mf::LogVerbatim(
"CCTM")<<
" number of traj points "<<trkPos.size();
1958 unsigned short end, nClose, indx, jndx;
1960 for(end = 0; end < 2; ++
end) {
1962 for(ipl = 0; ipl < nplanes - 1; ++ipl) {
1963 if(trkX[ipl].size() == 0)
continue;
1964 for(
unsigned short jpl = ipl + 1; jpl < nplanes; ++jpl) {
1965 if(trkX[jpl].size() == 0)
continue;
1970 indx = trkXErr[ipl].size() - 1;
1971 jndx = trkXErr[jpl].size() - 1;
1973 xErr = 3 * (trkXErr[ipl][indx] + trkXErr[jpl][jndx]);
1974 if(std::abs(trkX[ipl][indx] - trkX[jpl][jndx]) < xErr) ++nClose;
1977 if(nClose == nplanes) newtrk.
GoodEnd[
end] =
true;
1981 unsigned short ivx, itj, ccl;
1982 float dx, dy, dz, dr0, dr1;
1983 unsigned short attachEnd;
1984 for(end = 0; end < 2; ++
end) {
1986 if(end == 0 && matcomb[imat].Vtx >= 0) ivx = matcomb[imat].Vtx;
1987 if(end == 1 && matcomb[imat].oVtx >= 0) ivx = matcomb[imat].oVtx;
1988 if(ivx == USHRT_MAX)
continue;
1991 dx = vtx[ivx].X - newtrk.
TrjPos[itj](0);
1992 dy = vtx[ivx].Y - newtrk.
TrjPos[itj](1);
1993 dz = vtx[ivx].Z - newtrk.
TrjPos[itj](2);
1994 dr0 = dx*dx + dy*dy + dz*dz;
1995 itj = newtrk.
TrjPos.size() - 1;
1996 dx = vtx[ivx].X - newtrk.
TrjPos[itj](0);
1997 dy = vtx[ivx].Y - newtrk.
TrjPos[itj](1);
1998 dz = vtx[ivx].Z - newtrk.
TrjPos[itj](2);
1999 dr1 = dx*dx + dy*dy + dz*dz;
2010 newtrk.
TrjPos[itj](0) = vtx[ivx].
X;
2011 newtrk.
TrjPos[itj](1) = vtx[ivx].
Y;
2012 newtrk.
TrjPos[itj](2) = vtx[ivx].
Z;
2018 newtrk.
TrjDir[0] = dir.Unit();
2021 newtrk.
TrjDir[itj] = dir.Unit();
2026 mf::LogError(
"CCTM")<<
"StoreTrack: Trying to attach a vertex to both ends of a track. imat = "<<imat;
2034 for(
unsigned short itj = 1; itj < newtrk.
TrjPos.size(); ++itj) {
2038 norm = sqrt(X*X + Y*Y + Z*Z);
2044 for(ipl = 0; ipl < nplanes; ++ipl) {
2045 if(matcomb[imat].Cls[ipl] < 0)
continue;
2046 ccl = matcomb[imat].Cls[ipl];
2047 if(ccl > clsChain[ipl].size()) std::cout<<
"oops StoreTrack\n";
2048 clsChain[ipl][ccl].InTrack = newtrk.
ID;
2049 for(
unsigned short icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
2050 icl = clsChain[ipl][ccl].ClsIndex[icc];
2051 if(icl > cls[ipl].size()) std::cout<<
"oops StoreTrack\n";
2052 cls[ipl][icl].InTrack = newtrk.
ID;
2053 if(cls[ipl][icl].EvtIndex > fmCluHits.size() - 1) {
2054 std::cout<<
"ooops2 store track EvtIndex "<<cls[ipl][icl].EvtIndex<<
" size "<<fmCluHits.size()<<
" icl "<<icl<<
"\n";
2061 if(prt)
mf::LogVerbatim(
"CCTM")<<
" track ID "<<newtrk.
ID<<
" stored in StoreTrack";
2063 trk.push_back(newtrk);
2183 float kSlp, kAng,
kX, kWir, okWir;
2184 short idir, ioend, jdir, joend, kdir;
2187 float tpcSizeY = geom->DetHalfWidth();
2188 float tpcSizeZ = geom->DetLength();
2200 std::array<float, 3> mchg;
2202 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2203 for(
unsigned short icl = 0; icl < clsChain[ipl].size(); ++icl) {
2204 if(clsChain[ipl][icl].InTrack >= 0)
continue;
2206 if(clsChain[ipl][icl].Length < fMatchMinLen[algIndex])
continue;
2207 unsigned short jpl = (ipl + 1) % nplanes;
2208 unsigned short kpl = (jpl + 1) % nplanes;
2209 for(
unsigned short jcl = 0; jcl < clsChain[jpl].size(); ++jcl) {
2210 if(clsChain[jpl][jcl].InTrack >= 0)
continue;
2212 if(clsChain[jpl][jcl].Length < fMatchMinLen[algIndex])
continue;
2214 mchg[0] = clsChain[ipl][icl].TotChg;
2215 mchg[1] = clsChain[jpl][jcl].TotChg;
2217 if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5)
continue;
2218 for(
unsigned short iend = 0; iend < 2; ++iend) {
2219 idir = clsChain[ipl][icl].Dir[iend];
2220 for(
unsigned short jend = 0; jend < 2; ++jend) {
2221 jdir = clsChain[jpl][jcl].Dir[jend];
2222 if(idir != 0 && jdir != 0 && idir != jdir)
continue;
2224 if(fabs(clsChain[ipl][icl].
X[iend] - clsChain[jpl][jcl].
X[jend]) > dxcut)
continue;
2225 ioend = 1 - iend; joend = 1 - jend;
2227 kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2230 geom->IntersectionPoint((
unsigned int)(0.5+clsChain[ipl][icl].Wire[iend]),
2231 (
unsigned int)(0.5+clsChain[jpl][jcl].Wire[jend]),
2232 ipl, jpl, cstat, tpc, yp, zp);
2233 if(yp > tpcSizeY || yp < -tpcSizeY)
continue;
2234 if(zp < 0 || zp > tpcSizeZ)
continue;
2235 kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2236 kWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2238 geom->IntersectionPoint((
unsigned int)(0.5+clsChain[ipl][icl].Wire[ioend]),
2239 (
unsigned int)(0.5+clsChain[jpl][jcl].Wire[joend]),
2240 ipl, jpl, cstat, tpc, yp, zp);
2241 if(yp > tpcSizeY || yp < -tpcSizeY)
continue;
2242 if(zp < 0 || zp > tpcSizeZ)
continue;
2243 okWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2244 if(prt)
mf::LogVerbatim(
"CCTM")<<
"PlnMatch: chk i "<<ipl<<
":"<<icl<<
":"<<iend
2245 <<
" idir "<<idir<<
" X "<<clsChain[ipl][icl].X[iend]<<
" j "<<jpl<<
":"<<jcl<<
":"<<jend
2246 <<
" jdir "<<jdir<<
" X "<<clsChain[jpl][jcl].X[jend];
2248 if(prt)
mf::LogVerbatim(
"CCTM")<<
"PlnMatch: chk j "<<ipl<<
":"<<icl<<
":"<<iend
2249 <<
" "<<jpl<<
":"<<jcl<<
":"<<jend<<
" iSlp "<<std::setprecision(2)<<clsChain[ipl][icl].Slope[iend]
2250 <<
" jSlp "<<std::setprecision(2)<<clsChain[jpl][jcl].Slope[jend]<<
" kWir "<<(int)kWir
2251 <<
" okWir "<<(
int)okWir<<
" kSlp "<<std::setprecision(2)<<kSlp<<
" kAng " 2252 <<std::setprecision(2)<<kAng<<
" kX "<<std::setprecision(1)<<
kX;
2256 ignoreSign = (fabs(kSlp) > 1.5);
2257 if(ignoreSign) kAng = fabs(kAng);
2258 dxkcut = dxcut * AngleFactor(kSlp);
2259 bool gotkcl =
false;
2260 for(
unsigned short kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
2261 if(clsChain[kpl][kcl].InTrack >= 0)
continue;
2263 mchg[0] = clsChain[ipl][icl].TotChg;
2264 mchg[1] = clsChain[jpl][jcl].TotChg;
2265 mchg[2] = clsChain[kpl][kcl].TotChg;
2266 if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5)
continue;
2267 for(
unsigned short kend = 0; kend < 2; ++kend) {
2268 kdir = clsChain[kpl][kcl].Dir[kend];
2269 if(idir != 0 && kdir != 0 && idir != kdir)
continue;
2271 <<
" dx "<<std::abs(clsChain[kpl][kcl].
X[kend] - kX)<<
" dxkcut "<<dxkcut;
2272 if(std::abs(clsChain[kpl][kcl].
X[kend] - kX) > dxkcut)
continue;
2275 <<
" dw "<<(clsChain[kpl][kcl].Wire[kend] - kWir)<<
" ignoreSign "<<ignoreSign;
2276 if(fabs(clsChain[kpl][kcl].Wire[kend] - kWir) > dwcut)
continue;
2279 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
2280 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
2281 match.
Cls[kpl] = kcl; match.
End[kpl] = kend;
2283 if(DupMatch(match))
continue;
2284 match.
Chg[ipl] = 0; match.
Chg[jpl] = 0; match.
Chg[kpl] = 0;
2285 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2287 FillEndMatch(match);
2289 <<
":"<<match.
End[kpl]<<
" oChg "<<match.
Chg[kpl]<<
" mErr "<<match.
Err<<
" oErr "<<match.
oErr;
2290 if(match.
Chg[kpl] == 0)
continue;
2291 if(match.
Err > 10 || match.
oErr > 10)
continue;
2293 if(DupMatch(match))
continue;
2294 matcomb.push_back(match);
2302 match.
Cls[ipl] = icl; match.
End[ipl] = iend;
2303 match.
Cls[jpl] = jcl; match.
End[jpl] = jend;
2304 match.
Cls[kpl] = -1; match.
End[kpl] = 0;
2306 if(DupMatch(match))
continue;
2307 match.
Chg[ipl] = 0; match.
Chg[jpl] = 0; match.
Chg[kpl] = 0;
2308 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2310 FillEndMatch(match);
2311 if(prt)
mf::LogVerbatim(
"CCTM")<<
" Tried 2-plane match"<<
" k "<<kpl<<
":"<<match.
Cls[kpl]
2312 <<
":"<<match.
End[kpl]<<
" Chg "<<match.
Chg[kpl]<<
" Err "<<match.
Err<<
" match.oErr "<<match.
oErr;
2313 if(match.
Chg[kpl] <= 0)
continue;
2314 if(match.
Err > 10 || match.
oErr > 10)
continue;
2315 matcomb.push_back(match);
2323 if(matcomb.size() == 0)
return;
2331 unsigned short nMatCl, nMiss;
2332 float toterr = match.
Err + match.
oErr;
2333 for(
unsigned int imat = 0; imat < matcomb.size(); ++imat) {
2335 if(match.
Cls[0] == matcomb[imat].Cls[0] &&
2336 match.
Cls[1] == matcomb[imat].Cls[1] &&
2337 match.
Cls[2] == matcomb[imat].Cls[2]) {
2340 if(toterr < matcomb[imat].Err + matcomb[imat].oErr) {
2342 matcomb[imat].End[0] = match.
End[0];
2343 matcomb[imat].End[1] = match.
End[1];
2344 matcomb[imat].End[2] = match.
End[2];
2345 matcomb[imat].Vtx = match.
Vtx;
2346 matcomb[imat].dWir = match.
dWir;
2347 matcomb[imat].dAng = match.
dAng;
2348 matcomb[imat].dX = match.
dX;
2349 matcomb[imat].Err = match.
Err;
2350 matcomb[imat].oVtx = match.
oVtx;
2351 matcomb[imat].odWir = match.
odWir;
2352 matcomb[imat].odAng = match.
odAng;
2353 matcomb[imat].odX = match.
odX;
2354 matcomb[imat].oErr = match.
oErr;
2361 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2362 if(match.
Cls[ipl] >= 0) {
2363 if(match.
Cls[ipl] == matcomb[imat].Cls[ipl] && (match.
End[0] == matcomb[imat].End[0] || match.
End[1] == matcomb[imat].End[1])) ++nMatCl;
2368 if(nMatCl == 2 && nMiss == 1)
return true;
2379 std::vector<CluLen> materr;
2380 unsigned int ii, im;
2382 if(matcomb.size() == 0)
return;
2385 for(ii = 0; ii < matcomb.size(); ++ii) {
2387 merr.
length = matcomb[ii].Err + matcomb[ii].oErr;
2388 materr.push_back(merr);
2390 std::sort(materr.begin(), materr.end(),
lessThan);
2394 myprt<<
"SortMatches\n";
2395 myprt<<
" ii im Vx Err dW dA dX oVx oErr odW odA odX Asym icl jcl kcl \n";
2396 for(ii = 0; ii < materr.size(); ++ii) {
2397 im = materr[ii].index;
2398 float asym = fabs(matcomb[im].Chg[0] - matcomb[im].Chg[1]) /
2399 (matcomb[im].Chg[0] + matcomb[im].Chg[1]);
2400 asym *= fabs(matcomb[im].Chg[1] - matcomb[im].Chg[2]) /
2401 (matcomb[im].Chg[1] + matcomb[im].Chg[2]);
2403 <<std::setw(5)<<ii<<std::setw(5)<<im
2404 <<std::setw(4)<<matcomb[im].Vtx
2405 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].Err
2406 <<std::setw(7)<<std::setprecision(1)<<matcomb[im].dWir
2407 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dAng
2408 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dX
2409 <<std::setw(4)<<matcomb[im].oVtx
2410 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].oErr
2411 <<std::setw(7)<<std::setprecision(1)<<matcomb[im].odWir
2412 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odAng
2413 <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odX
2414 <<std::setw(7)<<std::setprecision(3)<<asym
2415 <<
" 0:"<<matcomb[im].Cls[0]<<
":"<<matcomb[im].End[0]
2416 <<
" 1:"<<matcomb[im].Cls[1]<<
":"<<matcomb[im].End[1];
2417 if(nplanes > 2) myprt<<
" 2:"<<matcomb[im].Cls[2]<<
":"<<matcomb[im].End[2];
2423 std::array<std::vector<bool>, 3> pclUsed;
2425 for(ipl = 0; ipl < nplanes; ++ipl) {
2426 pclUsed[ipl].resize(clsChain[ipl].size());
2431 unsigned short matcombTotCl = 0;
2432 float matcombTotLen = 0;
2434 for(ii = 0; ii < matcomb.size(); ++ii) {
2435 for(ipl = 0; ipl < nplanes; ++ipl) {
2436 if(matcomb[ii].Cls[ipl] < 0)
continue;
2437 icl = matcomb[ii].Cls[ipl];
2439 matcombTotLen += clsChain[ipl][icl].Length;
2443 if(prt)
mf::LogVerbatim(
"CCTM")<<
"Number of clusters to match "<<matcombTotCl <<
" total length "<<matcombTotLen;
2445 if(matcombTotLen <= 0) {
2446 mf::LogError(
"CCTM")<<
"SortMatches: bad matcomb total length "<<matcombTotLen;
2451 std::vector<unsigned short> matIndex;
2453 std::vector<unsigned short> bestMatIndex;
2454 float totLen, totErr, bestTotErr = 9999;
2456 unsigned short jj, jm, nused, jcl;
2460 for(ii = 0; ii < materr.size(); ++ii) {
2461 im = materr[ii].index;
2464 if(matcomb[im].Err > bestTotErr)
continue;
2468 for(ipl = 0; ipl < nplanes; ++ipl) {
2472 if(matcomb[im].Cls[ipl] < 0)
continue;
2473 icl = matcomb[im].Cls[ipl];
2474 pclUsed[ipl][icl] =
true;
2475 totLen += clsChain[ipl][icl].Length;
2478 totErr = matcomb[im].Err;
2480 matIndex.push_back(im);
2482 for(jj = 0; jj < materr.size(); ++jj) {
2483 if(jj == ii)
continue;
2484 jm = materr[jj].index;
2486 if(matcomb[jm].Err > bestTotErr)
continue;
2490 for(ipl = 0; ipl < nplanes; ++ipl) {
2491 if(matcomb[jm].Cls[ipl] < 0)
continue;
2492 jcl = matcomb[jm].Cls[ipl];
2493 if(pclUsed[ipl][jcl]) ++nused;
2495 if(nused > 0)
break;
2496 totLen += clsChain[ipl][jcl].Length;
2499 if(nused != 0)
continue;
2501 totErr += matcomb[jm].Err;
2502 matIndex.push_back(jm);
2504 for(ipl = 0; ipl < nplanes; ++ipl) {
2505 if(matcomb[jm].Cls[ipl] < 0)
continue;
2506 jcl = matcomb[jm].Cls[ipl];
2507 pclUsed[ipl][jcl] =
true;
2510 if(totLen == 0)
continue;
2512 for(ipl = 0; ipl < nplanes; ++ipl) {
2513 for(
unsigned short indx = 0; indx < pclUsed[ipl].size(); ++indx)
if(pclUsed[ipl][indx]) ++nused;
2515 if(totLen > matcombTotLen) std::cout<<
"Oops "<<totLen<<
" "<<matcombTotLen<<
"\n";
2517 fracLen = totLen / matcombTotLen;
2523 myprt<<
"match "<<im<<
" totErr "<<totErr<<
" nused "<<nused<<
" fracLen "<<fracLen<<
" totLen "<<totLen<<
" mat: ";
2524 for(
unsigned short indx = 0; indx < matIndex.size(); ++indx) myprt<<
" "<<matIndex[indx];
2528 if(totErr < bestTotErr) {
2529 bestTotErr = totErr;
2530 bestMatIndex = matIndex;
2531 if(nused == matcombTotCl)
break;
2534 myprt<<
"bestTotErr "<<bestTotErr<<
" nused "<<nused<<
" matcombTotCl "<<matcombTotCl<<
" mat: ";
2535 for(
unsigned short indx = 0; indx < bestMatIndex.size(); ++indx) myprt<<
" "<<bestMatIndex[indx];
2538 if(fracLen > 0.999)
break;
2542 if(bestTotErr > 9000)
return;
2544 for(ii = 0; ii < bestMatIndex.size(); ++ii) {
2545 im = bestMatIndex[ii];
2548 FillTrkHits(fmCluHits, im);
2551 StoreTrack(fmCluHits, im, procCode);
2567 unsigned short ipl = 0;
2568 unsigned short jpl = 1;
2571 if(match.
Cls[0] < 0 || match.
Cls[1] < 0)
return;
2573 unsigned short icl = match.
Cls[ipl];
2574 unsigned short iend = match.
End[ipl];
2575 match.
Chg[ipl] = clsChain[ipl][icl].TotChg;
2577 float miX = clsChain[ipl][icl].X[iend];
2579 unsigned short oiend = 1 - iend;
2580 float oiX = clsChain[ipl][icl].X[oiend];
2582 unsigned short jcl = match.
Cls[jpl];
2583 unsigned short jend = match.
End[jpl];
2584 match.
Chg[jpl] = clsChain[jpl][jcl].TotChg;
2586 float mjX = clsChain[jpl][jcl].X[jend];
2588 unsigned short ojend = 1 - jend;
2589 float ojX = clsChain[jpl][jcl].X[ojend];
2593 if(clsChain[ipl][icl].VtxIndex[iend] >= 0 &&
2594 clsChain[ipl][icl].VtxIndex[iend] == clsChain[jpl][jcl].VtxIndex[jend]) {
2595 match.
Vtx = clsChain[ipl][icl].VtxIndex[iend];
2596 miX = vtx[match.
Vtx].X;
2597 mjX = vtx[match.
Vtx].X;
2602 if(clsChain[ipl][icl].VtxIndex[oiend] >= 0 &&
2603 clsChain[ipl][icl].VtxIndex[oiend] == clsChain[jpl][jcl].VtxIndex[ojend]) {
2604 match.
oVtx = clsChain[ipl][icl].VtxIndex[oiend];
2605 oiX = vtx[match.
oVtx].X;
2606 ojX = vtx[match.
oVtx].X;
2611 if(fChgAsymFactor[algIndex] > 0) {
2612 chgAsym = fabs(match.
Chg[ipl] - match.
Chg[jpl]) / (match.
Chg[ipl] + match.
Chg[jpl]);
2613 if(chgAsym > 0.5)
return;
2614 chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2618 float maxSlp = fabs(clsChain[ipl][icl].Slope[iend]);
2619 if(fabs(clsChain[jpl][jcl].Slope[jend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[jend]);
2620 float sigmaX = fXMatchErr[algIndex] +
std::max(maxSlp, (
float)20);
2621 match.
dX = fabs(miX - mjX);
2622 match.
Err = chgAsym * match.
dX / sigmaX;
2626 maxSlp = fabs(clsChain[ipl][icl].Slope[oiend]);
2627 if(fabs(clsChain[jpl][jcl].Slope[ojend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[ojend]);
2628 sigmaX = fXMatchErr[algIndex] +
std::max(maxSlp, (
float)20);
2629 match.
odX = fabs(oiX - ojX);
2630 match.
oErr = chgAsym * match.
odX / sigmaX;
2632 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM2: m "<<ipl<<
":"<<icl<<
":"<<iend<<
" miX "<<miX
2633 <<
" - "<<jpl<<
":"<<jcl<<
":"<<jend<<
" mjX "<<mjX<<
" match.dX "<<match.
dX 2634 <<
" match.Err "<<match.
Err<<
" chgAsym "<<chgAsym<<
" o "<<
" oiX "<<oiX
2635 <<
" ojX "<<ojX<<
" match.odX "<<match.
odX<<
" match.oErr "<<match.
oErr<<
"\n";
2651 FillEndMatch2(match);
2655 std::array<short, 3> mVtx;
2656 std::array<short, 3> oVtx;
2657 std::array<float, 3> oWir;
2658 std::array<float, 3> oSlp;
2659 std::array<float, 3> oAng;
2660 std::array<float, 3> oX;
2662 std::array<float, 3> mChg;
2664 unsigned short ii, ipl, iend, jpl, jend, kpl, kend, oend;
2665 short icl, jcl, kcl;
2667 for(ipl = 0; ipl < 3; ++ipl) {
2668 mVtx[ipl] = -1; oVtx[ipl] = -1;
2669 oWir[ipl] = -66; oSlp[ipl] = -66; oAng[ipl] = -66; oX[ipl] = -66;
2674 match.
dWir = 0; match.
dAng = 0; match.
dX = 0; match.
Err = 100;
2681 for(ipl = 0; ipl < nplanes; ++ipl) {
2682 myprt<<
" "<<ipl<<
":"<<match.
Cls[ipl]<<
":"<<match.
End[ipl];
2686 short missingPlane = -1;
2687 unsigned short nClInPln = 0;
2690 unsigned short novxmat = 0;
2692 unsigned short nvxmat = 0;
2693 unsigned short nShortCl = 0;
2695 for(ipl = 0; ipl < nplanes; ++ipl) {
2696 if(match.
Cls[ipl] < 0) {
2701 icl = match.
Cls[ipl];
2702 match.
Chg[ipl] = clsChain[ipl][icl].TotChg;
2703 mChg[ipl] = clsChain[ipl][icl].TotChg;
2704 iend = match.
End[ipl];
2705 mVtx[ipl] = clsChain[ipl][icl].VtxIndex[iend];
2706 if(clsChain[ipl][icl].Length < 6) ++nShortCl;
2707 if(mVtx[ipl] >= 0) {
2708 if(aVtx < 0) aVtx = mVtx[ipl];
2709 if(mVtx[ipl] == aVtx) ++nvxmat;
2711 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];
2714 oWir[ipl] = clsChain[ipl][icl].Wire[oend];
2715 oAng[ipl] = clsChain[ipl][icl].Angle[oend];
2716 oSlp[ipl] = clsChain[ipl][icl].Slope[oend];
2717 oX[ipl] = clsChain[ipl][icl].X[oend];
2718 oVtx[ipl] = clsChain[ipl][icl].VtxIndex[oend];
2719 if(oVtx[ipl] >= 0) {
2720 if(aoVtx < 0) aoVtx = oVtx[ipl];
2721 if(oVtx[ipl] == aoVtx) ++novxmat;
2724 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];
2728 bool isShort = (nShortCl > 1);
2735 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: Vtx m "<<aVtx<<
" count "<<nvxmat
2736 <<
" o "<<aoVtx<<
" count "<<novxmat
2737 <<
" missingPlane "<<missingPlane
2738 <<
" nClInPln "<<nClInPln;
2741 if(nvxmat == 3 && novxmat == 3) {
2742 match.
Vtx = aVtx; match.
Err = 0;
2743 match.
oVtx = aoVtx; match.
oErr = 0;
2750 float ovxFactor = 1;
2755 match.
Vtx = aVtx; vxFactor = 0.33;
2759 match.
oVtx = aoVtx; ovxFactor = 0.33;
2764 match.
Vtx = aVtx; vxFactor = 0.5;
2767 match.
oVtx = aoVtx; ovxFactor = 0.5;
2779 float kSlp, okSlp, kAng, okAng, okX,
kX, kTim, okTim;
2782 ipl = 0; jpl = 1; kpl = 2;
2788 }
else if(kpl == 1) {
2794 iend = match.
End[ipl]; jend = match.
End[jpl];
2795 icl = match.
Cls[ipl]; jcl = match.
Cls[jpl];
2797 kcl = match.
Cls[kpl];
2798 kend = match.
End[kpl];
2802 okSlp = geom->ThirdPlaneSlope(ipl, oSlp[ipl], jpl, oSlp[jpl], tpc, cstat);
2803 okAng = atan(okSlp);
2806 bool ignoreSign = (fabs(okSlp) > 10);
2807 if(ignoreSign) okAng = fabs(okAng);
2808 if(match.
oVtx >= 0) {
2810 okWir = geom->WireCoordinate(vtx[match.
oVtx].Y, vtx[match.
oVtx].Z, kpl, tpc, cstat);
2811 okX = vtx[match.
oVtx].X;
2814 geom->IntersectionPoint(oWir[ipl], oWir[jpl],ipl, jpl, cstat, tpc, ypos, zpos);
2815 okWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2816 okX = 0.5 * (oX[ipl] + oX[jpl]);
2818 okTim = detprop->ConvertXToTicks(okX, kpl, tpc, cstat);
2819 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: oEnd"<<
" kpl "<<kpl<<
" okSlp "<<okSlp<<
" okAng " 2820 <<okAng<<
" okWir "<<(int)okWir<<
" okX "<<okX;
2825 kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2827 if(ignoreSign) kAng = fabs(kAng);
2828 if(match.
Vtx >= 0) {
2829 if(vtx.size() == 0 || (
unsigned int)match.
Vtx > vtx.size() - 1) {
2830 mf::LogError(
"CCTM")<<
"FEM: Bad match.Vtx "<<match.
Vtx<<
" vtx size "<<vtx.size();
2834 kWir = geom->WireCoordinate(vtx[match.
Vtx].Y, vtx[match.
Vtx].Z, kpl, tpc, cstat);
2835 kX = vtx[match.
Vtx].X;
2838 geom->IntersectionPoint(clsChain[ipl][icl].Wire[iend], clsChain[jpl][jcl].Wire[jend], ipl, jpl, cstat, tpc, ypos, zpos);
2839 kWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2840 kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2842 kTim = detprop->ConvertXToTicks(kX, kpl, tpc, cstat);
2843 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: mEnd"<<
" kpl "<<kpl<<
" kSlp "<<kSlp<<
" kAng "<<kAng<<
" kX "<<
kX;
2846 if(nClInPln < 3 && FindMissingCluster(kpl, kcl, kend, kWir, kX, okWir, okX)) {
2849 match.
Cls[kpl] = kcl;
2850 match.
End[kpl] = kend;
2851 match.
Chg[kpl] = clsChain[kpl][kcl].TotChg;
2852 mChg[kpl] = clsChain[kpl][kcl].TotChg;
2854 oWir[kpl] = clsChain[kpl][kcl].Wire[oend];
2855 oX[kpl] = clsChain[kpl][kcl].X[oend];
2856 oAng[kpl] = clsChain[kpl][kcl].Angle[oend];
2857 oSlp[kpl] = clsChain[kpl][kcl].Slope[oend];
2862 if(nClInPln == 2 && fabs(okWir - kWir) > 3)
return;
2868 if(nClInPln < 3 && mChg[missingPlane] <= 0) {
2869 if(missingPlane != kpl)
mf::LogError(
"CCTM")<<
"FEM bad missingPlane "<<missingPlane<<
" "<<kpl<<
"\n";
2870 mChg[kpl] = ChargeNear(kpl, (
unsigned short)kWir, kTim, (
unsigned short)okWir, okTim);
2871 match.
Chg[kpl] = mChg[kpl];
2872 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: Missing cluster in "<<kpl<<
" ChargeNear "<<(int)kWir<<
":"<<(
int)kTim
2873 <<
" "<<(int)okWir<<
":"<<(
int)okTim<<
" chg "<<mChg[kpl];
2874 if(mChg[kpl] <= 0)
return;
2877 if(fChgAsymFactor[algIndex] > 0) {
2878 chgAsym = ChargeAsym(mChg);
2879 if(chgAsym > 0.5)
return;
2880 chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2883 if(prt)
mf::LogVerbatim(
"CCTM")<<
"FEM: charge asymmetry factor "<<chgAsym;
2884 float sigmaX, sigmaA;
2890 bool allPlnVtxMatch =
false;
2892 unsigned short nmvtx = 0;
2893 for(ii = 0; ii < nplanes; ++ii) {
2895 if(aVtx < 0) aVtx = mVtx[ii];
2900 if(nmvtx ) allPlnVtxMatch =
true;
2904 sigmaX = fXMatchErr[algIndex] +
std::max(kSlp, (
float)20);
2905 sigmaA = fAngleMatchErr[algIndex] * AngleFactor(kSlp);
2906 if(prt)
mf::LogVerbatim(
"CCTM")<<
"bb "<<algIndex<<
" "<<fXMatchErr[algIndex]<<
" "<<fAngleMatchErr[algIndex]<<
" kslp "<<kSlp;
2909 kcl = match.
Cls[kpl];
2910 kend = match.
End[kpl];
2911 dw = kWir - clsChain[kpl][kcl].Wire[kend];
2913 if(fabs(match.
dWir) > 100)
return;
2914 if(match.
Vtx >= 0) {
2915 match.
dX = kX - clsChain[kpl][kcl].X[kend];
2917 match.
dX = std::abs(clsChain[ipl][icl].
X[iend] - clsChain[jpl][jcl].
X[jend]) +
2918 std::abs(clsChain[ipl][icl].
X[iend] - clsChain[kpl][kcl].
X[kend]);
2924 match.
dAng = kAng - fabs(clsChain[kpl][kcl].Angle[kend]);
2926 match.
dAng = kAng - clsChain[kpl][kcl].Angle[kend];
2929 da = fabs(match.
dAng) / sigmaA;
2930 dx = fabs(match.
dX) / sigmaX;
2931 if(allPlnVtxMatch) {
2933 match.
Err = vxFactor * chgAsym * da / 3;
2938 match.
Err = vxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2945 match.
dX = clsChain[ipl][icl].X[iend] - clsChain[jpl][jcl].X[jend];
2947 match.
Err = 3 + vxFactor * chgAsym * fabs(match.
dX) / sigmaX;
2954 dw = okWir - oWir[kpl];
2956 if(match.
oVtx >= 0) {
2957 match.
odX = okX - oX[kpl];
2959 match.
odX = std::abs(oX[ipl] - oX[jpl]) + std::abs(oX[ipl] - oX[kpl]);
2965 match.
odAng = okAng - fabs(oAng[kpl]);
2967 match.
odAng = okAng - oAng[kpl];
2970 da = match.
odAng / sigmaA;
2971 dx = fabs(match.
odX) / sigmaX;
2975 match.
oErr = ovxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2979 match.
odX = (oX[ipl] - oX[jpl]) / sigmaX;
2980 match.
oErr = 3 + ovxFactor * chgAsym * fabs(match.
odX);
3006 kkX = clsChain[kkpl][kkcl].X[kkend];
3007 float matchTime = detprop->ConvertXToTicks(kkX, kkpl, tpc, cstat);
3010 std::vector<unsigned int> wirs;
3011 std::vector<unsigned int> plns;
3012 std::vector<art::Ptr<recob::Hit>> clusterhits;
3013 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3014 if(ipl == kkpl)
continue;
3016 if(match.
Cls[ipl] < 0)
continue;
3017 float dTime, best = 99999;
3018 unsigned short wire = 0;
3019 unsigned short icl, ccl = match.
Cls[ipl];
3021 for(
unsigned short ii = 0; ii < clsChain[kkpl][ccl].ClsIndex.size(); ++ii) {
3022 icl = clsChain[kkpl][ccl].ClsIndex[ii];
3023 if(cls[ipl][icl].EvtIndex > fmCluHits.size() -1) {
3024 std::cout<<
"Bad ClsIndex in FMPM\n";
3027 clusterhits = fmCluHits.at(cls[ipl][icl].EvtIndex);
3029 for(
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
3030 dTime = fabs(clusterhits[iht]->PeakTime() - matchTime);
3033 wire = clusterhits[iht]->WireID().Wire;
3037 wirs.push_back(wire);
3038 plns.push_back(ipl);
3041 if(wirs.size() != 2)
return;
3043 geom->IntersectionPoint(wirs[0], wirs[1], plns[0], plns[1], cstat, tpc, Y, Z);
3044 kkWir = geom->WireCoordinate(Y, Z, kkpl, tpc, cstat);
3049 bool CCTrackMaker::FindMissingCluster(
unsigned short kpl,
short& kcl,
unsigned short& kend,
float kWir,
float kX,
float okWir,
float okX)
3053 unsigned short okend;
3056 if(kcl >= 0)
return false;
3059 float kslp = fabs((okX - kX) / (okWir - kWir));
3060 if(kslp > 20) kslp = 20;
3062 dxcut = 3 * fXMatchErr[algIndex] + kslp;
3063 unsigned short nfound = 0;
3064 unsigned short foundCl = 0, foundEnd = 0;
3065 for(
unsigned short ccl = 0; ccl < clsChain[kpl].size(); ++ccl) {
3066 if(clsChain[kpl][ccl].InTrack >= 0)
continue;
3068 for(
unsigned short end = 0;
end < 2; ++
end) {
3070 if(fabs(clsChain[kpl][ccl].Wire[
end] - kWir) > 4)
continue;
3071 if(fabs(clsChain[kpl][ccl].Wire[okend] - okWir) > 4)
continue;
3074 if(fabs(clsChain[kpl][ccl].
X[
end] - kX) > dxcut && fabs(clsChain[kpl][ccl].
X[okend] - okX) > dxcut)
continue;
3080 if(nfound == 0)
return false;
3082 mf::LogVerbatim(
"CCTM")<<
"FindMissingCluster: Found too many matches. Write some code "<<nfound;
3092 float CCTrackMaker::ChargeAsym(std::array<float, 3>& mChg)
3096 float big = 0, small = 1.E9;
3097 for(
unsigned short ii = 0; ii < 3; ++ii) {
3098 if(mChg[ii] < small) small = mChg[ii];
3099 if(mChg[ii] > big) big = mChg[ii];
3102 return (big - small) / (big + small);
3113 for(ipl = 0; ipl < 3; ++ipl) trkHits[ipl].
clear();
3115 if(imat > matcomb.size())
return;
3117 unsigned short indx;
3118 std::vector<art::Ptr<recob::Hit>> clusterhits;
3119 unsigned short icc, ccl, icl, ecl, iht, ii;
3120 short endOrder, fillOrder;
3122 if(prt)
mf::LogVerbatim(
"CCTM")<<
"In FillTrkHits: matcomb "<<imat<<
" cluster chains "<<matcomb[imat].Cls[0]<<
" "<<matcomb[imat].Cls[1]<<
" "<<matcomb[imat].Cls[2];
3124 for(ipl = 0; ipl < nplanes; ++ipl) {
3125 if(matcomb[imat].Cls[ipl] < 0)
continue;
3127 ccl = matcomb[imat].Cls[ipl];
3129 endOrder = 1 - 2 * matcomb[imat].End[ipl];
3132 std::reverse(clsChain[ipl][ccl].ClsIndex.begin(), clsChain[ipl][ccl].ClsIndex.end());
3133 std::reverse(clsChain[ipl][ccl].Order.begin(), clsChain[ipl][ccl].Order.end());
3134 for(ii = 0; ii < clsChain[ipl][ccl].Order.size(); ++ii) clsChain[ipl][ccl].Order[ii] = 1 - clsChain[ipl][ccl].Order[ii];
3136 if(ccl > clsChain[ipl].size() - 1) {
3137 mf::LogError(
"CCTM")<<
"Bad cluster chain index "<<ccl<<
" in plane "<<ipl;
3141 for(icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
3142 icl = clsChain[ipl][ccl].ClsIndex[icc];
3143 if(icl > fmCluHits.size() - 1) {
3144 std::cout<<
"oops in FTH "<<icl<<
" clsChain size "<<clsChain[ipl].size()<<
"\n";
3147 ecl = cls[ipl][icl].EvtIndex;
3148 if(ecl > fmCluHits.size() - 1) {
3149 std::cout<<
"FTH bad EvtIndex "<<ecl<<
" fmCluHits size "<<fmCluHits.size()<<
"\n";
3152 clusterhits = fmCluHits.at(ecl);
3153 if(clusterhits.size() == 0) {
3154 std::cout<<
"FTH no cluster hits for EvtIndex "<<cls[ipl][icl].EvtIndex<<
"\n";
3157 indx = trkHits[ipl].size();
3158 trkHits[ipl].resize(indx + clusterhits.size());
3160 fillOrder = 1 - 2 * clsChain[ipl][ccl].Order[icc];
3162 if(fillOrder == 1) {
3164 for(iht = 0; iht < clusterhits.size(); ++iht) {
3165 if(indx + iht > trkHits[ipl].size() - 1) std::cout<<
"FTH oops3\n";
3166 trkHits[ipl][indx + iht] = clusterhits[iht];
3171 for(ii = 0; ii < clusterhits.size(); ++ii) {
3172 iht = clusterhits.size() - 1 - ii;
3173 if(indx + ii > trkHits[ipl].size() - 1) std::cout<<
"FTH oops4\n";
3174 trkHits[ipl][indx + ii] = clusterhits[iht];
3178 ii = trkHits[ipl].size() - 1;
3179 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();
3189 void CCTrackMaker::PrintTracks()
const 3192 myprt<<
"********* PrintTracks \n";
3193 myprt<<
"vtx Index X Y Z\n";
3194 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3195 myprt<<
std::right<<std::setw(4)<<ivx<<std::setw(4)<<vtx[ivx].EvtIndex;
3197 myprt<<
std::right<<std::setw(10)<<std::setprecision(1)<<vtx[ivx].X;
3198 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3199 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3200 if(vtx[ivx].Neutrino) myprt<<
" Neutrino vertex";
3204 myprt<<
">>>>>>>>>> Tracks \n";
3205 myprt<<
"trk ID Proc nht nTrj sX sY sZ eX eY eZ sVx eVx sGd eGd ChgOrd dirZ Mom PDG ClsIndices\n";
3206 for(
unsigned short itr = 0; itr <
trk.size(); ++itr) {
3207 myprt<<
std::right<<std::setw(3)<<itr<<std::setw(4)<<
trk[itr].ID;
3208 myprt<<
std::right<<std::setw(5)<<std::setw(4)<<
trk[itr].Proc;
3209 unsigned short nht = 0;
3210 for(
unsigned short ii = 0; ii < 3; ++ii) nht +=
trk[itr].TrkHits[ii].size();
3212 myprt<<std::setw(4)<<
trk[itr].TrjPos.size();
3214 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](0);
3215 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](1);
3216 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[0](2);
3217 unsigned short itj =
trk[itr].TrjPos.size() - 1;
3218 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](0);
3219 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](1);
3220 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<
trk[itr].TrjPos[itj](2);
3221 myprt<<std::setw(4)<<
trk[itr].VtxIndex[0]<<std::setw(4)<<
trk[itr].VtxIndex[1];
3222 myprt<<std::setw(4)<<
trk[itr].GoodEnd[0];
3223 myprt<<std::setw(4)<<
trk[itr].GoodEnd[1];
3224 myprt<<std::setw(4)<<
trk[itr].ChgOrder;
3225 myprt<<
std::right<<std::setw(10)<<std::setprecision(3)<<
trk[itr].TrjDir[itj](2);
3228 for(
unsigned short ii = 0; ii <
trk[itr].ClsEvtIndices.size(); ++ii) myprt<<
" "<<
trk[itr].ClsEvtIndices[ii];
3239 unsigned short iTime;
3241 myprt<<
"******* PrintClusters ********* Num_Clusters_in Wire:Time\n";
3242 myprt<<
"vtx Index X Y Z Pln0 Pln1 Pln2 Pln0 Pln1 Pln2\n";
3243 for(
unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3244 myprt<<
std::right<<std::setw(3)<<ivx<<std::setw(7)<<ivx;
3246 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].X;
3247 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3248 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3249 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[0];
3250 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[1];
3251 myprt<<
std::right<<std::setw(5)<<vtx[ivx].nClusInPln[2];
3253 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3254 int time = (0.5 + detprop->ConvertXToTicks(vtx[ivx].
X, ipl, tpc, cstat));
3255 int wire = geom->WireCoordinate(vtx[ivx].
Y, vtx[ivx].
Z, ipl, tpc, cstat);
3256 myprt<<
std::right<<std::setw(7)<<wire<<
":"<<time;
3262 for(
unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3263 myprt<<
">>>>>>>>>> Cluster chains in Plane "<<ipl<<
"\n";
3264 myprt<<
"ipl ccl Len Chg W0:T0 Ang0 Dir0 Vx0 mBk0 W1:T1 Ang1 Dir1 Vx1 mBk1 InTk cls:Order \n";
3265 for(
unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
3268 myprt<<
std::right<<std::setw(6)<<clsChain[ipl][ccl].Length;
3269 myprt<<
std::right<<std::setw(8)<<(int)clsChain[ipl][ccl].TotChg;
3270 for(
unsigned short end = 0;
end < 2; ++
end) {
3271 iTime = clsChain[ipl][ccl].Time[
end];
3272 myprt<<
std::right<<std::setw(5)<<(int)clsChain[ipl][ccl].Wire[
end]
3273 <<
":"<<std::setprecision(1)<<iTime;
3276 }
else if(iTime < 100) {
3278 }
else if(iTime < 1000) myprt<<
" ";
3279 myprt<<
std::right<<std::setw(7)<<std::setprecision(2)<<clsChain[ipl][ccl].Angle[
end];
3280 myprt<<
std::right<<std::setw(5)<<clsChain[ipl][ccl].Dir[
end];
3281 myprt<<
std::right<<std::setw(5)<<clsChain[ipl][ccl].VtxIndex[
end];
3282 myprt<<std::fixed<<
std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].mBrkIndex[
end];
3285 myprt<<
std::right<<std::setw(7)<<clsChain[ipl][ccl].InTrack;
3287 for(
unsigned short ii = 0; ii < clsChain[ipl][ccl].ClsIndex.size(); ++ii)
3288 myprt<<
" "<<clsChain[ipl][ccl].ClsIndex[ii]<<
":"<<clsChain[ipl][ccl].Order[ii];
3291 if(fPrintAllClusters) {
3292 myprt<<
">>>>>>>>>> Clusters in Plane "<<ipl<<
"\n";
3293 myprt<<
"ipl icl Evt Len Chg W0:T0 Ang0 Dir0 Vx0 CN0 W1:T1 Ang1 Dir1 Vx1 CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
3294 for(
unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
3297 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].EvtIndex;
3298 myprt<<
std::right<<std::setw(6)<<cls[ipl][icl].Length;
3299 myprt<<
std::right<<std::setw(8)<<(int)cls[ipl][icl].TotChg;
3300 for(
unsigned short end = 0;
end < 2; ++
end) {
3301 iTime = cls[ipl][icl].Time[
end];
3302 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].Wire[
end]<<
":"<<iTime;
3305 }
else if(iTime < 100) {
3307 }
else if(iTime < 1000) myprt<<
" ";
3308 myprt<<
std::right<<std::setw(7)<<std::setprecision(2)<<cls[ipl][icl].Angle[
end];
3310 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].VtxIndex[
end];
3311 myprt<<std::fixed<<
std::right<<std::setw(5)<<std::setprecision(1)<<cls[ipl][icl].ChgNear[
end];
3314 myprt<<
std::right<<std::setw(5)<<cls[ipl][icl].InTrack;
3315 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[0];
3316 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[0];
3317 myprt<<
std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[1];
3318 myprt<<
std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[1];
3326 float CCTrackMaker::AngleFactor(
float slope)
3328 float slp = fabs(slope);
3329 if(slp > 10.) slp = 30.;
3331 return 1 + 0.05 * slp * slp;
3335 float CCTrackMaker::ChargeNear(
unsigned short ipl,
unsigned short wire1,
float time1,
unsigned short wire2,
float time2)
3341 unsigned short w1 = wire1;
3342 unsigned short w2 = wire2;
3355 slp = (t2 -
t1) / (w2 - w1);
3358 unsigned short wire;
3361 for(
unsigned short hit = 0;
hit < allhits.size(); ++
hit) {
3362 if(allhits[
hit]->WireID().Cryostat != cstat)
continue;
3363 if(allhits[
hit]->WireID().TPC != tpc)
continue;
3364 if(allhits[
hit]->WireID().Plane != ipl)
continue;
3365 wire = allhits[
hit]->WireID().Wire;
3366 if(wire < w1)
continue;
3367 if(wire > w2)
continue;
3368 prtime = t1 + (wire - w1) * slp;
3370 if(prtime > allhits[
hit]->PeakTimePlusRMS(3))
continue;
3371 if(prtime < allhits[
hit]->PeakTimeMinusRMS(3))
continue;
3372 chg += ChgNorm[ipl] * allhits[
hit]->Integral();
3385 for(ipl = 0; ipl < 3; ++ipl) {
3386 firstWire[ipl] = INT_MAX;
3388 firstHit[ipl] = INT_MAX;
3390 WireHitRange[ipl].clear();
3395 unsigned short oldipl = 0;
3396 for(
unsigned int hit = 0;
hit < allhits.size(); ++
hit) {
3397 if(allhits[
hit]->WireID().Cryostat != cstat)
continue;
3398 if(allhits[
hit]->WireID().TPC != tpc)
continue;
3399 ipl = allhits[
hit]->WireID().Plane;
3400 if(allhits[
hit]->WireID().Wire > geom->Nwires(ipl, tpc, cstat)) {
3401 if(lastWire[ipl] < firstWire[ipl]) {
3402 mf::LogError(
"CCTM")<<
"Invalid WireID().Wire "<<allhits[
hit]->WireID().Wire;
3408 mf::LogError(
"CCTM")<<
"Hits are not in increasing-plane order\n";
3412 if(firstHit[ipl] == INT_MAX) {
3413 firstHit[ipl] =
hit;
3414 firstWire[ipl] = allhits[
hit]->WireID().Wire;
3417 lastWire[ipl] = allhits[
hit]->WireID().Wire;
3421 for(ipl = 0; ipl < nplanes; ++ipl) {
3422 if(lastWire[ipl] < firstWire[ipl]) {
3423 mf::LogError(
"CCTM")<<
"Invalid first/last wire in plane "<<ipl;
3430 for(ipl = 0; ipl < nplanes; ++ipl) ChgNorm[ipl] = 1;
3437 int sflag, nwires, wire;
3438 unsigned int indx, thisWire, thisHit, lastFirstHit;
3440 for(ipl = 0; ipl < nplanes; ++ipl) {
3441 nwires = lastWire[ipl] - firstWire[ipl] + 1;
3442 WireHitRange[ipl].resize(nwires);
3445 for(wire = 0; wire < nwires; ++wire) WireHitRange[ipl][wire] = std::make_pair(sflag, sflag);
3448 for(wire = 0; wire < nwires; ++wire) {
3456 lastWire[ipl] = firstWire[ipl];
3457 thisHit = firstHit[ipl];
3458 lastFirstHit = firstHit[ipl];
3459 for(
unsigned int hit = firstHit[ipl];
hit <= lastHit[ipl]; ++
hit) {
3460 thisWire = allhits[
hit]->WireID().Wire;
3461 if(thisWire > lastWire[ipl]) {
3462 indx = lastWire[ipl] - firstWire[ipl];
3463 int tmp1 = lastFirstHit;
3465 WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3466 lastWire[ipl] = thisWire;
3467 lastFirstHit = thisHit;
3468 }
else if(thisWire < lastWire[ipl]) {
3469 mf::LogError(
"CCTM")<<
"Hit not in proper order in plane "<<ipl;
3475 indx = lastWire[ipl] - firstWire[ipl];
3476 int tmp1 = lastFirstHit;
3478 int tmp2 = lastHit[ipl];
3479 WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3485 for(ipl = 0; ipl < nplanes; ++ipl) {
3486 if(firstWire[ipl] < INT_MAX)
continue;
3487 if(lastWire[ipl] > 0)
continue;
3488 if(firstHit[ipl] < INT_MAX)
continue;
3489 if(lastHit[ipl] > 0)
continue;
3490 std::cout<<
"FWHR problem\n";
3494 unsigned int nht = 0;
3495 std::vector<bool> hchk(allhits.size());
3496 for(
unsigned int ii = 0; ii < hchk.size(); ++ii) hchk[ii] =
false;
3497 for(ipl = 0; ipl < nplanes; ++ipl) {
3498 for(
unsigned int w = firstWire[ipl];
w < lastWire[ipl]; ++
w) {
3499 indx =
w - firstWire[ipl];
3500 if(indx > lastWire[ipl]) {
3501 std::cout<<
"FWHR bad index "<<indx<<
"\n";
3505 if(WireHitRange[ipl][indx].first < 0)
continue;
3506 unsigned int firhit = WireHitRange[ipl][indx].first;
3507 unsigned int lashit = WireHitRange[ipl][indx].second;
3508 for(
unsigned int hit = firhit;
hit < lashit; ++
hit) {
3510 if(
hit > allhits.size() -1) {
3511 std::cout<<
"FWHR: Bad hchk "<<
hit<<
" size "<<allhits.size()<<
"\n";
3515 if(allhits[
hit]->WireID().
Plane != ipl || allhits[
hit]->WireID().Wire !=
w) {
3516 std::cout<<
"FWHR bad plane "<<allhits[
hit]->WireID().Plane<<
" "<<ipl<<
" or wire "<<allhits[
hit]->WireID().Wire<<
" "<<
w<<
"\n";
3523 if(nht != allhits.size()) {
3524 std::cout<<
"FWHR hit count problem "<<nht<<
" "<<allhits.size()<<
"\n";
3525 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
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
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
Planes which measure X direction.
Geometry information for a single TPC.
std::vector< art::Ptr< recob::Hit > > allhits
std::array< short, 2 > Dir
TrackTrajectory::Flags_t Flags_t
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)
Provides recob::Track data product.
A trajectory in space reconstructed from hits.
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::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
std::array< float, 2 > Wire
Declaration of cluster object.
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.
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
bool FillWireHitRange(TCSlice &slc)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
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