All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AssnsChainPFParticleMaker_module.cc
Go to the documentation of this file.
1 /**
2  * @file AssnsChainPFParticleMaker_module.cc
3  * @brief Test producer creating a few dummy PFParticles associated with
4  * clusters.
5  * @author Gianluca Petrillo (petrillo@fnal.gov)
6  * @date June 26, 2017
7  */
8 
9 // LArSoft libraries
10 #include "art/Persistency/Common/PtrMaker.h"
13 
14 // framework libraries
15 #include "art/Framework/Core/EDProducer.h"
16 #include "art/Framework/Core/ModuleMacros.h"
17 #include "art/Framework/Principal/Event.h"
18 
19 #include "canvas/Persistency/Common/Ptr.h"
20 #include "canvas/Persistency/Common/Assns.h"
21 #include "canvas/Utilities/InputTag.h"
22 
23 #include "fhiclcpp/types/Atom.h"
24 #include "fhiclcpp/types/Sequence.h"
25 #include "fhiclcpp/types/Name.h"
26 #include "fhiclcpp/types/Comment.h"
27 #include "messagefacility/MessageLogger/MessageLogger.h"
28 
29 // C/C++ standard libraries
30 #include <utility> // std::move()
31 #include <memory> // std::make_unique()
32 
33 
34 namespace lar {
35  namespace test {
36 
37  // -------------------------------------------------------------------------
38  /**
39  * @brief Creates some dummy PFParticles and associations to clusters.
40  *
41  * Configuration parameters
42  * =========================
43  *
44  * * *clusters* (list of input tags): collections of the clusters to be
45  * used if PFParticles
46  * * *clustersPerPFO* (unsigned integer, default: 3): number of clusters
47  * combined into each PFParticle
48  *
49  */
50  class AssnsChainPFParticleMaker: public art::EDProducer {
51  public:
52 
53  struct Config {
54  using Name = fhicl::Name;
55  using Comment = fhicl::Comment;
56 
57  fhicl::Sequence<art::InputTag> clusters{
58  Name("clusters"),
59  Comment("collections of clusters to be combined")
60  };
61 
62  fhicl::Atom<unsigned int> clustersPerPFO{
63  Name("clustersPerPFO"),
64  Comment("number of clusters combined into each PFParticle"),
65  3
66  };
67 
68  }; // struct Config
69 
70  using Parameters = art::EDProducer::Table<Config>;
71 
72  explicit AssnsChainPFParticleMaker(Parameters const& config)
73  : EDProducer{config}
74  , clusterTags(config().clusters())
75  , nClustersPerPFO(config().clustersPerPFO())
76  {
77  produces<std::vector<recob::PFParticle>>();
78  produces<art::Assns<recob::Cluster, recob::PFParticle>>();
79  }
80 
81  virtual void produce(art::Event& event) override;
82 
83  private:
84  std::vector<art::InputTag> clusterTags; ///< List of cluster tags.
85  unsigned int nClustersPerPFO; ///< Maximum number of clusters per PFO.
86 
87  /// Returns a list of clusters to be combined.
88  std::vector<art::Ptr<recob::Cluster>> collectClusters
89  (art::Event const& event) const;
90 
91  }; // AssnsChainPFParticleMaker
92 
93  // -------------------------------------------------------------------------
94 
95 
96  } // namespace test
97 } // namespace lar
98 
99 
100 // -----------------------------------------------------------------------------
102 
103  //
104  // prepare input: merge all hits in a single collection
105  //
106  std::vector<art::Ptr<recob::Cluster>> clusters = collectClusters(event);
107 
108  //
109  // prepare output
110  //
111  auto PFOs = std::make_unique<std::vector<recob::PFParticle>>();
112  auto clusterPFOassns
113  = std::make_unique<art::Assns<recob::Cluster, recob::PFParticle>>();
114 
115  //
116  // create the PFParticles
117  //
118  unsigned int nPFOs = clusters.size() / nClustersPerPFO;
119  if (nPFOs * nClustersPerPFO < clusters.size()) ++nPFOs;
120 
121  art::PtrMaker<recob::PFParticle> ptrMaker(event);
122 
123  unsigned int nDaughtersPerParticle = 2;
124  unsigned int nParticlesInTier = 1;
125  std::size_t firstPFOinThisTier = 0;
126  std::size_t firstPFOinNextTier = firstPFOinThisTier + nParticlesInTier;
127  std::size_t nextDaughter = firstPFOinNextTier;
128  std::vector<std::size_t> parents
129  (nPFOs, std::size_t(recob::PFParticle::kPFParticlePrimary));
130  for (unsigned int i = 0; i < nPFOs; ++i) {
131 
132  // prepare for the next tier, if needed
133  if (i >= firstPFOinNextTier) {
134  firstPFOinThisTier = firstPFOinNextTier;
135 
136  nParticlesInTier *= nDaughtersPerParticle;
137  nDaughtersPerParticle += 1;
138  firstPFOinNextTier += nParticlesInTier;
139  } // if
140 
141  //
142  // assign clusters to PFO
143  //
144  std::vector<art::Ptr<recob::Cluster>> PFOclusters;
145  std::size_t iCluster = i;
146  while (iCluster < clusters.size()) {
147  PFOclusters.push_back(clusters[iCluster]);
148  iCluster += nPFOs;
149  } // while
150 
151  //
152  // generate the PFParticle
153  //
154  std::size_t const endDaughter
155  = std::min(nextDaughter + nDaughtersPerParticle, (std::size_t) nPFOs);
156  std::vector<std::size_t> daughters;
157  daughters.reserve(endDaughter - nextDaughter);
158  while (nextDaughter < endDaughter) {
159  parents[nextDaughter] = i;
160  daughters.push_back(nextDaughter);
161  ++nextDaughter;
162  } // while
163 
164  PFOs->emplace_back(
165  11, // pdgCode (11 = shower-like)
166  i, // self
167  parents[i], // parent
168  std::move(daughters)
169  );
170 
171  //
172  // generate associations
173  //
174  auto const PFOptr = ptrMaker(i); // art pointer to the new PFParticle
175  for (art::Ptr<recob::Cluster> const& cluster: PFOclusters) {
176  mf::LogVerbatim("AssnsChainPFParticleMaker")
177  << "Associating cluster " << cluster << " with PFO " << PFOptr;
178  clusterPFOassns->addSingle(cluster, PFOptr);
179  }
180 
181  } // for
182 
183  mf::LogInfo("AssnsChainPFParticleMaker")
184  << "Created " << PFOs->size() << " particle flow objects with about "
185  << nClustersPerPFO << " clusters each from " << clusters.size()
186  << " clusters and " << clusterPFOassns->size() << " associations from "
187  << clusterTags.size() << " collections";
188 
189  event.put(std::move(PFOs));
190  event.put(std::move(clusterPFOassns));
191 
192 } // lar::test::AssnsChainClusterMaker::produce()
193 
194 
195 // -----------------------------------------------------------------------------
196 std::vector<art::Ptr<recob::Cluster>>
198  (art::Event const& event) const
199 {
200 
201  std::vector<art::Ptr<recob::Cluster>> allClusters;
202 
203  for (auto const& tag: clusterTags) {
204  auto clusters = event.getValidHandle<std::vector<recob::Cluster>>(tag);
205 
206  std::size_t const nClusters = clusters->size();
207  for (std::size_t i = 0; i < nClusters; ++i)
208  allClusters.emplace_back(clusters, i);
209 
210  } // for
211 
212  return allClusters;
213 } // lar::test::AssnsChainPFParticleMaker::collectClusters()
214 
215 
216 // -----------------------------------------------------------------------------
217 DEFINE_ART_MODULE(lar::test::AssnsChainPFParticleMaker)
218 
219 // -----------------------------------------------------------------------------
std::vector< art::InputTag > clusterTags
List of cluster tags.
process_name cluster
Definition: cheaterreco.fcl:51
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Definition: PFParticle.h:61
unsigned int nClustersPerPFO
Maximum number of clusters per PFO.
std::vector< art::Ptr< recob::Cluster > > collectClusters(art::Event const &event) const
Returns a list of clusters to be combined.
BEGIN_PROLOG vertical distance to the surface Name
Declaration of cluster object.
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour clustersPerPFO
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
Creates some dummy PFParticles and associations to clusters.
virtual void produce(art::Event &event) override