20 #include "art/Framework/Core/EDProducer.h" 
   21 #include "art/Framework/Core/ModuleMacros.h" 
   22 #include "art/Framework/Principal/Event.h" 
   23 #include "art/Framework/Principal/Handle.h" 
   24 #include "art/Framework/Services/Registry/ServiceHandle.h" 
   25 #include "canvas/Persistency/Common/Ptr.h" 
   26 #include "fhiclcpp/ParameterSet.h" 
   27 #include "messagefacility/MessageLogger/MessageLogger.h" 
   51   return (c1.length > c2.length);
 
   56   return (c1.length < c2.length);
 
   73     art::ServiceHandle<geo::Geometry const> 
geom;
 
  133       std::array<float, 2> 
X;          
 
  150     std::array<std::vector<clPar>, 3> 
cls;
 
  155       std::array<float, 2> 
X;        
 
  186     std::array<std::vector<unsigned short>, 3> 
vxCls;
 
  191       std::array<std::vector<art::Ptr<recob::Hit>>, 3> 
TrkHits;
 
  207     std::array<std::vector<art::Ptr<recob::Hit>>, 3> 
trkHits;
 
  209     std::array<std::vector<art::Ptr<recob::Hit>>, 3> 
seedHits;
 
  221       std::array<unsigned short, 3> 
End;
 
  243                            art::FindManyP<recob::Hit> 
const& fmCluHits);
 
  244     float dXClTraj(art::FindManyP<recob::Hit> 
const& fmCluHits,
 
  248                    unsigned short icl2);
 
  257                   art::FindManyP<recob::Hit> 
const& fmCluHits);
 
  260                   art::FindManyP<recob::Hit> 
const& fmCluHits);
 
  262     void AngMatch(art::FindManyP<recob::Hit> 
const& fmCluHits);
 
  279                             unsigned short& kend,
 
  288                      art::FindManyP<recob::Hit> 
const& fmCluHits,
 
  289                      unsigned short procCode);
 
  292     void FillTrkHits(art::FindManyP<recob::Hit> 
const& fmCluHits, 
unsigned short imat);
 
  299                     art::FindManyP<recob::Hit> 
const& fmCluHits,
 
  301                     unsigned short procCode);
 
  305                      unsigned short wire1,
 
  307                      unsigned short wire2,
 
  318     fHitModuleLabel = pset.get<std::string>(
"HitModuleLabel");
 
  319     fClusterModuleLabel = pset.get<std::string>(
"ClusterModuleLabel");
 
  320     fVertexModuleLabel = pset.get<std::string>(
"VertexModuleLabel");
 
  322     fMatchAlgs = pset.get<std::vector<short>>(
"MatchAlgs");
 
  323     fXMatchErr = pset.get<std::vector<float>>(
"XMatchErr");
 
  324     fAngleMatchErr = pset.get<std::vector<float>>(
"AngleMatchErr");
 
  325     fChgAsymFactor = pset.get<std::vector<float>>(
"ChgAsymFactor");
 
  326     fMatchMinLen = pset.get<std::vector<float>>(
"MatchMinLen");
 
  327     fMakeAlgTracks = pset.get<std::vector<bool>>(
"MakeAlgTracks");
 
  329     fMaxDAng = pset.get<
float>(
"MaxDAng");
 
  330     fChainMaxdX = pset.get<
float>(
"ChainMaxdX");
 
  331     fChainVtxAng = pset.get<
float>(
"ChainVtxAng");
 
  332     fMergeChgAsym = pset.get<
float>(
"MergeChgAsym");
 
  334     fFiducialCut = pset.get<
float>(
"FiducialCut");
 
  335     fDeltaRayCut = pset.get<
float>(
"DeltaRayCut");
 
  337     fMakePFPs = pset.get<
bool>(
"MakePFPs");
 
  339     fNVtxTrkHitsFit = pset.get<
unsigned short>(
"NVtxTrkHitsFit");
 
  340     fHitFitErrFac = pset.get<
float>(
"HitFitErrFac");
 
  342     fuBCode = pset.get<
bool>(
"uBCode");
 
  344     fDebugAlg = pset.get<
short>(
"DebugAlg");
 
  345     fDebugPlane = pset.get<
short>(
"DebugPlane");
 
  346     fDebugCluster = pset.get<
short>(
"DebugCluster");
 
  347     fPrintAllClusters = pset.get<
