19 #include "art/Framework/Core/EDProducer.h" 
   20 #include "art/Framework/Core/ModuleMacros.h" 
   21 #include "art/Framework/Principal/Event.h" 
   22 #include "art/Framework/Principal/Handle.h" 
   23 #include "fhiclcpp/types/Atom.h" 
   24 #include "fhiclcpp/types/Table.h" 
   25 #include "messagefacility/MessageLogger/MessageLogger.h" 
   28 #include "canvas/Utilities/InputTag.h" 
   54         Name(
"ProjectionMatchingAlg")};
 
   61         Name(
"HitModuleLabel"),
 
   62         Comment(
"tag of unclustered hits, which were used to produce PFPs and clusters")};
 
   65         Name(
"PfpModuleLabel"),
 
   66         Comment(
"tag of the input PFParticles and associated clusters")};
 
   69         Name(
"SaveOnlyBranchingVtx"),
 
   70         Comment(
"use true to save only vertices interconnecting many tracks, otherwise vertex is " 
   71                 "added to the front of each track")};
 
   75         Comment(
"save track nodes (only for algorithm development purposes)")};
 
   87     void produce(art::Event& 
e) 
override;
 
  105     art::ServiceHandle<geo::Geometry const> 
fGeom;
 
  114     , fHitModuleLabel(config().HitModuleLabel())
 
  115     , fPfpModuleLabel(config().PfpModuleLabel())
 
  118     fPmaConfig(config().ProjectionMatchingAlg())
 
  119     , fPmaFitterConfig(config().PMAlgFitting())
 
  120     , fPmaVtxConfig(config().PMAlgVertexing())
 
  123     fSaveOnlyBranchingVtx(config().SaveOnlyBranchingVtx())
 
  124     , fSavePmaNodes(config().SavePmaNodes())
 
  126     produces<std::vector<recob::Track>>();
 
  127     produces<std::vector<recob::SpacePoint>>();
 
  128     produces<std::vector<recob::Vertex>>();           
 
  129     produces<std::vector<recob::Vertex>>(kKinksName); 
 
  130     produces<std::vector<recob::Vertex>>(kNodesName); 
 
  134     produces<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>();
 
  136     produces<art::Assns<recob::Track, recob::SpacePoint>>();
 
  137     produces<art::Assns<recob::SpacePoint, recob::Hit>>();
 
  141     produces<art::Assns<recob::Track, recob::Vertex>>(kKinksName); 
 
  143     produces<art::Assns<recob::PFParticle, recob::Track>>();
 
  151     auto tracks = std::make_unique<std::vector<recob::Track>>();
 
  152     auto allsp = std::make_unique<std::vector<recob::SpacePoint>>();
 
  153     auto vtxs = std::make_unique<std::vector<recob::Vertex>>(); 
 
  154     auto kinks = std::make_unique<
 
  155       std::vector<recob::Vertex>>(); 
 
  156     auto nodes = std::make_unique<std::vector<recob::Vertex>>(); 
 
  158     auto trk2hit_oldway = std::make_unique<
 
  161     auto trk2hit = std::make_unique<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>();
 
  163     auto trk2sp = std::make_unique<art::Assns<recob::Track, recob::SpacePoint>>();
 
  165     auto sp2hit = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
 
  166     auto vtx2trk = std::make_unique<
 
  170       std::make_unique<art::Assns<recob::Track, recob::Vertex>>(); 
 
  172     auto pfp2trk = std::make_unique<art::Assns<recob::PFParticle, recob::Track>>();
 
  175     art::Handle<std::vector<recob::Hit>> allHitListHandle;
 
  176     art::Handle<std::vector<recob::Cluster>> cluListHandle;
 
  177     art::Handle<std::vector<recob::PFParticle>> pfparticleHandle;
 
  178     std::vector<art::Ptr<recob::Hit>> allhitlist;
 
  184       throw cet::exception(
"PMAlgTrajFitter")
 
  185         << 
