391 detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
397 std::unique_ptr<std::vector<recob::Track>> tcol(
new std::vector<recob::Track>);
400 std::unique_ptr<std::vector<recob::Vertex>> vcol(
new std::vector<recob::Vertex>);
402 std::unique_ptr<std::vector<recob::PFParticle>> pcol(
new std::vector<recob::PFParticle>);
410 std::unique_ptr<std::vector<recob::Seed>> scol(
new std::vector<recob::Seed>);
417 std::vector<art::Ptr<recob::Cluster>> clusterlist;
420 std::vector<art::Ptr<recob::Vertex>> vtxlist;
430 if(clusterlist.size() == 0)
return;
440 std::vector<CluLen> clulens;
442 unsigned short ipl, icl,
end, itr, tID, tIndex;
450 std::vector< art::Ptr<recob::Hit > > tmpHits;
451 std::vector< art::Ptr<recob::Cluster > > tmpCls;
452 std::vector< art::Ptr<recob::Vertex > > tmpVtx;
455 std::vector<size_t> dtrIndices;
458 double sPos[3], sDir[3];
459 double sErr[3] = {0,0,0};
462 std::vector<art::Ptr<recob::Hit>> clusterhits;
463 for(icl = 0; icl < clusterlist.size(); ++icl) {
464 ipl = clusterlist[icl]->Plane().Plane;
465 clusterhits = fmCluHits.at(icl);
466 if(clusterhits[0]->WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
467 std::cout<<
"CCTM Cluster-Hit End wire mis-match "<<clusterhits[0]->WireID().Wire<<
" vs "<<std::nearbyint(clusterlist[icl]->EndWire())<<
" Bail out! \n";
470 for(
unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
471 if(clusterhits[iht]->WireID().Plane != ipl) {
472 std::cout<<
"CCTM Cluster-Hit plane mis-match "<<ipl<<
" vs "<<clusterhits[iht]->WireID().Plane<<
" on hit "<<iht<<
" Bail out! \n";
487 for(ipl = 0; ipl < 3; ++ipl) {
494 for(ipl = 0; ipl <
nplanes; ++ipl) {
497 for(icl = 0; icl < clusterlist.size(); ++icl) {
498 if(clusterlist[icl]->
Plane().Cryostat !=
cstat)
continue;
499 if(clusterlist[icl]->
Plane().TPC !=
tpc)
continue;
500 if(clusterlist[icl]->
Plane().
Plane != ipl)
continue;
503 clulen.
length = clusterlist[icl]->EndWire();
504 clulens.push_back(clulen);
506 if(clulens.size() == 0)
continue;
508 std::sort (clulens.begin(),clulens.end(),
lessThan);
509 if(clulens.size() == 0)
continue;
510 for(
unsigned short ii = 0; ii < clulens.size(); ++ii) {
511 const unsigned short icl = clulens[ii].index;
513 clstr.EvtIndex = icl;
520 clstr.Slope[1] = std::tan(cluster.
StartAngle());
525 clstr.ChgNear[1] = 0;
526 clstr.VtxIndex[1] = -1;
527 clstr.mVtxIndex[1] = -1;
528 clstr.BrkIndex[1] = -1;
531 clstr.Wire[0] = cluster.
EndWire();
532 clstr.Time[0] = cluster.
EndTick();
534 clstr.Angle[0] = cluster.
EndAngle();
535 clstr.Slope[0] = std::tan(cluster.
EndAngle());
538 if(clstr.Time[1] > clstr.Time[0]) {
539 clstr.Dir[0] = 1; clstr.Dir[1] = -1;
541 clstr.Dir[0] = -1; clstr.Dir[1] = 1;
545 clstr.ChgNear[1] = 0;
546 clstr.VtxIndex[0] = -1;
547 clstr.mVtxIndex[0] = -1;
548 clstr.BrkIndex[0] = -1;
552 clstr.Length = (
unsigned short)(0.5 + clstr.Wire[1] - clstr.Wire[0]);
554 if(clstr.TotChg <= 0) clstr.TotChg = 1;
555 clusterhits = fmCluHits.at(icl);
556 if(clusterhits.size() == 0) {
557 mf::LogError(
"CCTM")<<
"No associated cluster hits "<<icl;
561 clstr.TotChg *= clstr.Length / (float)clusterhits.size();
562 cls[ipl].push_back(clstr);
572 for(
unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
576 vtxlist[ivx]->XYZ(xyz);
580 aVtx.nClusInPln[0] = 0;
581 aVtx.nClusInPln[1] = 0;
582 aVtx.nClusInPln[2] = 0;
583 std::vector<art::Ptr<recob::Cluster>>
const& vtxCls = fmVtxCls.at(ivx);
584 std::vector<const unsigned short*>
const& vtxClsEnd = fmVtxCls.data(ivx);
585 for(
unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
586 icl = vtxCls[vcass].key();
588 ipl = vtxCls[vcass]->Plane().Plane;
589 end = *vtxClsEnd[vcass];
590 if(end > 1)
throw cet::exception(
"CCTM")<<
"Invalid end data from vertex - cluster association"<<
end;
594 for(
unsigned short jcl = 0; jcl <
cls[ipl].size(); ++jcl) {
595 if(
cls[ipl][jcl].EvtIndex == icl) {
596 cls[ipl][jcl].VtxIndex[
end] = ivx;
597 ++aVtx.nClusInPln[ipl];
602 if(!gotit)
throw cet::exception(
"CCTM")<<
"Bad index from vertex - cluster association"<<icl;
635 for(
unsigned short ipf = 0; ipf <
pfpToTrkID.size(); ++ipf) {
638 if(tID >
trk.size()+1) {
645 for(
unsigned short jpf = 0; jpf <
pfpToTrkID.size(); ++jpf) {
647 if(
trk[itr].MomID == tID) dtrIndices.push_back(jpf);
650 unsigned short parentIndex = USHRT_MAX;
654 pcol->emplace_back(std::move(pfp));
655 for(
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
656 if(!
vtx[ivx].Neutrino)
continue;
661 size_t vStart = vcol->size();
663 vcol->emplace_back(std::move(
vertex));
664 size_t vEnd = vcol->size();
667 vtx[ivx].ID = -
vtx[ivx].ID;
675 for(
unsigned short ii = 0; ii <
pfpToTrkID.size(); ++ii) {
682 mf::LogVerbatim(
"CCTM")<<
"daughters tID "<<tID<<
" pdg "<<
trk[tIndex].PDGCode<<
" ipf "<<ipf<<
" parentIndex "<<parentIndex<<
" dtr size "<<dtrIndices.size();
684 pcol->emplace_back(std::move(pfp));
687 size_t tStart = tcol->size();
692 tcol->emplace_back(std::move(
track));
693 size_t tEnd = tcol->size();
697 trk[tIndex].ID = -
trk[tIndex].ID;
700 for(ipl = 0; ipl <
nplanes; ++ipl)
701 tmpHits.insert(tmpHits.end(),
trk[tIndex].TrkHits[ipl].begin(),
trk[tIndex].TrkHits[ipl].end());
706 unsigned short itj = 0;
707 if(end > 0) itj =
trk[tIndex].TrjPos.size() - 1;
708 for(
unsigned short ii = 0; ii < 3; ++ii) {
709 sPos[ii] =
trk[tIndex].TrjPos[itj](ii);
710 sDir[ii] =
trk[tIndex].TrjDir[itj](ii);
712 size_t sStart = scol->size();
714 scol->emplace_back(std::move(
seed));
715 size_t sEnd = scol->size();
720 for(ipl = 0; ipl <
nplanes; ++ipl)
726 for(
unsigned short ii = 0; ii <
trk[tIndex].ClsEvtIndices.size(); ++ii) {
727 icl =
trk[tIndex].ClsEvtIndices[ii];
728 tmpCls.push_back(clusterlist[icl]);
734 for(
unsigned short itr = 0; itr <
trk.size(); ++itr) {
736 if(
trk[itr].ID < 0)
continue;
741 tcol->emplace_back(std::move(
track));
743 for(ipl = 0; ipl <
nplanes; ++ipl)
744 tmpHits.insert(tmpHits.end(),
trk[itr].TrkHits[ipl].begin(),
trk[itr].TrkHits[ipl].end());
748 for(
unsigned short ivx = 0; ivx <
vtx.size(); ++ivx) {
749 if(
vtx[ivx].ID < 0)
continue;
754 vcol->emplace_back(std::move(
vertex));
758 double orphanLen = 0;
759 for(ipl = 0; ipl <
nplanes; ++ipl) {
760 for(icl = 0; icl <
cls[ipl].size(); ++icl) {
761 if(
cls[ipl][icl].Length > 40 &&
cls[ipl][icl].InTrack < 0) {
762 orphanLen +=
cls[ipl][icl].Length;
764 mf::LogVerbatim(
"CCTM")<<
"Orphan long cluster "<<ipl<<
":"<<icl<<
":"<<
cls[ipl][icl].Wire[0]
765 <<
":"<<(int)
cls[ipl][icl].Time[0]<<
" length "<<
cls[ipl][icl].Length;
772 std::cout<<
"Total orphan length "<<orphanLen<<
"\n";
779 evt.
put(std::move(pcol));
780 evt.
put(std::move(ptassn));
781 evt.
put(std::move(pcassn));
782 evt.
put(std::move(pvassn));
783 evt.
put(std::move(psassn));
784 evt.
put(std::move(tcol));
785 evt.
put(std::move(thassn));
786 evt.
put(std::move(scol));
787 evt.
put(std::move(vcol));
std::string fHitModuleLabel
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
std::string fVertexModuleLabel
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
unsigned int Nplanes() const
Number of planes in this tpc.
void PrintClusters() const
std::vector< art::Ptr< recob::Hit > > allhits
TrackTrajectory::Flags_t Flags_t
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Plane(const Point_t &planePos, const Vector_t &planeDir)
Constructor from reference position on the plane and direction orthogonal to the plane.
std::string fClusterModuleLabel
Set of hits with a 2D structure.
float EndTick() const
Returns the tick coordinate of the end of the cluster.
std::vector< unsigned short > pfpToTrkID
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
std::array< float, 3 > ChgNorm
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::array< std::vector< clPar >, 3 > cls
float StartAngle() const
Returns the starting angle of the cluster.
Definition of vertex object for LArSoft.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
ProductID put(std::unique_ptr< PROD > &&product)
std::array< std::vector< ClsChainPar >, 3 > clsChain
float EndCharge() const
Returns the charge on the last wire of the cluster.
void MakeClusterChains(art::FindManyP< recob::Hit > const &fmCluHits)
A trajectory in space reconstructed from hits.
unsigned int NTPC() const
Number of TPCs in this cryostat.
std::vector< vtxPar > vtx
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
Hierarchical representation of particle flow.
float StartCharge() const
Returns the charge on the first wire of the cluster.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc'th TPC in the cryostat.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
art::ServiceHandle< geo::Geometry > geom
bool lessThan(CluLen c1, CluLen c2)
void SortMatches(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
void VtxMatch(art::FindManyP< recob::Hit > const &fmCluHits)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void PlnMatch(art::FindManyP< recob::Hit > const &fmCluHits)
std::vector< bool > fMakeAlgTracks
std::vector< short > fMatchAlgs
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
float EndAngle() const
Returns the ending angle of the cluster.
recob::tracking::Plane Plane
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
cet::coded_exception< error, detail::translate > exception
const detinfo::DetectorProperties * detprop
std::array< std::vector< unsigned short >, 3 > vxCls
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.