bool>(
"PrintAllClusters");
 
  350     if (fMatchAlgs.size() > fXMatchErr.size() || fMatchAlgs.size() > fAngleMatchErr.size() ||
 
  351         fMatchAlgs.size() > fChgAsymFactor.size() || fMatchAlgs.size() > fMatchMinLen.size() ||
 
  352         fMatchAlgs.size() > fMakeAlgTracks.size()) {
 
  353       mf::LogError(
"CCTM") << 
"Incompatible fcl input vector sizes";
 
  357     for (
unsigned short ii = 0; ii < fMatchAlgs.size(); ++ii) {
 
  358       if (fAngleMatchErr[ii] <= 0 || fXMatchErr[ii] <= 0) {
 
  359         mf::LogError(
"CCTM") << 
"Invalid matching parameters " << fAngleMatchErr[ii] << 
" " 
  365     produces<std::vector<recob::PFParticle>>();
 
  366     produces<art::Assns<recob::PFParticle, recob::Track>>();
 
  367     produces<art::Assns<recob::PFParticle, recob::Cluster>>();
 
  368     produces<art::Assns<recob::PFParticle, recob::Seed>>();
 
  369     produces<art::Assns<recob::PFParticle, recob::Vertex>>();
 
  370     produces<std::vector<recob::Vertex>>();
 
  371     produces<std::vector<recob::Track>>();
 
  372     produces<art::Assns<recob::Track, recob::Hit>>();
 
  373     produces<std::vector<recob::Seed>>();
 
  384     auto tcol = std::make_unique<std::vector<recob::Track>>();
 
  385     auto thassn = std::make_unique<art::Assns<recob::Track, recob::Hit>>();
 
  386     auto vcol = std::make_unique<std::vector<recob::Vertex>>();
 
  387     auto pcol = std::make_unique<std::vector<recob::PFParticle>>();
 
  388     auto ptassn = std::make_unique<art::Assns<recob::PFParticle, recob::Track>>();
 
  389     auto pcassn = std::make_unique<art::Assns<recob::PFParticle, recob::Cluster>>();
 
  390     auto psassn = std::make_unique<art::Assns<recob::PFParticle, recob::Seed>>();
 
  391     auto pvassn = std::make_unique<art::Assns<recob::PFParticle, recob::Vertex>>();
 
  394     auto scol = std::make_unique<std::vector<recob::Seed>>();
 
  395     auto shassn = std::make_unique<art::Assns<recob::Seed, recob::Hit>>();
 
  398     art::Handle<std::vector<recob::Hit>> allhitsListHandle;
 
  400     art::Handle<std::vector<recob::Cluster>> clusterListHandle;
 
  401     std::vector<art::Ptr<recob::Cluster>> clusterlist;
 
  403     art::Handle<std::vector<recob::Vertex>> VtxListHandle;
 
  404     std::vector<art::Ptr<recob::Vertex>> vtxlist;
 
  409       art::fill_ptr_vector(
allhits, allhitsListHandle);
 
  412     if (evt.getByLabel(fClusterModuleLabel, clusterListHandle))
 
  413       art::fill_ptr_vector(clusterlist, clusterListHandle);
 
  414     if (clusterlist.size() == 0) 
return;
 
  416     art::FindManyP<recob::Hit> fmCluHits(clusterListHandle, evt, fClusterModuleLabel);
 
  419     if (evt.getByLabel(fVertexModuleLabel, VtxListHandle))
 
  420       art::fill_ptr_vector(vtxlist, VtxListHandle);
 
  421     art::FindManyP<recob::Cluster, unsigned short> fmVtxCls(VtxListHandle, evt, fVertexModuleLabel);
 
  423     std::vector<CluLen> clulens;
 
  425     unsigned short ipl, icl, 
end, itr, tID, tIndex;
 
  433     std::vector<art::Ptr<recob::Hit>> tmpHits;
 
  434     std::vector<art::Ptr<recob::Cluster>> tmpCls;
 
  435     std::vector<art::Ptr<recob::Vertex>> tmpVtx;
 
  438     std::vector<size_t> dtrIndices;
 
  441     double sPos[3], sDir[3];
 
  442     double sErr[3] = {0, 0, 0};
 
  445       art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
 
  448     std::vector<art::Ptr<recob::Hit>> clusterhits;
 
  449     for (icl = 0; icl < clusterlist.size(); ++icl) {
 
  450       ipl = clusterlist[icl]->Plane().Plane;
 
  451       clusterhits = fmCluHits.at(icl);
 
  452       if (clusterhits[0]->
WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
 
  453         std::cout << 
"CCTM Cluster-Hit End wire mis-match " << clusterhits[0]->WireID().Wire
 
  454                   << 
" vs " << std::nearbyint(clusterlist[icl]->EndWire()) << 
" Bail out! \n";
 
  457       for (
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
 
  458         if (clusterhits[iht]->
WireID().Plane != ipl) {
 
  459           std::cout << 
"CCTM Cluster-Hit plane mis-match " << ipl << 
" vs " 
  460                     << clusterhits[iht]->WireID().Plane << 
" on hit " << iht << 
" Bail out! \n";
 
  473         for (ipl = 0; ipl < 3; ++ipl) {
 
  480         for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
  483           for (icl = 0; icl < clusterlist.size(); ++icl) {
 
  484             if (clusterlist[icl]->
Plane().Cryostat != 
cstat) 
continue;
 
  485             if (clusterlist[icl]->
Plane().TPC != 
tpc) 
continue;
 
  486             if (clusterlist[icl]->
Plane().
Plane != ipl) 
continue;
 
  489             clulen.length = clusterlist[icl]->EndWire();
 
  490             clulens.push_back(clulen);
 
  492           if (clulens.size() == 0) 
continue;
 
  494           std::sort(clulens.begin(), clulens.end(), 
lessThan);
 
  495           if (clulens.size() == 0) 
continue;
 
  496           for (
unsigned short ii = 0; ii < clulens.size(); ++ii) {
 
  497             const unsigned short icl = clulens[ii].index;
 
  522             if (clstr.
Time[1] > clstr.
Time[0]) {
 
  539             clstr.
Length = (
unsigned short)(0.5 + clstr.
Wire[1] - clstr.
Wire[0]);
 
  542             clusterhits = fmCluHits.at(icl);
 
  543             if (clusterhits.size() == 0) {
 
  544               mf::LogError(
"CCTM") << 
"No associated cluster hits " << icl;
 
  548             clstr.
TotChg *= clstr.
Length / (float)clusterhits.size();
 
  549             cls[ipl].push_back(clstr);
 
  557         for (
unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
 
  561           vtxlist[ivx]->XYZ(xyz);
 
  568           std::vector<art::Ptr<recob::Cluster>> 
const& vtxCls = fmVtxCls.at(ivx);
 
  569           std::vector<const unsigned short*> 
const& vtxClsEnd = fmVtxCls.data(ivx);
 
  570           for (
unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
 
  571             icl = vtxCls[vcass].key();
 
  573             ipl = vtxCls[vcass]->Plane().Plane;
 
  574             end = *vtxClsEnd[vcass];
 
  576               throw cet::exception(
"CCTM")
 
  577                 << 
"Invalid end data from vertex - cluster association" << 
end;
 
  581             for (
unsigned short jcl = 0; jcl < 
cls[ipl].size(); ++jcl) {
 
  582               if (
cls[ipl][jcl].EvtIndex == icl) {
 
  583                 cls[ipl][jcl].VtxIndex[
end] = ivx;
 
  590               throw cet::exception(
"CCTM") << 
"Bad index from vertex - cluster association" << icl;
 
  602             prt = (fDebugAlg == 1);
 
  606           else if (fMatchAlgs[
algIndex] == 2) {
 
  607             prt = (fDebugAlg == 2);
 
  623         for (
unsigned short ipf = 0; ipf < 
pfpToTrkID.size(); ++ipf) {
 
  626           if (tID > 
trk.size() + 1) {
 
  627             mf::LogWarning(
"CCTM") << 
"Bad track ID";
 
  632           mf::LogVerbatim(
"CCTM") << 
"PFParticle " << ipf << 
" tID " << tID;
 
  633           for (
unsigned short jpf = 0; jpf < 
pfpToTrkID.size(); ++jpf) {
 
  635             if (
trk[itr].MomID == tID) dtrIndices.push_back(jpf);
 
  636             if (
trk[itr].MomID == tID)
 
  637               mf::LogVerbatim(
"CCTM") << 
" dtr jpf " << jpf << 
" itr " << itr;
 
  639           unsigned short parentIndex = USHRT_MAX;
 
  643             pcol->emplace_back(std::move(pfp));
 
  644             for (
unsigned short ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
  645               if (!
vtx[ivx].Neutrino) 
continue;
 
  650               size_t vStart = vcol->size();
 
  652               vcol->emplace_back(std::move(vertex));
 
  653               size_t vEnd = vcol->size();
 
  656               vtx[ivx].ID = -
vtx[ivx].ID;
 
  665             for (
unsigned short ii = 0; ii < 
pfpToTrkID.size(); ++ii) {
 
  672             mf::LogVerbatim(
"CCTM")
 
  673               << 
"daughters tID " << tID << 
" pdg " << 
trk[tIndex].PDGCode << 
" ipf " << ipf
 
  674               << 
" parentIndex " << parentIndex << 
" dtr size " << dtrIndices.size();
 
  676             pcol->emplace_back(std::move(pfp));
 
  679             size_t tStart = tcol->size();
 
  691             tcol->emplace_back(std::move(
track));
 
  692             size_t tEnd = tcol->size();
 
  696             trk[tIndex].ID = -
trk[tIndex].ID;
 
  699             for (ipl = 0; ipl < 
nplanes; ++ipl)
 
  701                 tmpHits.end(), 
trk[tIndex].TrkHits[ipl].begin(), 
trk[tIndex].TrkHits[ipl].end());
 
  706             unsigned short itj = 0;
 
  707             if (end > 0) itj = 
trk[tIndex].TrjPos.size() - 1;
 
  708             for (
unsigned short ii = 0; ii < 3; ++ii) {
 
  709               sPos[ii] = 
trk[tIndex].TrjPos[itj](ii);
 
  710               sDir[ii] = 
trk[tIndex].TrjDir[itj](ii);
 
  712             size_t sStart = scol->size();
 
  714             scol->emplace_back(std::move(seed));
 
  715             size_t sEnd = scol->size();
 
  720             for (ipl = 0; ipl < 
nplanes; ++ipl)
 
  726             for (
unsigned short ii = 0; ii < 
trk[tIndex].ClsEvtIndices.size(); ++ii) {
 
  727               icl = 
trk[tIndex].ClsEvtIndices[ii];
 
  728               tmpCls.push_back(clusterlist[icl]);
 
  734         for (
unsigned short itr = 0; itr < 
trk.size(); ++itr) {
 
  736           if (
trk[itr].ID < 0) 
continue;
 
  748           tcol->emplace_back(std::move(
track));
 
  750           for (ipl = 0; ipl < 
nplanes; ++ipl)
 
  752               tmpHits.end(), 
trk[itr].TrkHits[ipl].begin(), 
trk[itr].TrkHits[ipl].end());
 
  756         for (
unsigned short ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
  757           if (
vtx[ivx].ID < 0) 
continue;
 
  762           vcol->emplace_back(std::move(vertex));
 
  766         double orphanLen = 0;
 
  767         for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
  768           for (icl = 0; icl < 
cls[ipl].size(); ++icl) {
 
  769             if (
cls[ipl][icl].
Length > 40 && 
cls[ipl][icl].InTrack < 0) {
 
  770               orphanLen += 
cls[ipl][icl].Length;
 
  772               mf::LogVerbatim(
"CCTM")
 
  773                 << 
"Orphan long cluster " << ipl << 
":" << icl << 
":" << 
cls[ipl][icl].Wire[0]
 
  774                 << 
":" << (int)
cls[ipl][icl].Time[0] << 
" length " << 
cls[ipl][icl].
Length;
 
  781         std::cout << 
"Total orphan length " << orphanLen << 
"\n";
 
  788     evt.put(std::move(pcol));
 
  789     evt.put(std::move(ptassn));
 
  790     evt.put(std::move(pcassn));
 
  791     evt.put(std::move(pvassn));
 
  792     evt.put(std::move(psassn));
 
  793     evt.put(std::move(tcol));
 
  794     evt.put(std::move(thassn));
 
  795     evt.put(std::move(scol));
 
  796     evt.put(std::move(vcol));
 
  811     std::vector<std::vector<geo::WireID>> hitWID;
 
  812     std::vector<std::vector<double>> hitX;
 
  813     std::vector<std::vector<double>> hitXErr;
 
  814     TVector3 pos, posErr;
 
  815     std::vector<TVector3> trkDir;
 
  816     std::vector<TVector3> trkDirErr;
 
  819     if (fNVtxTrkHitsFit == 0) 
return;
 
  821     unsigned short indx, indx2, iht, nHitsFit;
 
  823     for (
unsigned short ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
  824       if (!
vtx[ivx].Neutrino) 
continue;
 
  830       unsigned int thePln, theTPC, theCst;
 
  831       for (
unsigned short itk = 0; itk < 
trk.size(); ++itk) {
 
  832         for (
unsigned short end = 0; 
end < 2; ++
end) {
 
  833           if (
trk[itk].VtxIndex[
end] != ivx) 
continue;
 
  834           unsigned short itj = 0;
 
  835           if (
end == 1) itj = 
trk[itk].TrjPos.size() - 1;
 
  838           hitWID.resize(indx + 1);
 
  839           hitX.resize(indx + 1);
 
  840           hitXErr.resize(indx + 1);
 
  841           trkDir.resize(indx + 1);
 
  842           trkDir[indx] = 
trk[itk].TrjDir[itj];
 
  843           for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
  844             if (
trk[itk].TrkHits[ipl].
size() < 2) 
continue;
 
  846             nHitsFit = 
trk[itk].TrkHits[ipl].size();
 
  848             indx2 = hitWID[indx].size();
 
  849             hitWID[indx].resize(indx2 + nHitsFit);
 
  850             hitX[indx].resize(indx2 + nHitsFit);
 
  851             hitXErr[indx].resize(indx2 + nHitsFit);
 
  852             for (
unsigned short ii = 0; ii < nHitsFit; ++ii) {
 
  853               if (
end == 0) { iht = ii; }
 
  855                 iht = 
trk[itk].TrkHits[ipl].size() - ii - 1;
 
  857               hitWID[indx][indx2 + ii] = 
trk[itk].TrkHits[ipl][iht]->WireID();
 
  858               thePln = 
trk[itk].TrkHits[ipl][iht]->WireID().Plane;
 
  859               theTPC = 
trk[itk].TrkHits[ipl][iht]->WireID().TPC;
 
  860               theCst = 
trk[itk].TrkHits[ipl][iht]->WireID().Cryostat;
 
  862                 trk[itk].TrkHits[ipl][iht]->PeakTime(), thePln, theTPC, theCst);
 
  863               hitXErr[indx][indx2 + ii] = fHitFitErrFac * 
trk[itk].TrkHits[ipl][iht]->RMS();
 
  868       if (hitX.size() < 2) {
 
  869         mf::LogVerbatim(
"CCTM") << 
"Not enough hits to fit vtx " << ivx;
 
  876       if (ChiDOF > 3000) 
continue;
 
  882       unsigned short fitTrk = 0;
 
  883       for (
unsigned short itk = 0; itk < 
trk.size(); ++itk) {
 
  884         for (
unsigned short end = 0; 
end < 2; ++
end) {
 
  885           if (
trk[itk].VtxIndex[
end] != ivx) 
continue;
 
  886           unsigned short itj = 0;
 
  887           if (
end == 1) itj = 
trk[itk].TrjPos.size() - 1;
 
  888           trk[itk].TrjDir[itj] = trkDir[fitTrk];
 
  901     unsigned short wire, nwires, indx;
 
  902     float dir, ctime, cx, chgWinLo, chgWinHi;
 
  905     for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
  906       for (
unsigned short icl = 0; icl < 
cls[ipl].size(); ++icl) {
 
  908         nwires = 
cls[ipl][icl].Length / 2;
 
  909         if (nwires < 2) 
continue;
 
  911         if (nwires > 30) nwires = 30;
 
  912         for (
unsigned short end = 0; 
end < 2; ++
end) {
 
  916           for (
unsigned short w = 0; 
w < nwires; ++
w) {
 
  917             wire = 
cls[ipl][icl].Wire[
end] + dir * 
w;
 
  926             for (
unsigned int hit = firhit; 
hit < lashit; ++
hit) {
 
  929                   << 
"FillChgNear bad lashit " << lashit << 
" size " << 
allhits.size() << 
"\n";
 
  932               if (
allhits[
hit]->PeakTime() < chgWinLo) 
continue;
 
  933               if (
allhits[
hit]->PeakTime() > chgWinHi) 
continue;
 
  937           cnear /= (float)(nwires - 1);
 
  938           if (cnear > 
cls[ipl][icl].Charge[
end]) {
 
  942             cls[ipl][icl].ChgNear[
end] = 0;
 
  956     unsigned short ivx, itr, ipl, ii, jtr;
 
  957     unsigned short nus, nds, nuhs, ndhs;
 
  958     float longUSTrk, longDSTrk, 
qual;
 
  962     float tgMuonCut2 = 9;
 
  966       unsigned short VtxIndex;
 
  967       unsigned short nUSTk;
 
  968       unsigned short nDSTk;
 
  969       unsigned short nUSHit;
 
  970       unsigned short nDSHit;
 
  975     std::vector<NuVtx> nuVtxCand;
 
  980     float best = 999, dx, dy, dz, dr;
 
  984     for (ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
  985       vtx[ivx].Neutrino = 
false;
 
  994       for (itr = 0; itr < 
trk.size(); ++itr) {
 
  995         if (
trk[itr].ID < 0) 
continue;
 
  996         if (
trk[itr].PDGCode != 13) 
continue;
 
  997         for (itj = 0; itj < 
trk[itr].TrjPos.size(); ++itj) {
 
  998           dx = 
trk[itr].TrjPos[itj](0) - 
vtx[ivx].
X;
 
  999           dy = 
trk[itr].TrjPos[itj](1) - 
vtx[ivx].Y;
 
 1000           dz = 
trk[itr].TrjPos[itj](2) - 
vtx[ivx].Z;
 
 1001           dr = dx * dx + dy * dy + dz * dz;
 
 1002           if (dr < tgMuonCut2) {
 
 1010       if (skipVtx) 
continue;
 
 1011       for (itr = 0; itr < 
trk.size(); ++itr) {
 
 1012         if (
trk[itr].ID < 0) 
continue;
 
 1013         if (
trk[itr].VtxIndex[0] == ivx) {
 
 1016           if (
trk[itr].
Length > longDSTrk) longDSTrk = 
trk[itr].Length;
 
 1017           for (ipl = 0; ipl < 
nplanes; ++ipl)
 
 1018             ndhs += 
trk[itr].TrkHits[ipl].
size();
 
 1023         if (
trk[itr].VtxIndex[1] == ivx && 
trk[itr].VtxIndex[0] >= 0) {
 
 1027         if (
trk[itr].VtxIndex[1] == ivx && 
trk[itr].VtxIndex[0] < 0) {
 
 1030           if (
trk[itr].
Length > longUSTrk) longUSTrk = 
trk[itr].Length;
 
 1031           for (ipl = 0; ipl < 
nplanes; ++ipl)
 
 1032             nuhs += 
trk[itr].TrkHits[ipl].
size();
 
 1036       if (skipVtx) 
continue;
 
 1037       if (nds == 0) 
continue;
 
 1038       qual = 1 / (float)nds;
 
 1039       qual /= (float)ndhs;
 
 1040       if (nus > 0) qual *= (float)nuhs / (
float)ndhs;
 
 1045       if (nds > 0 && longDSTrk > 5) {
 
 1047         aNuVtx.VtxIndex = ivx;
 
 1050         aNuVtx.nUSHit = nuhs;
 
 1051         aNuVtx.nDSHit = ndhs;
 
 1052         aNuVtx.longUSTrk = longUSTrk;
 
 1053         aNuVtx.longDSTrk = longDSTrk;
 
 1055         nuVtxCand.push_back(aNuVtx);
 
 1065     if (imbest < 0) 
return;
 
 1069     vtx[ivx].Neutrino = 
true;
 
 1077     std::vector<unsigned short> dtrGen;
 
 1078     std::vector<unsigned short> dtrNextGen;
 
 1079     for (itr = 0; itr < 
trk.size(); ++itr) {
 
 1080       if (
trk[itr].ID < 0) 
continue;
 
 1081       if (
trk[itr].VtxIndex[0] == ivx) {
 
 1085         trk[itr].PDGCode = 2212;
 
 1087         dtrGen.push_back(itr);
 
 1089       if (
trk[itr].VtxIndex[1] == ivx) {
 
 1093         trk[itr].PDGCode = 2212;
 
 1096         std::reverse(
trk[itr].TrjPos.begin(), 
trk[itr].TrjPos.end());
 
 1097         for (ii = 0; ii < 
trk[itr].TrjDir.size(); ++ii)
 
 1098           trk[itr].TrjDir[ii] = -
trk[itr].TrjDir[ii];
 
 1102     if (dtrGen.size() == 0) 
return;
 
 1104     unsigned short tmp, indx;
 
 1105     unsigned short nit = 0;
 
 1113       for (ii = 0; ii < dtrGen.size(); ++ii) {
 
 1115         if (
trk[itr].VtxIndex[1] >= 0) {
 
 1117           ivx = 
trk[itr].VtxIndex[1];
 
 1119           for (jtr = 0; jtr < 
trk.size(); ++jtr) {
 
 1120             if (jtr == itr) 
continue;
 
 1121             if (
trk[jtr].VtxIndex[0] == ivx) {
 
 1123               indx = 
trk[itr].DtrID.size();
 
 1124               trk[itr].DtrID.resize(indx + 1);
 
 1125               trk[itr].DtrID[indx] = jtr;
 
 1127               trk[jtr].MomID = 
trk[itr].ID;
 
 1129               trk[jtr].PDGCode = 211;
 
 1130               dtrNextGen.push_back(jtr);
 
 1133             if (
trk[jtr].VtxIndex[1] == ivx) {
 
 1135               indx = 
trk[itr].DtrID.size();
 
 1136               trk[itr].DtrID.resize(indx + 1);
 
 1137               trk[itr].DtrID[indx] = jtr;
 
 1139               trk[jtr].MomID = 
trk[itr].ID;
 
 1141               trk[jtr].PDGCode = 211;
 
 1142               dtrNextGen.push_back(jtr);
 
 1145               std::reverse(
trk[jtr].TrjPos.begin(), 
trk[jtr].TrjPos.end());
 
 1146               for (
unsigned short jj = 0; jj < 
trk[jtr].TrjDir.size(); ++jj)
 
 1147                 trk[jtr].TrjDir[jj] = -
trk[jtr].TrjDir[jj];
 
 1149               tmp = 
trk[jtr].VtxIndex[0];
 
 1150               trk[jtr].VtxIndex[0] = 
trk[jtr].VtxIndex[1];
 
 1151               trk[jtr].VtxIndex[1] = tmp;
 
 1157       if (dtrNextGen.size() == 0) 
break;
 
 1158       dtrGen = dtrNextGen;
 
 1168     unsigned short ipf, itj;
 
 1172     double local[3] = {0., 0., 0.};
 
 1173     double world[3] = {0., 0., 0.};
 
 1184     bool startsIn, endsIn;
 
 1186     for (
unsigned short itk = 0; itk < 
trk.size(); ++itk) {
 
 1188       if (
trk[itk].ID < 0) 
continue;
 
 1193       for (ipf = 0; ipf < 
pfpToTrkID.size(); ++ipf) {
 
 1199       if (skipit) 
continue;
 
 1201       if (
trk[itk].TrjPos[0](0) < XLo || 
trk[itk].TrjPos[0](0) > XHi) startsIn = 
false;
 
 1202       if (
trk[itk].TrjPos[0](1) < YLo || 
trk[itk].TrjPos[0](1) > YHi) startsIn = 
false;
 
 1203       if (
trk[itk].TrjPos[0](2) < ZLo || 
trk[itk].TrjPos[0](2) > ZHi) startsIn = 
false;
 
 1205       if (startsIn) 
continue;
 
 1207       itj = 
trk[itk].TrjPos.size() - 1;
 
 1208       if (
trk[itk].TrjPos[itj](0) < XLo || 
trk[itk].TrjPos[itj](0) > XHi) endsIn = 
false;
 
 1209       if (
trk[itk].TrjPos[itj](1) < YLo || 
trk[itk].TrjPos[itj](1) > YHi) endsIn = 
false;
 
 1210       if (
trk[itk].TrjPos[itj](2) < ZLo || 
trk[itk].TrjPos[itj](2) > ZHi) endsIn = 
false;
 
 1212       if (endsIn) 
continue;
 
 1214       trk[itk].PDGCode = 13;
 
 1218     if (fDeltaRayCut <= 0) 
return;
 
 1220     for (
unsigned short itk = 0; itk < 
trk.size(); ++itk) {
 
 1222       if (
trk[itk].PDGCode != 13) 
continue;
 
 1231                          art::FindManyP<recob::Hit> 
const& fmCluHits)
 
 1234     unsigned short ivx, ii, ipl, icl, jj, jpl, jcl, kk, kpl, kcl;
 
 1235     short idir, iend, jdir, jend, kdir, kend, ioend;
 
 1237     for (ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
 1240       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1242         for (icl = 0; icl < 
clsChain[ipl].size(); ++icl) {
 
 1243           if (
clsChain[ipl][icl].InTrack >= 0) 
continue;
 
 1244           for (iend = 0; iend < 2; ++iend) {
 
 1245             if (
clsChain[ipl][icl].VtxIndex[iend] == 
vtx[ivx].EvtIndex) 
vxCls[ipl].push_back(icl);
 
 1251         mf::LogVerbatim myprt(
"CCTM");
 
 1252         myprt << 
"VtxMatch: Vertex ID " << 
vtx[ivx].EvtIndex << 
"\n";
 
 1253         for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1254           myprt << 
"ipl " << ipl << 
" cls";
 
 1255           for (
unsigned short ii = 0; ii < 
vxCls[ipl].size(); ++ii)
 
 1256             myprt << 
" " << 
vxCls[ipl][ii];
 
 1265       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1266         if (nplanes == 2 && ipl > 0) 
continue;
 
 1267         for (ii = 0; ii < 
vxCls[ipl].size(); ++ii) {
 
 1268           icl = 
vxCls[ipl][ii];
 
 1270           if (
clsChain[ipl][icl].InTrack >= 0) 
continue;
 
 1271           jpl = (ipl + 1) % nplanes;
 
 1272           kpl = (jpl + 1) % nplanes;
 
 1273           for (jj = 0; jj < 
vxCls[jpl].size(); ++jj) {
 
 1274             jcl = 
vxCls[jpl][jj];
 
 1275             if (
clsChain[jpl][jcl].InTrack >= 0) 
continue;
 
 1276             for (iend = 0; iend < 2; ++iend) {
 
 1277               if (
clsChain[ipl][icl].VtxIndex[iend] != 
vtx[ivx].EvtIndex) 
continue;
 
 1279               idir = 
clsChain[ipl][icl].Dir[iend];
 
 1280               for (jend = 0; jend < 2; ++jend) {
 
 1281                 if (
clsChain[jpl][jcl].VtxIndex[jend] != 
vtx[ivx].EvtIndex) 
continue;
 
 1282                 jdir = 
clsChain[jpl][jcl].Dir[jend];
 
 1283                 if (idir != 0 && jdir != 0 && idir != jdir) 
continue;
 
 1288                 match.
Cls[ipl] = icl;
 
 1289                 match.
End[ipl] = iend;
 
 1290                 match.
Cls[jpl] = jcl;
 
 1291                 match.
End[jpl] = jend;
 
 1300                     mf::LogVerbatim(
"CCTM")
 
 1301                       << 
"FillEndMatch2: Err " << match.
Err << 
" oErr " << match.
oErr;
 
 1302                   if (match.
Err + match.
oErr > 100) 
continue;
 
 1307                 match.
Cls[kpl] = -1;
 
 1310                   mf::LogVerbatim(
"CCTM")
 
 1311                     << 
"VtxMatch: check " << ipl << 
":" << icl << 
":" << iend << 
" and " << jpl
 
 1312                     << 
":" << jcl << 
":" << jend << 
" for cluster in kpl " << kpl;
 
 1314                 for (kk = 0; kk < 
vxCls[kpl].size(); ++kk) {
 
 1315                   kcl = 
vxCls[kpl][kk];
 
 1316                   if (
clsChain[kpl][kcl].InTrack >= 0) 
continue;
 
 1317                   for (kend = 0; kend < 2; ++kend) {
 
 1318                     kdir = 
clsChain[kpl][kcl].Dir[kend];
 
 1319                     if (idir != 0 && kdir != 0 && idir != kdir) 
continue;
 
 1320                     if (
clsChain[kpl][kcl].VtxIndex[kend] != 
vtx[ivx].EvtIndex) 
continue;
 
 1323                     match.
Cls[kpl] = kcl;
 
 1324                     match.
End[kpl] = kend;
 
 1329                     if (match.
Chg[kpl] <= 0) 
continue;
 
 1330                     if (match.
Err + match.
oErr > 100) 
continue;
 
 1338                 if (gotkcl) 
continue;
 
 1342                 unsigned short kbend = 0;
 
 1344                   mf::LogVerbatim(
"CCTM") << 
"VtxMatch: look for missed cluster chain in kpl";
 
 1345                 for (kcl = 0; kcl < 
clsChain[kpl].size(); ++kcl) {
 
 1346                   if (
clsChain[kpl][kcl].InTrack >= 0) 
continue;
 
 1347                   for (kend = 0; kend < 2; ++kend) {
 
 1348                     kdir = 
clsChain[kpl][kcl].Dir[kend];
 
 1349                     if (idir != 0 && kdir != 0 && idir != kdir) 
continue;
 
 1350                     if (
clsChain[kpl][kcl].VtxIndex[kend] >= 0) 
continue;
 
 1352                     if (fabs(
clsChain[kpl][kcl].
X[kend] - 
vtx[ivx].
X) > 5) 
continue;
 
 1354                     if (fabs(
clsChain[kpl][kcl].X[1 - kend] - 
clsChain[ipl][icl].X[ioend]) > 50)
 
 1357                     match.
Cls[kpl] = kcl;
 
 1358                     match.
End[kpl] = kend;
 
 1361                     totErr = match.
Err + match.
oErr;
 
 1363                       mf::LogVerbatim myprt(
"CCTM");
 
 1364                       myprt << 
"VtxMatch: Chk missing cluster match ";
 
 1365                       for (
unsigned short ii = 0; ii < 
nplanes; ++ii)
 
 1366                         myprt << 
" " << ii << 
":" << match.
Cls[ii] << 
":" << match.
End[ii];
 
 1367                       myprt << 
" Err " << match.
Err << 
"\n";
 
 1369                     if (totErr > 100) 
continue;
 
 1370                     if (totErr < best) {
 
 1379                   match.
Cls[kpl] = kbst;
 
 1380                   match.
End[kpl] = kbend;
 
 1384                   clsChain[kpl][kbst].VtxIndex[kbend] = ivx;
 
 1386                   vxCls[kpl].push_back(kbst);
 
 1390                   match.
Cls[kpl] = -1;
 
 1402       if (
matcomb.size() == 0) 
continue;
 
 1407     for (ipl = 0; ipl < 3; ++ipl)
 
 1419     unsigned short ipl, icl, 
end, ivx, oend;
 
 1420     float best, dWire, dX;
 
 1423     if (
vtx.size() == 0) 
return;
 
 1425     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1426       for (icl = 0; icl < 
cls[ipl].size(); ++icl) {
 
 1427         for (end = 0; end < 2; ++
end) {
 
 1429           if (
cls[ipl][icl].VtxIndex[end] >= 0) 
continue;
 
 1434           for (ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
 1436             if (
cls[ipl][icl].VtxIndex[oend] == ivx) 
continue;
 
 1446               if (dWire > 30 || dWire < -2) 
continue;
 
 1449               if (dWire < -30 || dWire > 2) 
continue;
 
 1452             dX = fabs(
cls[ipl][icl].
X[end] + 
cls[ipl][icl].Slope[end] * 
fWirePitch * dWire -
 
 1462             cls[ipl][icl].VtxIndex[
end] = ibstvx;
 
 1463             cls[ipl][icl].mVtxIndex[
end] = ibstvx;
 
 1474                                   art::FindManyP<recob::Hit> 
const& fmCluHits)
 
 1476     unsigned short ipl, icl, icl1, icl2;
 
 1477     float dw, dx, dWCut, dw1Max, dw2Max;
 
 1478     float dA, dA2, dACut = 
fMaxDAng, chgAsymCut;
 
 1479     float dXCut, chgasym, mrgErr;
 
 1482     bool gotprt = 
false;
 
 1483     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1485         for (icl1 = 0; icl1 < 
cls[ipl].size() - 1; ++icl1) {
 
 1487           if (
prt) gotprt = 
true;
 
 1489           dw1Max = 0.6 * 
cls[ipl][icl1].Length;
 
 1490           ls1 = (
cls[ipl][icl1].Length > 100 &&
 
 1491                  fabs(
cls[ipl][icl1].Angle[0] - 
cls[ipl][icl1].Angle[1]) < 0.04);
 
 1492           for (icl2 = icl1 + 1; icl2 < 
cls[ipl].size(); ++icl2) {
 
 1493             ls2 = (
cls[ipl][icl2].Length > 100 &&
 
 1494                    fabs(
cls[ipl][icl2].Angle[0] - 
cls[ipl][icl2].Angle[1]) < 0.04);
 
 1495             dw2Max = 0.6 * 
cls[ipl][icl2].Length;
 
 1498             if (dw2Max < dWCut) dWCut = dw2Max;
 
 1500             if (dWCut > 100) dWCut = 100;
 
 1501             if (dWCut < 2) dWCut = 2;
 
 1506               mf::LogVerbatim(
"CCTM")
 
 1507                 << 
"MCC P:C:W icl1 " << ipl << 
":" << icl1 << 
":" << 
cls[ipl][icl1].Wire[1]
 
 1508                 << 
" vtx " << 
cls[ipl][icl1].VtxIndex[1] << 
" ls1 " << ls1 << 
" icl2 " << ipl << 
":" 
 1509                 << icl2 << 
":" << 
cls[ipl][icl2].Wire[0] << 
" vtx " << 
cls[ipl][icl2].VtxIndex[0]
 
 1510                 << 
" ls2 " << ls2 << 
" dWCut " << dWCut;
 
 1511             if (
std::abs(
cls[ipl][icl1].Wire[1] - 
cls[ipl][icl2].Wire[0]) > dWCut) 
continue;
 
 1516             dACut = fMaxDAng * af;
 
 1517             dXCut = fChainMaxdX * 5 * af;
 
 1518             dA = fabs(
cls[ipl][icl1].Angle[1] - 
cls[ipl][icl2].Angle[0]);
 
 1521             dA2 = fabs(
cls[ipl][icl1].Angle[0] - 
cls[ipl][icl2].Angle[1]);
 
 1524               mf::LogVerbatim(
"CCTM")
 
 1525                 << 
" dA " << dA << 
" dA2 " << dA2 << 
" DACut " << dACut << 
" dXCut " << dXCut;
 
 1527             if (dA2 < dA) dA = dA2;
 
 1530             if (dA < fChainVtxAng && 
cls[ipl][icl1].VtxIndex[1] >= 0) {
 
 1533                    cls[ipl][icl2].X[0];
 
 1534               unsigned short ivx = 
cls[ipl][icl1].VtxIndex[1];
 
 1535               if (
vtx[ivx].nClusInPln[ipl] == 2 && fabs(dx) < 1) {
 
 1536                 cls[ipl][icl1].VtxIndex[1] = -2;
 
 1537                 cls[ipl][icl2].VtxIndex[0] = -2;
 
 1538                 vtx[ivx].nClusInPln[ipl] = 0;
 
 1539                 if (
prt) mf::LogVerbatim(
"CCTM") << 
" clobbered vertex " << ivx;
 
 1544             if (
cls[ipl][icl1].VtxIndex[1] >= 0) 
continue;
 
 1545             if (
cls[ipl][icl2].VtxIndex[0] >= 0) 
continue;
 
 1548             if (
cls[ipl][icl2].Wire[0] - 
cls[ipl][icl1].Wire[1] < 3 &&
 
 1550               if (
prt) mf::LogVerbatim(
"CCTM") << 
"Stopping cluster";
 
 1559               dx = 
cls[ipl][icl2].X[0] - 
cls[ipl][icl1].X[1];
 
 1560               float dA3 = 
std::abs(atan(dx / dw) - 
cls[ipl][icl1].Angle[1]);
 
 1561               if (
prt) mf::LogVerbatim(
"CCTM") << 
" dA3 " << dA3;
 
 1562               if (dA3 > dA) dA = dA3;
 
 1566             if (dA > dACut) 
continue;
 
 1569               mf::LogVerbatim(
"CCTM")
 
 1570                 << 
" rough dX " << fabs(
cls[ipl][icl1].
X[1] - 
cls[ipl][icl2].
X[0]) << 
" cut = 20";
 
 1573             if (fabs(
cls[ipl][icl1].X[1] - 
cls[ipl][icl2].X[0]) > 20) 
continue;
 
 1578               if (dA > fChainVtxAng) 
continue;
 
 1581               chgasym = fabs(
cls[ipl][icl1].Charge[1] - 
cls[ipl][icl2].Charge[0]);
 
 1582               chgasym /= 
cls[ipl][icl1].Charge[1] + 
cls[ipl][icl2].Charge[0];
 
 1583               if (
prt) mf::LogVerbatim(
"CCTM") << 
" chgasym " << chgasym << 
" cut " << chgAsymCut;
 
 1584               if (chgasym > chgAsymCut) 
continue;
 
 1590                    cls[ipl][icl2].X[0];
 
 1595                    cls[ipl][icl1].X[1];
 
 1599             if (dA2 < 0.01 && 
abs(dx) > dXCut && dx < -1) {
 
 1600               dx = 
dXClTraj(fmCluHits, ipl, icl1, 1, icl2);
 
 1601               if (
prt) mf::LogVerbatim(
"CCTM") << 
" new dx from dXClTraj " << dx;
 
 1605               mf::LogVerbatim(
"CCTM")
 
 1606                 << 
" X0 " << 
cls[ipl][icl1].X[1] << 
" slp " << 
cls[ipl][icl1].Slope[1] << 
" dw " 
 1607                 << dw << 
" oX " << 
cls[ipl][icl2].X[0] << 
" dx " << dx << 
" cut " << dXCut;
 
 1609             if (fabs(dx) > dXCut) 
continue;
 
 1612             float xerr = dx / dXCut;
 
 1613             float aerr = dA / dACut;
 
 1614             mrgErr = xerr * xerr + aerr * aerr;
 
 1617               mf::LogVerbatim(
"CCTM")
 
 1618                 << 
"icl1 mrgErr " << mrgErr << 
" MergeError " << 
cls[ipl][icl1].MergeError[1]
 
 1619                 << 
" icl2 MergeError " << 
cls[ipl][icl2].MergeError[0];
 
 1622             if (mrgErr > 
cls[ipl][icl1].MergeError[1]) 
continue;
 
 1623             if (mrgErr > 
cls[ipl][icl2].MergeError[0]) 
continue;
 
 1626             if (
cls[ipl][icl1].BrkIndex[1] >= 0) {
 
 1627               unsigned short ocl = 
cls[ipl][icl1].BrkIndex[1];
 
 1628               if (
prt) mf::LogVerbatim(
"CCTM") << 
"clobber old icl1 BrkIndex " << ocl;
 
 1629               if (
cls[ipl][ocl].BrkIndex[0] == icl1) {
 
 1630                 cls[ipl][ocl].BrkIndex[0] = -1;
 
 1633               if (
cls[ipl][ocl].BrkIndex[1] == icl1) {
 
 1634                 cls[ipl][ocl].BrkIndex[1] = -1;
 
 1638             cls[ipl][icl1].BrkIndex[1] = icl2;
 
 1639             cls[ipl][icl1].MergeError[1] = mrgErr;
 
 1642             if (
cls[ipl][icl2].BrkIndex[0] >= 0) {
 
 1643               unsigned short ocl = 
cls[ipl][icl2].BrkIndex[0];
 
 1644               if (
prt) mf::LogVerbatim(
"CCTM") << 
"clobber old icl2 BrkIndex " << ocl;
 
 1645               if (
cls[ipl][ocl].BrkIndex[0] == icl1) {
 
 1646                 cls[ipl][ocl].BrkIndex[0] = -1;
 
 1649               if (
cls[ipl][ocl].BrkIndex[1] == icl1) {
 
 1650                 cls[ipl][ocl].BrkIndex[1] = -1;
 
 1654             cls[ipl][icl2].BrkIndex[0] = icl1;
 
 1655             cls[ipl][icl2].MergeError[0] = mrgErr;
 
 1656             if (
prt) mf::LogVerbatim(
"CCTM") << 
" merge " << icl1 << 
" and " << icl2;
 
 1664         for (icl1 = 0; icl1 < 
cls[ipl].size() - 1; ++icl1) {
 
 1666           for (icl2 = icl1 + 1; icl2 < 
cls[ipl].size(); ++icl2) {
 
 1668             for (
unsigned short end = 0; 
end < 2; ++
end) {
 
 1670               if (
cls[ipl][icl1].BrkIndex[
end] >= 0) 
continue;
 
 1671               if (
cls[ipl][icl2].BrkIndex[
end] >= 0) 
continue;
 
 1673               if (fabs(
cls[ipl][icl1].Angle[
end]) < 1) 
continue;
 
 1675               if (fabs(
cls[ipl][icl2].Angle[end]) < 1) 
continue;
 
 1677                 mf::LogVerbatim(
"CCTM")
 
 1678                   << 
"BrokenC: clusters " << 
cls[ipl][icl1].Wire[
end] << 
":" 
 1679                   << (int)
cls[ipl][icl1].Time[end] << 
" " << 
cls[ipl][icl2].Wire[end] << 
":" 
 1680                   << (
int)
cls[ipl][icl2].Time[
end] << 
" angles " << 
cls[ipl][icl1].Angle[
end] << 
" " 
 1681                   << 
cls[ipl][icl2].Angle[
end] << 
" dWire " 
 1682                   << fabs(
cls[ipl][icl1].Wire[end] - 
cls[ipl][icl2].Wire[end]);
 
 1683               if (fabs(
cls[ipl][icl1].Wire[end] - 
cls[ipl][icl2].Wire[end]) > 5) 
continue;
 
 1686               float dsl = 
cls[ipl][icl2].Slope[
end] - 
cls[ipl][icl1].Slope[
end];
 
 1691               if (
prt) mf::LogVerbatim(
"CCTM") << 
" fvw " << fvw;
 
 1692               if (fabs(
cls[ipl][icl1].Wire[end] - fvw) > 4) 
continue;
 
 1693               if (fabs(
cls[ipl][icl2].Wire[end] - fvw) > 4) 
continue;
 
 1694               cls[ipl][icl1].BrkIndex[
end] = icl2;
 
 1696               cls[ipl][icl1].MergeError[
end] = 1;
 
 1697               cls[ipl][icl2].BrkIndex[
end] = icl1;
 
 1698               cls[ipl][icl2].MergeError[
end] = 1;
 
 1700               dx = fabs(
cls[ipl][icl1].
X[end] - 
cls[ipl][icl2].
X[end]);
 
 1702                 mf::LogVerbatim(
"CCTM")
 
 1703                   << 
"BrokenC: icl1:W " << icl1 << 
":" << 
cls[ipl][icl1].Wire[
end] << 
" icl2:W " 
 1704                   << icl2 << 
":" << 
cls[ipl][icl2].Wire[
end] << 
" end " << end << 
" dx " << dx;
 
 1713       unsigned short end, mom, momBrkEnd, dtrBrkEnd, nit;
 
 1716       std::vector<bool> gotcl(
cls[ipl].
size());
 
 1717       for (icl = 0; icl < 
cls[ipl].size(); ++icl)
 
 1720         mf::LogVerbatim(
"CCTM") << 
"ipl " << ipl << 
" cls.size() " << 
cls[ipl].size() << 
"\n";
 
 1722       std::vector<unsigned short> sCluster;
 
 1723       std::vector<unsigned short> sOrder;
 
 1724       for (icl = 0; icl < 
cls[ipl].size(); ++icl) {
 
 1727         if (gotcl[icl]) 
continue;
 
 1729         if (
cls[ipl][icl].BrkIndex[0] >= 0 && 
cls[ipl][icl].BrkIndex[1] >= 0) 
continue;
 
 1730         for (end = 0; end < 2; ++
end) {
 
 1731           if (
cls[ipl][icl].BrkIndex[end] < 0) 
continue;
 
 1737           sCluster.push_back(mom);
 
 1738           if (momBrkEnd == 1) {
 
 1740             sOrder.push_back(0);
 
 1744             sOrder.push_back(1);
 
 1746           dtr = 
cls[ipl][icl].BrkIndex[
end];
 
 1748           while (dtr >= 0 && dtr < (
short)
cls[ipl].
size() && nit < 
cls[ipl].
size()) {
 
 1750             for (dtrBrkEnd = 0; dtrBrkEnd < 2; ++dtrBrkEnd)
 
 1751               if (
cls[ipl][dtr].BrkIndex[dtrBrkEnd] == mom) 
break;
 
 1752             if (dtrBrkEnd == 2) {
 
 1758               sCluster.push_back(dtr);
 
 1759               sOrder.push_back(dtrBrkEnd);
 
 1766             momBrkEnd = 1 - dtrBrkEnd;
 
 1768             dtr = 
cls[ipl][mom].BrkIndex[momBrkEnd];
 
 1770           if (dtrBrkEnd == 2) 
continue;
 
 1775           sCluster.push_back(icl);
 
 1776           sOrder.push_back(0);
 
 1779         if (sCluster.size() == 0) {
 
 1780           mf::LogError(
"CCTM") << 
"MakeClusterChains error in plane " << ipl << 
" cluster " << icl;
 
 1786         unsigned short jcl = sCluster[0];
 
 1788         unsigned short oend;
 
 1789         for (end = 0; end < 2; ++
end) {
 
 1791           if (sOrder[0] > 0) oend = 1 - 
end;
 
 1794           ccp.
X[
end] = 
cls[ipl][jcl].X[oend];
 
 1806         for (
unsigned short ii = 1; ii < sCluster.size(); ++ii) {
 
 1811           if (end > 1) 
std::cout << 
"oops2 MCC\n";
 
 1814           ccp.
Wire[1] = 
cls[ipl][jcl].Wire[oend];
 
 1815           ccp.
Time[1] = 
cls[ipl][jcl].Time[oend];
 
 1816           ccp.
X[1] = 
cls[ipl][jcl].X[oend];
 
 1817           ccp.
Slope[1] = 
cls[ipl][jcl].Slope[oend];
 
 1818           ccp.
Angle[1] = 
cls[ipl][jcl].Angle[oend];
 
 1819           ccp.
Dir[1] = 
cls[ipl][jcl].Dir[oend];
 
 1821           ccp.
ChgNear[1] = 
cls[ipl][jcl].ChgNear[oend];
 
 1842       unsigned short brkCls;
 
 1844       for (
unsigned short ccl = 0; ccl < 
clsChain[ipl].size(); ++ccl) {
 
 1845         for (
unsigned short end = 0; end < 2; ++
end) {
 
 1846           if (
clsChain[ipl][ccl].mBrkIndex[end] < 0) 
continue;
 
 1850           for (
unsigned short ccl2 = 0; ccl2 < 
clsChain[ipl].size(); ++ccl2) {
 
 1851             if (ccl2 == ccl) 
continue;
 
 1852             if (std::find(
clsChain[ipl][ccl2].ClsIndex.begin(),
 
 1853                           clsChain[ipl][ccl2].ClsIndex.end(),
 
 1854                           brkCls) == 
clsChain[ipl][ccl2].ClsIndex.end())
 
 1862             mf::LogError(
"CCTM") << 
"MCC: Cluster chain " << ccl << 
" end " << end
 
 1863                                  << 
" Failed to find brkCls " << brkCls << 
" in plane " << ipl;
 
 1878                          unsigned short icl1,
 
 1879                          unsigned short end1,
 
 1880                          unsigned short icl2)
 
 1883     float dw, dx, best = 999;
 
 1884     std::vector<art::Ptr<recob::Hit>> clusterhits = fmCluHits.at(
cls[ipl][icl1].EvtIndex);
 
 1885     for (
unsigned short hit = 0; 
hit < clusterhits.size(); ++
hit) {
 
 1886       dw = clusterhits[
hit]->WireID().Wire - 
cls[ipl][icl1].Wire[end1];
 
 1887       dx = fabs(
cls[ipl][icl1].Time[end1] + dw * 
fWirePitch * 
cls[ipl][icl1].Slope[end1] -
 
 1888                 clusterhits[
hit]->PeakTime());
 
 1889       if (dx < best) best = dx;
 
 1890       if (dx < 0.01) 
break;
 
 1898                            art::FindManyP<recob::Hit> 
const& fmCluHits,
 
 1899                            unsigned short imat,
 
 1900                            unsigned short procCode)
 
 1906     if (imat > 
matcomb.size() - 1) {
 
 1907       mf::LogError(
"CCTM") << 
"Bad imat in StoreTrack";
 
 1912     unsigned short nhitinpl = 0;
 
 1913     for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl)
 
 1916       mf::LogError(
"CCTM") << 
"StoreTrack: Not enough hits in each plane\n";
 
 1920       mf::LogVerbatim(
"CCTM") << 
"In StoreTrack: matcomb " << imat << 
" cluster chains " 
 1925     std::array<std::vector<geo::WireID>, 3> trkWID;
 
 1926     std::array<std::vector<double>, 3> trkX;
 
 1927     std::array<std::vector<double>, 3> trkXErr;
 
 1930     std::vector<TVector3> trkPos;
 
 1931     std::vector<TVector3> trkDir;
 
 1933     newtrk.
ID = 
trk.size() + 1;
 
 1934     newtrk.
Proc = procCode;
 
 1943     newtrk.
EndInTPC = {{
false, 
false}};
 
 1944     newtrk.
GoodEnd = {{
false, 
false}};
 
 1948     unsigned short ipl, icl, iht;
 
 1951       mf::LogVerbatim(
"CCTM") << 
"CCTM: Make traj for track " << newtrk.
ID << 
" procCode " 
 1952                               << procCode << 
" nhits in planes " << 
trkHits[0].size() << 
" " 
 1956       trkWID[2].resize(0);
 
 1958       trkXErr[2].resize(0);
 
 1960     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 1964       for (iht = 0; iht < 
trkHits[ipl].size(); ++iht) {
 
 1965         trkWID[ipl][iht] = 
trkHits[ipl][iht]->WireID();
 
 1968           fHitFitErrFac * 
trkHits[ipl][iht]->RMS() * 
trkHits[ipl][iht]->Multiplicity();
 
 1972     if (trkPos.size() < 2) {
 
 1973       mf::LogError(
"CCTM") << 
"StoreTrack: No trajectory points on failed track " << newtrk.
ID 
 1974                            << 
" in StoreTrack: matcomb " << imat << 
" cluster chains " 
 1986     if (
prt) mf::LogVerbatim(
"CCTM") << 
" number of traj points " << trkPos.size();
 
 1990     unsigned short end, nClose, indx, jndx;
 
 1992     for (end = 0; end < 2; ++
end) {
 
 1994       for (ipl = 0; ipl < nplanes - 1; ++ipl) {
 
 1995         if (trkX[ipl].
size() == 0) 
continue;
 
 1996         for (
unsigned short jpl = ipl + 1; jpl < 
nplanes; ++jpl) {
 
 1997           if (trkX[jpl].
size() == 0) 
continue;
 
 2003             indx = trkXErr[ipl].size() - 1;
 
 2004             jndx = trkXErr[jpl].size() - 1;
 
 2006           xErr = 3 * (trkXErr[ipl][indx] + trkXErr[jpl][jndx]);
 
 2007           if (
std::abs(trkX[ipl][indx] - trkX[jpl][jndx]) < xErr) ++nClose;
 
 2010       if (nClose == nplanes) newtrk.
GoodEnd[
end] = 
true;
 
 2014     unsigned short ivx, itj, ccl;
 
 2015     float dx, dy, dz, dr0, dr1;
 
 2016     unsigned short attachEnd;
 
 2017     for (end = 0; end < 2; ++
end) {
 
 2020       if (end == 1 && 
matcomb[imat].oVtx >= 0) ivx = 
matcomb[imat].oVtx;
 
 2021       if (ivx == USHRT_MAX) 
continue;
 
 2024       dx = 
vtx[ivx].X - newtrk.
TrjPos[itj](0);
 
 2025       dy = 
vtx[ivx].Y - newtrk.
TrjPos[itj](1);
 
 2026       dz = 
vtx[ivx].Z - newtrk.
TrjPos[itj](2);
 
 2027       dr0 = dx * dx + dy * dy + dz * dz;
 
 2028       itj = newtrk.
TrjPos.size() - 1;
 
 2029       dx = 
vtx[ivx].X - newtrk.
TrjPos[itj](0);
 
 2030       dy = 
vtx[ivx].Y - newtrk.
TrjPos[itj](1);
 
 2031       dz = 
vtx[ivx].Z - newtrk.
TrjPos[itj](2);
 
 2032       dr1 = dx * dx + dy * dy + dz * dz;
 
 2038         if (dr0 > 5) 
return;
 
 2042         if (dr1 > 5) 
return;
 
 2052         newtrk.
TrjDir[0] = dir.Unit();
 
 2056         newtrk.
TrjDir[itj] = dir.Unit();
 
 2061       mf::LogError(
"CCTM")
 
 2062         << 
"StoreTrack: Trying to attach a vertex to both ends of a track. imat = " << imat;
 
 2070     for (
unsigned short itj = 1; itj < newtrk.
TrjPos.size(); ++itj) {
 
 2074       norm = sqrt(X * X + Y * Y + Z * Z);
 
 2080     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2081       if (
matcomb[imat].Cls[ipl] < 0) 
continue;
 
 2085       for (
unsigned short icc = 0; icc < 
clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
 
 2086         icl = 
clsChain[ipl][ccl].ClsIndex[icc];
 
 2088         cls[ipl][icl].InTrack = newtrk.
ID;
 
 2089         if (
cls[ipl][icl].EvtIndex > fmCluHits.size() - 1) {
 
 2090           std::cout << 
"ooops2 store track EvtIndex " << 
cls[ipl][icl].EvtIndex << 
" size " 
 2091                     << fmCluHits.size() << 
" icl " << icl << 
"\n";
 
 2098     if (
prt) mf::LogVerbatim(
"CCTM") << 
" track ID " << newtrk.
ID << 
" stored in StoreTrack";
 
 2100     trk.push_back(newtrk);
 
 2106                          art::FindManyP<recob::Hit> 
const& fmCluHits)
 
 2111     float kSlp, kAng, 
kX, kWir, okWir;
 
 2112     short idir, ioend, jdir, joend, kdir;
 
 2115     float tpcSizeY = 
geom->DetHalfWidth();
 
 2116     float tpcSizeZ = 
geom->DetLength();
 
 2127     std::array<float, 3> mchg;
 
 2129     for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2130       for (
unsigned short icl = 0; icl < 
clsChain[ipl].size(); ++icl) {
 
 2131         if (
clsChain[ipl][icl].InTrack >= 0) 
continue;
 
 2134         unsigned short jpl = (ipl + 1) % nplanes;
 
 2135         unsigned short kpl = (jpl + 1) % nplanes;
 
 2136         for (
unsigned short jcl = 0; jcl < 
clsChain[jpl].size(); ++jcl) {
 
 2137           if (
clsChain[jpl][jcl].InTrack >= 0) 
continue;
 
 2139           if (
clsChain[jpl][jcl].
Length < fMatchMinLen[algIndex]) 
continue;
 
 2141           mchg[0] = 
clsChain[ipl][icl].TotChg;
 
 2142           mchg[1] = 
clsChain[jpl][jcl].TotChg;
 
 2144           if (fChgAsymFactor[algIndex] > 0 && 
ChargeAsym(mchg) > 0.5) 
continue;
 
 2145           for (
unsigned short iend = 0; iend < 2; ++iend) {
 
 2146             idir = 
clsChain[ipl][icl].Dir[iend];
 
 2147             for (
unsigned short jend = 0; jend < 2; ++jend) {
 
 2148               jdir = 
clsChain[jpl][jcl].Dir[jend];
 
 2149               if (idir != 0 && jdir != 0 && idir != jdir) 
continue;
 
 2155               kSlp = 
geom->ThirdPlaneSlope(ipl,
 
 2163               geom->IntersectionPoint((
unsigned int)(0.5 + 
clsChain[ipl][icl].Wire[iend]),
 
 2164                                       (
unsigned int)(0.5 + 
clsChain[jpl][jcl].Wire[jend]),
 
 2171               if (yp > tpcSizeY || yp < -tpcSizeY) 
continue;
 
 2172               if (zp < 0 || zp > tpcSizeZ) 
continue;
 
 2176               geom->IntersectionPoint((
unsigned int)(0.5 + 
clsChain[ipl][icl].Wire[ioend]),
 
 2177                                       (
unsigned int)(0.5 + 
clsChain[jpl][jcl].Wire[joend]),
 
 2184               if (yp > tpcSizeY || yp < -tpcSizeY) 
continue;
 
 2185               if (zp < 0 || zp > tpcSizeZ) 
continue;
 
 2188                 mf::LogVerbatim(
"CCTM")
 
 2189                   << 
"PlnMatch: chk i " << ipl << 
":" << icl << 
":" << iend << 
" idir " << idir
 
 2190                   << 
" X " << 
clsChain[ipl][icl].X[iend] << 
" j " << jpl << 
":" << jcl << 
":" 
 2191                   << jend << 
" jdir " << jdir << 
" X " << 
clsChain[jpl][jcl].X[jend];
 
 2194                 mf::LogVerbatim(
"CCTM")
 
 2195                   << 
"PlnMatch: chk j " << ipl << 
":" << icl << 
":" << iend << 
" " << jpl << 
":" 
 2196                   << jcl << 
":" << jend << 
" iSlp " << std::setprecision(2)
 
 2197                   << 
clsChain[ipl][icl].Slope[iend] << 
" jSlp " << std::setprecision(2)
 
 2198                   << 
clsChain[jpl][jcl].Slope[jend] << 
" kWir " << (int)kWir << 
" okWir " 
 2199                   << (
int)okWir << 
" kSlp " << std::setprecision(2) << kSlp << 
" kAng " 
 2200                   << std::setprecision(2) << kAng << 
" kX " << std::setprecision(1) << 
kX;
 
 2204               ignoreSign = (fabs(kSlp) > 1.5);
 
 2205               if (ignoreSign) kAng = fabs(kAng);
 
 2207               bool gotkcl = 
false;
 
 2208               for (
unsigned short kcl = 0; kcl < 
clsChain[kpl].size(); ++kcl) {
 
 2209                 if (
clsChain[kpl][kcl].InTrack >= 0) 
continue;
 
 2211                 mchg[0] = 
clsChain[ipl][icl].TotChg;
 
 2212                 mchg[1] = 
clsChain[jpl][jcl].TotChg;
 
 2213                 mchg[2] = 
clsChain[kpl][kcl].TotChg;
 
 2214                 if (fChgAsymFactor[algIndex] > 0 && 
ChargeAsym(mchg) > 0.5) 
continue;
 
 2215                 for (
unsigned short kend = 0; kend < 2; ++kend) {
 
 2216                   kdir = 
clsChain[kpl][kcl].Dir[kend];
 
 2217                   if (idir != 0 && kdir != 0 && idir != kdir) 
continue;
 
 2219                     mf::LogVerbatim(
"CCTM")
 
 2220                       << 
" kcl " << kcl << 
" kend " << kend << 
" dx " 
 2225                     mf::LogVerbatim(
"CCTM")
 
 2226                       << 
" kcl " << kcl << 
" kend " << kend << 
" dw " 
 2227                       << (
clsChain[kpl][kcl].Wire[kend] - kWir) << 
" ignoreSign " << ignoreSign;
 
 2228                   if (fabs(
clsChain[kpl][kcl].Wire[kend] - kWir) > dwcut) 
continue;
 
 2229                   if (
prt) mf::LogVerbatim(
"CCTM") << 
" chk k " << kpl << 
":" << kcl << 
":" << kend;
 
 2231                   match.
Cls[ipl] = icl;
 
 2232                   match.
End[ipl] = iend;
 
 2233                   match.
Cls[jpl] = jcl;
 
 2234                   match.
End[jpl] = jend;
 
 2235                   match.
Cls[kpl] = kcl;
 
 2236                   match.
End[kpl] = kend;
 
 2246                     mf::LogVerbatim(
"CCTM") << 
" PlnMatch: match k " << kpl << 
":" << match.
Cls[kpl]
 
 2247                                             << 
":" << match.
End[kpl] << 
" oChg " << match.
Chg[kpl]
 
 2248                                             << 
" mErr " << match.
Err << 
" oErr " << match.
oErr;
 
 2249                   if (match.
Chg[kpl] == 0) 
continue;
 
 2250                   if (match.
Err > 10 || match.
oErr > 10) 
continue;
 
 2251                   if (
prt) mf::LogVerbatim(
"CCTM") << 
" dup? ";
 
 2257               if (
prt) mf::LogVerbatim(
"CCTM") << 
" PlnMatch: gotkcl " << gotkcl;
 
 2261                 match.
Cls[ipl] = icl;
 
 2262                 match.
End[ipl] = iend;
 
 2263                 match.
Cls[jpl] = jcl;
 
 2264                 match.
End[jpl] = jend;
 
 2265                 match.
Cls[kpl] = -1;
 
 2276                   mf::LogVerbatim(
"CCTM")
 
 2277                     << 
" Tried 2-plane match" 
 2278                     << 
" k " << kpl << 
":" << match.
Cls[kpl] << 
":" << match.
End[kpl] << 
" Chg " 
 2279                     << match.
Chg[kpl] << 
" Err " << match.
Err << 
" match.oErr " << match.
oErr;
 
 2280                 if (match.
Chg[kpl] <= 0) 
continue;
 
 2281                 if (match.
Err > 10 || match.
oErr > 10) 
continue;
 
 2290     if (
matcomb.size() == 0) 
return;
 
 2299     unsigned short nMatCl, nMiss;
 
 2300     float toterr = match.
Err + match.
oErr;
 
 2301     for (
unsigned int imat = 0; imat < 
matcomb.size(); ++imat) {
 
 2328       for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2329         if (match.
Cls[ipl] >= 0) {
 
 2330           if (match.
Cls[ipl] == 
matcomb[imat].Cls[ipl] &&
 
 2338       if (nMatCl == 2 && nMiss == 1) 
return true;
 
 2346                             art::FindManyP<recob::Hit> 
const& fmCluHits,
 
 2347                             unsigned short procCode)
 
 2352     std::vector<CluLen> materr;
 
 2353     unsigned int ii, im;
 
 2355     if (
matcomb.size() == 0) 
return;
 
 2358     for (ii = 0; ii < 
matcomb.size(); ++ii) {
 
 2361       materr.push_back(merr);
 
 2363     std::sort(materr.begin(), materr.end(), 
lessThan);
 
 2366       mf::LogVerbatim myprt(
"CCTM");
 
 2367       myprt << 
"SortMatches\n";
 
 2368       myprt << 
"   ii    im  Vx   Err     dW     dA     dX  oVx   oErr    odW   odA    odX   Asym  " 
 2370       for (ii = 0; ii < materr.size(); ++ii) {
 
 2371         im = materr[ii].index;
 
 2376         myprt << std::fixed << 
std::right << std::setw(5) << ii << std::setw(5) << im
 
 2377               << std::setw(4) << 
matcomb[im].Vtx << std::setw(7) << std::setprecision(2)
 
 2378               << 
matcomb[im].Err << std::setw(7) << std::setprecision(1) << 
matcomb[im].dWir
 
 2379               << std::setw(7) << std::setprecision(2) << 
matcomb[im].dAng << std::setw(7)
 
 2380               << std::setprecision(2) << 
matcomb[im].dX << std::setw(4) << 
matcomb[im].oVtx
 
 2381               << std::setw(7) << std::setprecision(2) << 
matcomb[im].oErr << std::setw(7)
 
 2382               << std::setprecision(1) << 
matcomb[im].odWir << std::setw(7) << std::setprecision(2)
 
 2383               << 
matcomb[im].odAng << std::setw(7) << std::setprecision(2) << 
matcomb[im].odX
 
 2384               << std::setw(7) << std::setprecision(3) << asym << 
" 0:" << 
matcomb[im].Cls[0] << 
":" 
 2392     std::array<std::vector<bool>, 3> pclUsed;
 
 2394     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2399     unsigned short matcombTotCl = 0;
 
 2400     float matcombTotLen = 0;
 
 2402     for (ii = 0; ii < 
matcomb.size(); ++ii) {
 
 2403       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2404         if (
matcomb[ii].Cls[ipl] < 0) 
continue;
 
 2407         matcombTotLen += 
clsChain[ipl][icl].Length;
 
 2412       mf::LogVerbatim(
"CCTM") << 
"Number of clusters to match " << matcombTotCl << 
" total length " 
 2415     if (matcombTotLen <= 0) {
 
 2416       mf::LogError(
"CCTM") << 
"SortMatches: bad matcomb total length " << matcombTotLen;
 
 2421     std::vector<unsigned short> matIndex;
 
 2423     std::vector<unsigned short> bestMatIndex;
 
 2424     float totLen, totErr, bestTotErr = 9999;
 
 2426     unsigned short jj, jm, nused, jcl;
 
 2430     for (ii = 0; ii < materr.size(); ++ii) {
 
 2431       im = materr[ii].index;
 
 2434       if (
matcomb[im].Err > bestTotErr) 
continue;
 
 2437       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2441         if (
matcomb[im].Cls[ipl] < 0) 
continue;
 
 2443         pclUsed[ipl][icl] = 
true;
 
 2444         totLen += 
clsChain[ipl][icl].Length;
 
 2449       matIndex.push_back(im);
 
 2451       for (jj = 0; jj < materr.size(); ++jj) {
 
 2452         if (jj == ii) 
continue;
 
 2453         jm = materr[jj].index;
 
 2455         if (
matcomb[jm].Err > bestTotErr) 
continue;
 
 2458         for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2459           if (
matcomb[jm].Cls[ipl] < 0) 
continue;
 
 2461           if (pclUsed[ipl][jcl]) ++nused;
 
 2463           if (nused > 0) 
break;
 
 2464           totLen += 
clsChain[ipl][jcl].Length;
 
 2467         if (nused != 0) 
continue;
 
 2470         matIndex.push_back(jm);
 
 2472         for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2473           if (
matcomb[jm].Cls[ipl] < 0) 
continue;
 
 2475           pclUsed[ipl][jcl] = 
true;
 
 2478       if (totLen == 0) 
continue;
 
 2480       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2481         for (
unsigned short indx = 0; indx < pclUsed[ipl].size(); ++indx)
 
 2482           if (pclUsed[ipl][indx]) ++nused;
 
 2484       if (totLen > matcombTotLen) 
std::cout << 
"Oops " << totLen << 
" " << matcombTotLen << 
"\n";
 
 2486       fracLen = totLen / matcombTotLen;
 
 2489         mf::LogVerbatim myprt(
"CCTM");
 
 2490         myprt << 
"match " << im << 
" totErr " << totErr << 
" nused " << nused << 
" fracLen " 
 2491               << fracLen << 
" totLen " << totLen << 
" mat: ";
 
 2492         for (
unsigned short indx = 0; indx < matIndex.size(); ++indx)
 
 2493           myprt << 
" " << matIndex[indx];
 
 2496       if (totErr < bestTotErr) {
 
 2497         bestTotErr = totErr;
 
 2498         bestMatIndex = matIndex;
 
 2499         if (nused == matcombTotCl) 
break;
 
 2501           mf::LogVerbatim myprt(
"CCTM");
 
 2502           myprt << 
"bestTotErr " << bestTotErr << 
" nused " << nused << 
" matcombTotCl " 
 2503                 << matcombTotCl << 
" mat: ";
 
 2504           for (
unsigned short indx = 0; indx < bestMatIndex.size(); ++indx)
 
 2505             myprt << 
" " << bestMatIndex[indx];
 
 2508         if (fracLen > 0.999) 
break;
 
 2512     if (bestTotErr > 9000) 
return;
 
 2514     for (ii = 0; ii < bestMatIndex.size(); ++ii) {
 
 2515       im = bestMatIndex[ii];
 
 2519       StoreTrack(detProp, fmCluHits, im, procCode);
 
 2538     unsigned short ipl = 0;
 
 2539     unsigned short jpl = 1;
 
 2541     if (match.
Cls[0] < 0 || match.
Cls[1] < 0) 
return;
 
 2543     unsigned short icl = match.
Cls[ipl];
 
 2544     unsigned short iend = match.
End[ipl];
 
 2547     float miX = 
clsChain[ipl][icl].X[iend];
 
 2549     unsigned short oiend = 1 - iend;
 
 2550     float oiX = 
clsChain[ipl][icl].X[oiend];
 
 2552     unsigned short jcl = match.
Cls[jpl];
 
 2553     unsigned short jend = match.
End[jpl];
 
 2556     float mjX = 
clsChain[jpl][jcl].X[jend];
 
 2558     unsigned short ojend = 1 - jend;
 
 2559     float ojX = 
clsChain[jpl][jcl].X[ojend];
 
 2563     if (
clsChain[ipl][icl].VtxIndex[iend] >= 0 &&
 
 2572     if (
clsChain[ipl][icl].VtxIndex[oiend] >= 0 &&
 
 2573         clsChain[ipl][icl].VtxIndex[oiend] == 
clsChain[jpl][jcl].VtxIndex[ojend]) {
 
 2581     if (fChgAsymFactor[
algIndex] > 0) {
 
 2582       chgAsym = fabs(match.
Chg[ipl] - match.
Chg[jpl]) / (match.
Chg[ipl] + match.
Chg[jpl]);
 
 2583       if (chgAsym > 0.5) 
return;
 
 2584       chgAsym = 1 + fChgAsymFactor[
algIndex] * chgAsym;
 
 2588     float maxSlp = fabs(
clsChain[ipl][icl].Slope[iend]);
 
 2589     if (fabs(
clsChain[jpl][jcl].Slope[jend]) > maxSlp)
 
 2590       maxSlp = fabs(
clsChain[jpl][jcl].Slope[jend]);
 
 2591     float sigmaX = fXMatchErr[
algIndex] + std::max(maxSlp, (
float)20);
 
 2592     match.
dX = fabs(miX - mjX);
 
 2593     match.
Err = chgAsym * match.
dX / sigmaX;
 
 2596     maxSlp = fabs(
clsChain[ipl][icl].Slope[oiend]);
 
 2597     if (fabs(
clsChain[jpl][jcl].Slope[ojend]) > maxSlp)
 
 2598       maxSlp = fabs(
clsChain[jpl][jcl].Slope[ojend]);
 
 2599     sigmaX = fXMatchErr[
algIndex] + std::max(maxSlp, (
float)20);
 
 2600     match.
odX = fabs(oiX - ojX);
 
 2601     match.
oErr = chgAsym * match.
odX / sigmaX;
 
 2604       mf::LogVerbatim(
"CCTM") << 
"FEM2: m " << ipl << 
":" << icl << 
":" << iend << 
" miX " << miX
 
 2605                               << 
" - " << jpl << 
":" << jcl << 
":" << jend << 
" mjX " << mjX
 
 2606                               << 
" match.dX " << match.
dX << 
" match.Err " << match.
Err 
 2607                               << 
" chgAsym " << chgAsym << 
" o " 
 2608                               << 
" oiX " << oiX << 
" ojX " << ojX << 
" match.odX " << match.
odX 
 2609                               << 
" match.oErr " << match.
oErr << 
"\n";
 
 2629     std::array<short, 3> mVtx;
 
 2630     std::array<short, 3> oVtx;
 
 2631     std::array<float, 3> oWir;
 
 2632     std::array<float, 3> oSlp;
 
 2633     std::array<float, 3> oAng;
 
 2634     std::array<float, 3> oX;
 
 2636     std::array<float, 3> mChg;
 
 2638     unsigned short ii, ipl, iend, jpl, jend, kpl, kend, oend;
 
 2639     short icl, jcl, kcl;
 
 2641     for (ipl = 0; ipl < 3; ++ipl) {
 
 2663       mf::LogVerbatim myprt(
"CCTM");
 
 2665       for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2666         myprt << 
" " << ipl << 
":" << match.
Cls[ipl] << 
":" << match.
End[ipl];
 
 2670     short missingPlane = -1;
 
 2671     unsigned short nClInPln = 0;
 
 2674     unsigned short novxmat = 0;
 
 2676     unsigned short nvxmat = 0;
 
 2677     unsigned short nShortCl = 0;
 
 2679     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 2680       if (match.
Cls[ipl] < 0) {
 
 2685       icl = match.
Cls[ipl];
 
 2687       mChg[ipl] = 
clsChain[ipl][icl].TotChg;
 
 2688       iend = match.
End[ipl];
 
 2689       mVtx[ipl] = 
clsChain[ipl][icl].VtxIndex[iend];
 
 2691       if (mVtx[ipl] >= 0) {
 
 2692         if (aVtx < 0) aVtx = mVtx[ipl];
 
 2693         if (mVtx[ipl] == aVtx) ++nvxmat;
 
 2696         mf::LogVerbatim(
"CCTM") << 
"FEM: m " << ipl << 
":" << icl << 
":" << iend << 
" Vtx " 
 2697                                 << mVtx[ipl] << 
"  Wir " << 
clsChain[ipl][icl].Wire[iend]
 
 2698                                 << std::fixed << std::setprecision(3) << 
" Slp " 
 2699                                 << 
clsChain[ipl][icl].Slope[iend] << std::fixed
 
 2700                                 << std::setprecision(1) << 
" X " << 
clsChain[ipl][icl].X[iend];
 
 2703       oWir[ipl] = 
clsChain[ipl][icl].Wire[oend];
 
 2704       oAng[ipl] = 
clsChain[ipl][icl].Angle[oend];
 
 2705       oSlp[ipl] = 
clsChain[ipl][icl].Slope[oend];
 
 2706       oX[ipl] = 
clsChain[ipl][icl].X[oend];
 
 2707       oVtx[ipl] = 
clsChain[ipl][icl].VtxIndex[oend];
 
 2708       if (oVtx[ipl] >= 0) {
 
 2709         if (aoVtx < 0) aoVtx = oVtx[ipl];
 
 2710         if (oVtx[ipl] == aoVtx) ++novxmat;
 
 2714         mf::LogVerbatim(
"CCTM") << 
"     o " << ipl << 
":" << icl << 
":" << oend << 
" oVtx " 
 2715                                 << oVtx[ipl] << 
" oWir " << oWir[ipl] << std::fixed
 
 2716                                 << std::setprecision(3) << 
" oSlp " << oSlp[ipl] << std::fixed
 
 2717                                 << std::setprecision(1) << 
" oX " << oX[ipl] << 
" Chg " 
 2722     bool isShort = (nShortCl > 1);
 
 2725       mf::LogWarning(
"CCTM") << 
"Not enough matched planes supplied";
 
 2730       mf::LogVerbatim(
"CCTM") << 
"FEM: Vtx m " << aVtx << 
" count " << nvxmat << 
" o " << aoVtx
 
 2731                               << 
" count " << novxmat << 
" missingPlane " << missingPlane
 
 2732                               << 
" nClInPln " << nClInPln;
 
 2735     if (nvxmat == 3 && novxmat == 3) {
 
 2746     float ovxFactor = 1;
 
 2747     if (nClInPln == 3) {
 
 2780     float kSlp, okSlp, kAng, okAng, okX, 
kX, kTim, okTim;
 
 2782     if (nClInPln == 3) {
 
 2794       else if (kpl == 1) {
 
 2803     iend = match.
End[ipl];
 
 2804     jend = match.
End[jpl];
 
 2805     icl = match.
Cls[ipl];
 
 2806     jcl = match.
Cls[jpl];
 
 2808       kcl = match.
Cls[kpl];
 
 2809       kend = match.
End[kpl];
 
 2813     okSlp = 
geom->ThirdPlaneSlope(ipl, oSlp[ipl], jpl, oSlp[jpl], 
tpc, 
cstat);
 
 2814     okAng = atan(okSlp);
 
 2817     bool ignoreSign = (fabs(okSlp) > 10);
 
 2818     if (ignoreSign) okAng = fabs(okAng);
 
 2819     if (match.
oVtx >= 0) {
 
 2826       geom->IntersectionPoint(oWir[ipl], oWir[jpl], ipl, jpl, 
cstat, 
tpc, ypos, zpos);
 
 2827       okWir = (0.5 + 
geom->WireCoordinate(ypos, zpos, kpl, 
tpc, 
cstat));
 
 2828       okX = 0.5 * (oX[ipl] + oX[jpl]);
 
 2832       mf::LogVerbatim(
"CCTM") << 
"FEM: oEnd" 
 2833                               << 
" kpl " << kpl << 
" okSlp " << okSlp << 
" okAng " << okAng
 
 2834                               << 
" okWir " << (int)okWir << 
" okX " << okX;
 
 2838     kSlp = 
geom->ThirdPlaneSlope(
 
 2841     if (ignoreSign) kAng = fabs(kAng);
 
 2842     if (match.
Vtx >= 0) {
 
 2843       if (
vtx.size() == 0 || (
unsigned int)match.
Vtx > 
vtx.size() - 1) {
 
 2844         mf::LogError(
"CCTM") << 
"FEM: Bad match.Vtx " << match.
Vtx << 
" vtx size " << 
vtx.size();
 
 2861       kWir = (0.5 + 
geom->WireCoordinate(ypos, zpos, kpl, 
tpc, 
cstat));
 
 2866       mf::LogVerbatim(
"CCTM") << 
"FEM: mEnd" 
 2867                               << 
" kpl " << kpl << 
" kSlp " << kSlp << 
" kAng " << kAng << 
" kX " 
 2874       match.
Cls[kpl] = kcl;
 
 2875       match.
End[kpl] = kend;
 
 2877       mChg[kpl] = 
clsChain[kpl][kcl].TotChg;
 
 2879       oWir[kpl] = 
clsChain[kpl][kcl].Wire[oend];
 
 2880       oX[kpl] = 
clsChain[kpl][kcl].X[oend];
 
 2881       oAng[kpl] = 
clsChain[kpl][kcl].Angle[oend];
 
 2882       oSlp[kpl] = 
clsChain[kpl][kcl].Slope[oend];
 
 2887     if (nClInPln == 2 && fabs(okWir - kWir) > 3) 
return;
 
 2893     if (nClInPln < 3 && mChg[missingPlane] <= 0) {
 
 2894       if (missingPlane != kpl)
 
 2895         mf::LogError(
"CCTM") << 
"FEM bad missingPlane " << missingPlane << 
" " << kpl << 
"\n";
 
 2896       mChg[kpl] = 
ChargeNear(kpl, (
unsigned short)kWir, kTim, (
unsigned short)okWir, okTim);
 
 2897       match.
Chg[kpl] = mChg[kpl];
 
 2899         mf::LogVerbatim(
"CCTM") << 
"FEM: Missing cluster in " << kpl << 
" ChargeNear " << (int)kWir
 
 2900                                 << 
":" << (
int)kTim << 
" " << (int)okWir << 
":" << (
int)okTim
 
 2901                                 << 
" chg " << mChg[kpl];
 
 2902       if (mChg[kpl] <= 0) 
return;
 
 2905     if (fChgAsymFactor[
algIndex] > 0) {
 
 2907       if (chgAsym > 0.5) 
return;
 
 2908       chgAsym = 1 + fChgAsymFactor[
algIndex] * chgAsym;
 
 2911     if (
prt) mf::LogVerbatim(
"CCTM") << 
"FEM: charge asymmetry factor " << chgAsym;
 
 2912     float sigmaX, sigmaA;
 
 2918     bool allPlnVtxMatch = 
false;
 
 2919     if (nClInPln == 3) {
 
 2920       unsigned short nmvtx = 0;
 
 2921       for (ii = 0; ii < 
nplanes; ++ii) {
 
 2922         if (mVtx[ii] >= 0) {
 
 2923           if (aVtx < 0) aVtx = mVtx[ii];
 
 2928       if (nmvtx) allPlnVtxMatch = 
true;
 
 2932     sigmaX = fXMatchErr[
algIndex] + std::max(kSlp, (
float)20);
 
 2935       mf::LogVerbatim(
"CCTM") << 
"bb " << 
algIndex << 
"  " << fXMatchErr[
algIndex] << 
" " 
 2936                               << fAngleMatchErr[
algIndex] << 
" kslp " << kSlp;
 
 2938     if (nClInPln == 3) {
 
 2939       kcl = match.
Cls[kpl];
 
 2940       kend = match.
End[kpl];
 
 2941       dw = kWir - 
clsChain[kpl][kcl].Wire[kend];
 
 2943       if (fabs(match.
dWir) > 100) 
return;
 
 2944       if (match.
Vtx >= 0) { match.
dX = kX - 
clsChain[kpl][kcl].X[kend]; }
 
 2949       if (
prt) mf::LogVerbatim(
"CCTM") << 
" dw " << dw << 
" dx " << match.
dX;
 
 2952         if (ignoreSign) { match.
dAng = kAng - fabs(
clsChain[kpl][kcl].Angle[kend]); }
 
 2957       da = fabs(match.
dAng) / sigmaA;
 
 2958       dx = fabs(match.
dX) / sigmaX;
 
 2959       if (allPlnVtxMatch) {
 
 2961         match.
Err = vxFactor * chgAsym * da / 3;
 
 2962         if (
prt) mf::LogVerbatim(
"CCTM") << 
" 3-pln w Vtx  match.Err " << match.
Err;
 
 2967         match.
Err = vxFactor * chgAsym * sqrt(dx * dx + da * da + dw * dw) / 9;
 
 2968         if (
prt) mf::LogVerbatim(
"CCTM") << 
" 3-pln match.Err " << match.
Err;
 
 2977       match.
Err = 3 + vxFactor * chgAsym * fabs(match.
dX) / sigmaX;
 
 2978       if (
prt) mf::LogVerbatim(
"CCTM") << 
" 2-pln Err " << match.
Err;
 
 2982     if (nClInPln == 3) {
 
 2984       dw = okWir - oWir[kpl];
 
 2986       if (match.
oVtx >= 0) { match.
odX = okX - oX[kpl]; }
 
 2991         mf::LogVerbatim(
"CCTM") << 
" odw " << match.
odWir << 
" odx " << match.
odX << 
" sigmaX " 
 2995         if (ignoreSign) { match.
odAng = okAng - fabs(oAng[kpl]); }
 
 2997           match.
odAng = okAng - oAng[kpl];
 
 3000       da = match.
odAng / sigmaA;
 
 3001       dx = fabs(match.
odX) / sigmaX;
 
 3005       match.
oErr = ovxFactor * chgAsym * sqrt(dx * dx + da * da + dw * dw) / 9;
 
 3006       if (
prt) mf::LogVerbatim(
"CCTM") << 
" 3-pln match.oErr " << match.
oErr;
 
 3010       match.
odX = (oX[ipl] - oX[jpl]) / sigmaX;
 
 3011       match.
oErr = 3 + ovxFactor * chgAsym * fabs(match.
odX);
 
 3012       if (
prt) mf::LogVerbatim(
"CCTM") << 
" 2-pln match.oErr " << match.
oErr;
 
 3020                                    unsigned short& kend,
 
 3028     unsigned short okend;
 
 3031     if (kcl >= 0) 
return false;
 
 3034     float kslp = fabs((okX - kX) / (okWir - kWir));
 
 3035     if (kslp > 20) kslp = 20;
 
 3037     dxcut = 3 * fXMatchErr[
algIndex] + kslp;
 
 3038     unsigned short nfound = 0;
 
 3039     unsigned short foundCl = 0, foundEnd = 0;
 
 3040     for (
unsigned short ccl = 0; ccl < 
clsChain[kpl].size(); ++ccl) {
 
 3041       if (
clsChain[kpl][ccl].InTrack >= 0) 
continue;
 
 3043       for (
unsigned short end = 0; 
end < 2; ++
end) {
 
 3045         if (fabs(
clsChain[kpl][ccl].Wire[
end] - kWir) > 4) 
continue;
 
 3046         if (fabs(
clsChain[kpl][ccl].Wire[okend] - okWir) > 4) 
continue;
 
 3049             fabs(
clsChain[kpl][ccl].
X[okend] - okX) > dxcut)
 
 3056     if (nfound == 0) 
return false;
 
 3058       mf::LogVerbatim(
"CCTM") << 
"FindMissingCluster: Found too many matches. Write some code " 
 3074     float big = 0, small = 1.E9;
 
 3075     for (
unsigned short ii = 0; ii < 3; ++ii) {
 
 3076       if (mChg[ii] < small) small = mChg[ii];
 
 3077       if (mChg[ii] > big) big = mChg[ii];
 
 3080     return (big - small) / (big + small);
 
 3091     for (ipl = 0; ipl < 3; ++ipl)
 
 3094     if (imat > 
matcomb.size()) 
return;
 
 3096     unsigned short indx;
 
 3097     std::vector<art::Ptr<recob::Hit>> clusterhits;
 
 3098     unsigned short icc, ccl, icl, ecl, iht, ii;
 
 3099     short endOrder, fillOrder;
 
 3102       mf::LogVerbatim(
"CCTM") << 
"In FillTrkHits: matcomb " << imat << 
" cluster chains " 
 3106     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3107       if (
matcomb[imat].Cls[ipl] < 0) 
continue;
 
 3111       endOrder = 1 - 2 * 
matcomb[imat].End[ipl];
 
 3114         std::reverse(
clsChain[ipl][ccl].ClsIndex.begin(), 
clsChain[ipl][ccl].ClsIndex.end());
 
 3115         std::reverse(
clsChain[ipl][ccl].Order.begin(), 
clsChain[ipl][ccl].Order.end());
 
 3116         for (ii = 0; ii < 
clsChain[ipl][ccl].Order.size(); ++ii)
 
 3120         mf::LogError(
"CCTM") << 
"Bad cluster chain index " << ccl << 
" in plane " << ipl;
 
 3124       for (icc = 0; icc < 
clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
 
 3125         icl = 
clsChain[ipl][ccl].ClsIndex[icc];
 
 3126         if (icl > fmCluHits.size() - 1) {
 
 3127           std::cout << 
"oops in FTH " << icl << 
" clsChain size " << 
clsChain[ipl].size() << 
"\n";
 
 3130         ecl = 
cls[ipl][icl].EvtIndex;
 
 3131         if (ecl > fmCluHits.size() - 1) {
 
 3132           std::cout << 
"FTH bad EvtIndex " << ecl << 
" fmCluHits size " << fmCluHits.size() << 
"\n";
 
 3135         clusterhits = fmCluHits.at(ecl);
 
 3136         if (clusterhits.size() == 0) {
 
 3137           std::cout << 
"FTH no cluster hits for EvtIndex " << 
cls[ipl][icl].EvtIndex << 
"\n";
 
 3141         trkHits[ipl].resize(indx + clusterhits.size());
 
 3143         fillOrder = 1 - 2 * 
clsChain[ipl][ccl].Order[icc];
 
 3145         if (fillOrder == 1) {
 
 3147           for (iht = 0; iht < clusterhits.size(); ++iht) {
 
 3149             trkHits[ipl][indx + iht] = clusterhits[iht];
 
 3155           for (ii = 0; ii < clusterhits.size(); ++ii) {
 
 3156             iht = clusterhits.size() - 1 - ii;
 
 3158             trkHits[ipl][indx + ii] = clusterhits[iht];
 
 3164         mf::LogVerbatim(
"CCTM") << 
"plane " << ipl << 
" first p " << 
trkHits[ipl][0]->WireID().Plane
 
 3165                                 << 
" w " << 
trkHits[ipl][0]->WireID().Wire << 
":" 
 3166                                 << (int)
trkHits[ipl][0]->PeakTime() << 
" last p " 
 3167                                 << 
trkHits[ipl][ii]->WireID().Plane << 
" w " 
 3168                                 << 
trkHits[ipl][ii]->WireID().Wire << 
":" 
 3169                                 << (int)
trkHits[ipl][ii]->PeakTime();
 
 3182     mf::LogVerbatim myprt(
"CCTM");
 
 3183     myprt << 
"********* PrintTracks \n";
 
 3184     myprt << 
"vtx  Index    X      Y      Z\n";
 
 3185     for (
unsigned short ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
 3186       myprt << 
std::right << std::setw(4) << ivx << std::setw(4) << 
vtx[ivx].EvtIndex;
 
 3187       myprt << std::fixed;
 
 3188       myprt << 
std::right << std::setw(10) << std::setprecision(1) << 
vtx[ivx].X;
 
 3189       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
vtx[ivx].Y;
 
 3190       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
vtx[ivx].Z;
 
 3191       if (
vtx[ivx].Neutrino) myprt << 
" Neutrino vertex";
 
 3195     myprt << 
">>>>>>>>>> Tracks \n";
 
 3196     myprt << 
"trk  ID  Proc nht nTrj  sX     sY     sZ     eX     eY     eZ  sVx eVx sGd eGd " 
 3197              "ChgOrd  dirZ Mom PDG     ClsIndices\n";
 
 3198     for (
unsigned short itr = 0; itr < 
trk.size(); ++itr) {
 
 3199       myprt << 
std::right << std::setw(3) << itr << std::setw(4) << 
trk[itr].ID;
 
 3200       myprt << 
std::right << std::setw(5) << std::setw(4) << 
trk[itr].Proc;
 
 3201       unsigned short nht = 0;
 
 3202       for (
unsigned short ii = 0; ii < 3; ++ii)
 
 3203         nht += 
trk[itr].TrkHits[ii].
size();
 
 3205       myprt << std::setw(4) << 
trk[itr].TrjPos.size();
 
 3206       myprt << std::fixed;
 
 3207       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[0](0);
 
 3208       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[0](1);
 
 3209       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[0](2);
 
 3210       unsigned short itj = 
trk[itr].TrjPos.size() - 1;
 
 3211       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[itj](0);
 
 3212       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[itj](1);
 
 3213       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
trk[itr].TrjPos[itj](2);
 
 3214       myprt << std::setw(4) << 
trk[itr].VtxIndex[0] << std::setw(4) << 
trk[itr].VtxIndex[1];
 
 3215       myprt << std::setw(4) << 
trk[itr].GoodEnd[0];
 
 3216       myprt << std::setw(4) << 
trk[itr].GoodEnd[1];
 
 3217       myprt << std::setw(4) << 
trk[itr].ChgOrder;
 
 3218       myprt << 
std::right << std::setw(10) << std::setprecision(3) << 
trk[itr].TrjDir[itj](2);
 
 3220       myprt << 
std::right << std::setw(5) << 
trk[itr].PDGCode << 
"   ";
 
 3221       for (
unsigned short ii = 0; ii < 
trk[itr].ClsEvtIndices.size(); ++ii)
 
 3222         myprt << 
" " << 
trk[itr].ClsEvtIndices[ii];
 
 3233     unsigned short iTime;
 
 3234     mf::LogVerbatim myprt(
"CCTM");
 
 3235     myprt << 
"******* PrintClusters *********  Num_Clusters_in             Wire:Time\n";
 
 3236     myprt << 
"vtx  Index    X       Y       Z  Pln0 Pln1 Pln2          Pln0    Pln1    Pln2\n";
 
 3237     for (
unsigned short ivx = 0; ivx < 
vtx.size(); ++ivx) {
 
 3238       myprt << 
std::right << std::setw(3) << ivx << std::setw(7) << ivx;
 
 3239       myprt << std::fixed;
 
 3240       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
vtx[ivx].X;
 
 3241       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
vtx[ivx].Y;
 
 3242       myprt << 
std::right << std::setw(7) << std::setprecision(1) << 
vtx[ivx].Z;
 
 3243       myprt << 
std::right << std::setw(5) << 
vtx[ivx].nClusInPln[0];
 
 3244       myprt << 
std::right << std::setw(5) << 
vtx[ivx].nClusInPln[1];
 
 3245       myprt << 
std::right << std::setw(5) << 
vtx[ivx].nClusInPln[2];
 
 3247       for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3250         myprt << 
std::right << std::setw(7) << wire << 
":" << time;
 
 3256     for (
unsigned short ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3257       myprt << 
">>>>>>>>>> Cluster chains in Plane " << ipl << 
"\n";
 
 3258       myprt << 
"ipl   ccl  Len    Chg    W0:T0     Ang0 Dir0  Vx0  mBk0   W1:T1     Ang1 Dir1  Vx1 " 
 3259                " mBk1  InTk    cls:Order \n";
 
 3260       for (
unsigned short ccl = 0; ccl < 
clsChain[ipl].size(); ++ccl) {
 
 3265         for (
unsigned short end = 0; 
end < 2; ++
end) {
 
 3268                 << std::setprecision(1) << iTime;
 
 3269           if (iTime < 10) { myprt << 
"   "; }
 
 3270           else if (iTime < 100) {
 
 3273           else if (iTime < 1000)
 
 3275           myprt << 
std::right << std::setw(7) << std::setprecision(2)
 
 3279           myprt << std::fixed << 
std::right << std::setw(6) << std::setprecision(1)
 
 3285         for (
unsigned short ii = 0; ii < 
clsChain[ipl][ccl].ClsIndex.size(); ++ii)
 
 3286           myprt << 
" " << 
clsChain[ipl][ccl].ClsIndex[ii] << 
":" << 
clsChain[ipl][ccl].Order[ii];
 
 3289       if (fPrintAllClusters) {
 
 3290         myprt << 
">>>>>>>>>> Clusters in Plane " << ipl << 
"\n";
 
 3291         myprt << 
"ipl  icl  Evt   Len     Chg   W0:T0     Ang0 Dir0  Vx0  CN0   W1:T1      Ang1  " 
 3292                  "Dir1  Vx1  CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
 
 3293         for (
unsigned short icl = 0; icl < 
cls[ipl].size(); ++icl) {
 
 3296           myprt << 
std::right << std::setw(5) << 
cls[ipl][icl].EvtIndex;
 
 3297           myprt << 
std::right << std::setw(6) << 
cls[ipl][icl].Length;
 
 3298           myprt << 
std::right << std::setw(8) << (int)
cls[ipl][icl].TotChg;
 
 3299           for (
unsigned short end = 0; 
end < 2; ++
end) {
 
 3300             iTime = 
cls[ipl][icl].Time[
end];
 
 3301             myprt << 
std::right << std::setw(5) << (int)
cls[ipl][icl].Wire[
end] << 
":" << iTime;
 
 3302             if (iTime < 10) { myprt << 
"   "; }
 
 3303             else if (iTime < 100) {
 
 3306             else if (iTime < 1000)
 
 3308             myprt << 
std::right << std::setw(7) << std::setprecision(2) << 
cls[ipl][icl].Angle[
end];
 
 3311             myprt << std::fixed << 
std::right << std::setw(5) << std::setprecision(1)
 
 3312                   << 
cls[ipl][icl].ChgNear[
end];
 
 3314           myprt << std::fixed;
 
 3315           myprt << 
std::right << std::setw(5) << 
cls[ipl][icl].InTrack;
 
 3316           myprt << 
std::right << std::setw(5) << (int)
cls[ipl][icl].BrkIndex[0];
 
 3317           myprt << 
std::right << std::setw(7) << std::setprecision(1)
 
 3318                 << 
cls[ipl][icl].MergeError[0];
 
 3319           myprt << 
std::right << std::setw(5) << (int)
cls[ipl][icl].BrkIndex[1];
 
 3320           myprt << 
std::right << std::setw(7) << std::setprecision(1)
 
 3321                 << 
cls[ipl][icl].MergeError[1];
 
 3332     float slp = fabs(slope);
 
 3333     if (slp > 10.) slp = 30.;
 
 3335     return 1 + 0.05 * slp * slp;
 
 3341                            unsigned short wire1,
 
 3343                            unsigned short wire2,
 
 3350     unsigned short w1 = wire1;
 
 3351     unsigned short w2 = wire2;
 
 3355     if (w1 == w2) { slp = 0; }
 
 3363       slp = (t2 - t1) / (w2 - w1);
 
 3366     unsigned short wire;
 
 3374       if (wire < w1) 
continue;
 
 3375       if (wire > w2) 
continue;
 
 3376       prtime = t1 + (wire - w1) * slp;
 
 3378       if (prtime > 
allhits[
hit]->PeakTimePlusRMS(3)) 
continue;
 
 3379       if (prtime < 
allhits[
hit]->PeakTimeMinusRMS(3)) 
continue;
 
 3394     for (ipl = 0; ipl < 3; ++ipl) {
 
 3404     unsigned short oldipl = 0;
 
 3411           mf::LogError(
"CCTM") << 
"Invalid WireID().Wire " << 
allhits[
hit]->WireID().Wire;
 
 3417         mf::LogError(
"CCTM") << 
"Hits are not in increasing-plane order\n";
 
 3430     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3432         mf::LogError(
"CCTM") << 
"Invalid first/last wire in plane " << ipl;
 
 3439     for (ipl = 0; ipl < 
nplanes; ++ipl)
 
 3447     int sflag, nwires, wire;
 
 3448     unsigned int indx, thisWire, thisHit, lastFirstHit;
 
 3450     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3455       for (wire = 0; wire < nwires; ++wire)
 
 3456         WireHitRange[ipl][wire] = std::make_pair(sflag, sflag);
 
 3459       for (wire = 0; wire < nwires; ++wire) {
 
 3473           indx = 
lastWire[ipl] - firstWire[ipl];
 
 3474           int tmp1 = lastFirstHit;
 
 3478           lastFirstHit = thisHit;
 
 3480         else if (thisWire < 
lastWire[ipl]) {
 
 3481           mf::LogError(
"CCTM") << 
"Hit not in proper order in plane " << ipl;
 
 3487       indx = 
lastWire[ipl] - firstWire[ipl];
 
 3488       int tmp1 = lastFirstHit;
 
 3497     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3500       if (
firstHit[ipl] < INT_MAX) 
continue;
 
 3501       if (
lastHit[ipl] > 0) 
continue;
 
 3506     unsigned int nht = 0;
 
 3507     std::vector<bool> hchk(
allhits.size());
 
 3508     for (
unsigned int ii = 0; ii < hchk.size(); ++ii)
 
 3510     for (ipl = 0; ipl < 
nplanes; ++ipl) {
 
 3513         if (indx > lastWire[ipl]) {
 
 3514           std::cout << 
"FWHR bad index " << indx << 
"\n";
 
 3521         for (
unsigned int hit = firhit; 
hit < lashit; ++
hit) {
 
 3530                       << 
" or wire " << 
allhits[
hit]->WireID().Wire << 
" " << 
w << 
"\n";
 
 3538       std::cout << 
"FWHR hit count problem " << nht << 
" " << 
allhits.size() << 
"\n";
 
 3539       for (
unsigned int ii = 0; ii < hchk.size(); ++ii)
 
 3542                     << 
allhits[ii]->WireID().Wire << 
" " << (int)
allhits[ii]->PeakTime() << 
"\n";
 
std::string fHitModuleLabel
float Length(const PFPStruct &pfp)
std::array< short, 2 > VtxIndex
std::vector< MatchPars > matcomb
float ChargeNear(unsigned short ipl, unsigned short wire1, float time1, unsigned short wire2, float time2)
art::ServiceHandle< geo::Geometry const  > geom
std::string fVertexModuleLabel
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
std::array< float, 3 > ChgNorm
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
std::vector< float > fChgAsymFactor
std::array< unsigned short, 3 > End
Declaration of signal hit object. 
std::array< unsigned int, 3 > firstWire
void FillEndMatch2(detinfo::DetectorPropertiesData const &detProp, MatchPars &match)
Planes which measure X direction. 
Geometry information for a single TPC. 
void SortMatches(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
std::vector< art::Ptr< recob::Hit > > allhits
std::array< short, 2 > Dir
TrackTrajectory::Flags_t Flags_t
void StoreTrack(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat, unsigned short procCode)
float StartWire() const 
Returns the wire coordinate of the start of the cluster. 
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
Plane(const Point_t &planePos, const Vector_t &planeDir)
Constructor from reference position on the plane and direction orthogonal to the plane. 
std::string fClusterModuleLabel
std::size_t size(FixedBins< T, C > const &) noexcept
TrackTrajectoryAlg fTrackTrajectoryAlg
std::array< float, 2 > ChgNear
Set of hits with a 2D structure. 
std::array< short, 2 > BrkIndex
float EndTick() const 
Returns the tick coordinate of the end of the cluster. 
process_name use argoneut_mc_hitfinder track
std::vector< unsigned short > pfpToTrkID
std::vector< TVector3 > TrjPos
std::vector< TrkPar > trk
float dXClTraj(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short ipl, unsigned short icl1, unsigned short end1, unsigned short icl2)
void PlnMatch(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
bool FindMissingCluster(unsigned short kpl, short &kcl, unsigned short &kend, float kWir, float kX, float okWir, float okX)
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
std::vector< float > fAngleMatchErr
std::array< float, 2 > ChgNear
std::array< std::vector< clPar >, 3 > cls
void FitVertices(detinfo::DetectorPropertiesData const &detProp)
float StartAngle() const 
Returns the starting angle of the cluster. 
Definition of vertex object for LArSoft. 
std::array< float, 2 > Slope
std::array< bool, 2 > EndInTPC
void AngMatch(art::FindManyP< recob::Hit > const &fmCluHits)
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
std::array< std::vector< ClsChainPar >, 3 > clsChain
float EndCharge() const 
Returns the charge on the last wire of the cluster. 
bool DupMatch(MatchPars &match)
void FillTrkHits(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat)
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter. 
A trajectory in space reconstructed from hits. 
std::vector< float > fMatchMinLen
void FillEndMatch(detinfo::DetectorPropertiesData const &detProp, MatchPars &match)
CCTrackMaker(fhicl::ParameterSet const &pset)
std::vector< unsigned short > Order
float AngleFactor(float slope)
std::array< short, 2 > VtxIndex
std::array< short, 2 > mVtxIndex
auto end(FixedBins< T, C > const &) noexcept
std::vector< short > DtrID
double ConvertXToTicks(double X, int p, int t, int c) const 
std::vector< vtxPar > vtx
std::array< float, 2 > MergeError
void produce(art::Event &evt) override
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::array< bool, 2 > GoodEnd
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
std::array< float, 2 > Wire
Declaration of cluster object. 
void TrackTrajectory(std::array< std::vector< geo::WireID >, 3 > trkWID, std::array< std::vector< double >, 3 > trkX, std::array< std::vector< double >, 3 > trkXErr, std::vector< TVector3 > &TrajPos, std::vector< TVector3 > &TrajDir)
std::array< unsigned int, 3 > firstHit
std::array< float, 2 > Charge
Provides recob::Track data product. 
std::vector< unsigned short > ClsIndex
void MakeClusterChains(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
auto norm(Vector const &v)
Return norm of the specified vector. 
std::vector< unsigned short > ClsEvtIndices
std::array< unsigned int, 3 > lastWire
Class defining a plane for tracking. It provides various functionalities to convert track parameters ...
double ConvertTicksToX(double ticks, int p, int t, int c) const 
auto begin(FixedBins< T, C > const &) noexcept
bool greaterThan(CluLen c1, CluLen c2)
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association. 
void VertexFit(std::vector< std::vector< geo::WireID >> const &hitWID, std::vector< std::vector< double >> const &hitX, std::vector< std::vector< double >> const &hitXErr, TVector3 &VtxPos, TVector3 &VtxPosErr, std::vector< TVector3 > &TrkDir, std::vector< TVector3 > &TrkDirErr, float &ChiDOF) const 
Hierarchical representation of particle flow. 
std::array< float, 2 > Time
float StartCharge() const 
Returns the charge on the first wire of the cluster. 
std::array< float, 2 > Slope
std::array< short, 2 > VtxIndex
void PrintClusters(detinfo::DetectorPropertiesData const &detProp) const 
std::array< unsigned int, 3 > lastHit
bool lessThan(CluLen c1, CluLen c2)
std::array< short, 2 > Dir
std::vector< TVector3 > TrjDir
std::array< float, 2 > Angle
void FillChgNear(detinfo::DetectorPropertiesData const &detProp)
std::vector< bool > fMakeAlgTracks
std::vector< short > fMatchAlgs
std::vector< float > fXMatchErr
float EndAngle() const 
Returns the ending angle of the cluster. 
recob::tracking::Plane Plane
float ChargeAsym(std::array< float, 3 > &mChg)
std::array< float, 2 > Wire
std::array< short, 3 > Cls
void VtxMatch(detinfo::DetectorPropertiesData const &detProp, art::FindManyP< recob::Hit > const &fmCluHits)
float StartTick() const 
Returns the tick coordinate of the start of the cluster. 
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > TrkHits
void LocalToWorld(const double *tpc, double *world) const 
Transform point from local TPC frame to world frame. 
VertexFitAlg fVertexFitAlg
std::array< short, 2 > Time
std::array< float, 3 > Chg
art framework interface to geometry description 
BEGIN_PROLOG could also be cout
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track: 
std::array< float, 2 > Angle
Encapsulate the construction of a single detector plane. 
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
std::array< std::vector< unsigned short >, 3 > vxCls
std::array< unsigned short, 3 > nClusInPln
unsigned short fNVtxTrkHitsFit
float Integral() const 
Returns the total charge of the cluster from hit shape. 
float EndWire() const 
Returns the wire coordinate of the end of the cluster. 
std::array< short, 2 > mBrkIndex