"Not all required data products found in the event." << std::endl;
 
  188     art::fill_ptr_vector(allhitlist, allHitListHandle);
 
  190     art::FindManyP<recob::Hit> hitsFromClusters(cluListHandle, evt, 
fPfpModuleLabel);
 
  191     art::FindManyP<recob::Cluster> clustersFromPfps(pfparticleHandle, evt, 
fPfpModuleLabel);
 
  192     art::FindManyP<recob::Vertex> vtxFromPfps(pfparticleHandle, evt, 
fPfpModuleLabel);
 
  195       art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
 
  209     int retCode = pmalgFitter.build(
detProp);
 
  212     case -2: mf::LogError(
"Summary") << 
"problem"; 
break;
 
  213     case -1: mf::LogWarning(
"Summary") << 
"no input"; 
break;
 
  214     case 0: mf::LogVerbatim(
"Summary") << 
"no tracks done"; 
break;
 
  217         mf::LogVerbatim(
"Summary") << 
"unknown result";
 
  218       else if (retCode == 1)
 
  219         mf::LogVerbatim(
"Summary") << retCode << 
" track ready";
 
  221         mf::LogVerbatim(
"Summary") << retCode << 
" tracks ready";
 
  226     auto const& result = pmalgFitter.result();
 
  229       size_t spStart = 0, spEnd = 0;
 
  230       double sp_pos[3], sp_err[6];
 
  231       for (
size_t i = 0; i < 3; i++)
 
  233       for (
size_t i = 0; i < 6; i++)
 
  237       std::map<size_t, std::vector<art::Ptr<recob::Track>>> pfPartToTrackVecMap;
 
  241       tracks->reserve(result.size());
 
  242       for (
size_t trkIndex = 0; trkIndex < result.size(); ++trkIndex) {
 
  252         if (trk->
size() < 2) 
continue;
 
  258         size_t trkIdx = 
tracks->size() - 1; 
 
  259         art::ProductID trkId = evt.getProductID<std::vector<recob::Track>>();
 
  260         art::Ptr<recob::Track> trkPtr(trkId, trkIdx, evt.productGetter(trkId));
 
  263         for (
size_t h = 0, cnt = 0; 
h < trk->
size(); 
h++) {
 
  268           trk2hit->addSingle(trkPtr, h3d->
Hit2DPtr(), metadata);
 
  269           trk2hit_oldway->addSingle(
 
  273         art::PtrVector<recob::Hit> sp_hits;
 
  274         spStart = allsp->size();
 
  275         for (
size_t h = 0; 
h < trk->
size(); ++
h) {
 
  279           double hx = h3d->
Point3D().X();
 
  280           double hy = h3d->
Point3D().Y();
 
  281           double hz = h3d->
Point3D().Z();
 
  283           if ((
h == 0) || (std::fabs(sp_pos[0] - hx) > 1.0
e-5) ||
 
  284               (std::fabs(sp_pos[1] - hy) > 1.0
e-5) || (std::fabs(sp_pos[2] - hz) > 1.0
e-5)) {
 
  302         spEnd = allsp->size();
 
  307         if (result[trkIndex].Key() > -1) {
 
  308           size_t trackIdx = 
tracks->size() - 1;
 
  309           art::ProductID trackId = evt.getProductID<std::vector<recob::Track>>();
 
  310           art::Ptr<recob::Track> trackPtr(trackId, trackIdx, evt.productGetter(trackId));
 
  311           pfPartToTrackVecMap[result[trkIndex].Key()].push_back(trackPtr);
 
  315       auto vid = evt.getProductID<std::vector<recob::Vertex>>();
 
  316       auto kid = evt.getProductID<std::vector<recob::Vertex>>(
kKinksName);
 
  317       auto const* kinkGetter = evt.productGetter(kid);
 
  319       auto tid = evt.getProductID<std::vector<recob::Track>>();
 
  320       auto const* trkGetter = evt.productGetter(tid);
 
  322       auto vsel = pmalgFitter.getVertices(
 
  324       auto ksel = pmalgFitter.getKinks(); 
 
  325       std::map<size_t, art::Ptr<recob::Vertex>> frontVtxs; 
 
  330         for (
auto const& v : vsel) {
 
  331           xyz[0] = v.first.X();
 
  332           xyz[1] = v.first.Y();
 
  333           xyz[2] = v.first.Z();
 
  334           mf::LogVerbatim(
"Summary") << 
"  vtx:" << xyz[0] << 
":" << xyz[1] << 
":" << xyz[2]
 
  335                                      << 
"  (" << v.second.size() << 
" tracks)";
 
  337           size_t vidx = vtxs->size();
 
  338           vtxs->push_back(recob::Vertex(xyz, vidx));
 
  340           art::Ptr<recob::Vertex> vptr(vid, vidx, evt.productGetter(vid));
 
  341           if (vptr.isNull()) mf::LogWarning(
"PMAlgTrajFitter") << 
"Vertex ptr is null.";
 
  342           if (!v.second.empty()) {
 
  343             for (
const auto& vEntry : v.second) {
 
  344               size_t tidx = vEntry.first;
 
  345               bool isFront = vEntry.second;
 
  347               if (isFront) frontVtxs[tidx] = vptr; 
 
  349               art::Ptr<recob::Track> tptr(tid, tidx, trkGetter);
 
  350               vtx2trk->addSingle(vptr, tptr);
 
  354             mf::LogWarning(
"PMAlgTrajFitter") << 
"No tracks found at this vertex.";
 
  356         mf::LogVerbatim(
"Summary") << vtxs->size() << 
" vertices ready";
 
  358         for (
auto const& 
k : ksel) {
 
  359           xyz[0] = 
k.first.X();
 
  360           xyz[1] = 
k.first.Y();
 
  361           xyz[2] = 
k.first.Z();
 
  362           mf::LogVerbatim(
"Summary") << 
"  kink:" << xyz[0] << 
":" << xyz[1] << 
":" << xyz[2];
 
  364           size_t kidx = kinks->size();
 
  365           size_t tidx = 
k.second; 
 
  368             recob::Vertex(xyz, tidx)); 
 
  370           art::Ptr<recob::Track> tptr(tid, tidx, trkGetter);
 
  371           art::Ptr<recob::Vertex> kptr(kid, kidx, kinkGetter);
 
  372           trk2kink->addSingle(tptr, kptr);
 
  374         mf::LogVerbatim(
"Summary") << ksel.size() << 
" kinks ready";
 
  379         for (
size_t t = 0; t < result.size(); ++t) {
 
  380           auto const& trk = *(result[t].Track());
 
  381           for (
auto const* node : trk.Nodes()) {
 
  382             xyz[0] = node->Point3D().X();
 
  383             xyz[1] = node->Point3D().Y();
 
  384             xyz[2] = node->Point3D().Z();
 
  385             nodes->push_back(recob::Vertex(xyz, t));
 
  390       for (
const auto& pfParticleItr : pfPartToTrackVecMap) {
 
  391         art::Ptr<recob::PFParticle> pfParticle(pfparticleHandle, pfParticleItr.first);
 
  392         mf::LogVerbatim(
"PMAlgTrajFitter")
 
  393           << 
"PFParticle key: " << pfParticle.key() << 
", self: " << pfParticle->Self()
 
  394           << 
", #tracks: " << pfParticleItr.second.size();
 
  396         if (!pfParticle.isNull())
 
  399           mf::LogError(
"PMAlgTrajFitter")
 
  400             << 
"Error in PFParticle lookup, pfparticle index: " << pfParticleItr.first
 
  401             << 
", key: " << pfParticle.key();
 
  405     evt.put(std::move(
tracks));
 
  406     evt.put(std::move(allsp));
 
  407     evt.put(std::move(vtxs));
 
  411     evt.put(std::move(trk2hit_oldway)); 
 
  412     evt.put(std::move(trk2hit));
 
  413     evt.put(std::move(trk2sp));
 
  415     evt.put(std::move(sp2hit));
 
  416     evt.put(std::move(vtx2trk));
 
  419     evt.put(std::move(pfp2trk));
 
fhicl::Table< pma::ProjectionMatchingAlg::Config > ProjectionMatchingAlg
bool SelectHits(float fraction=1.0F)
double Dx() const noexcept
ClusterModuleLabel join with tracks
recob::Track convertFrom(const pma::Track3D &src, unsigned int tidx, int pdg=0)
bool fSaveOnlyBranchingVtx
Declaration of signal hit object. 
fhicl::Atom< bool > SavePmaNodes
TVector3 const & Point3D() const 
Planes which measure Z direction. 
art::ServiceHandle< geo::Geometry const  > fGeom
Definition of vertex object for LArSoft. 
void produce(art::Event &e) override
fhicl::Table< pma::PMAlgFitter::Config > PMAlgFitting
art::InputTag fPfpModuleLabel
fhicl::Atom< bool > SaveOnlyBranchingVtx
fhicl::Atom< bool > RunVertexing
BEGIN_PROLOG vertical distance to the surface Name
fhicl::Table< pma::PMAlgVertexing::Config > PMAlgVertexing
unsigned int FrontTPC() const 
unsigned int FrontCryo() const 
Declaration of cluster object. 
Provides recob::Track data product. 
size_t CompleteMissingWires(detinfo::DetectorPropertiesData const &detProp, unsigned int view)
art::EDProducer::Table< Config > Parameters
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. 
pma::PMAlgVertexing::Config fPmaVtxConfig
static const std::string kNodesName
pma::ProjectionMatchingAlg::Config fPmaConfig
art::Ptr< recob::Hit > const & Hit2DPtr() const 
bool IsEnabled() const noexcept
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects. 
2D representation of charge deposited in the TDC/wire plane 
PMAlgTrajFitter(Parameters const &config)
static const std::string kKinksName
fhicl::Atom< art::InputTag > HitModuleLabel
PMAlgTrajFitter & operator=(PMAlgTrajFitter const &)=delete
art framework interface to geometry description 
pma::PMAlgFitter::Config fPmaFitterConfig
Encapsulate the construction of a single detector plane. 
fhicl::Atom< art::InputTag > PfpModuleLabel
art::InputTag fHitModuleLabel