AssnsChainClusterMaker_module.cc
Go to the documentation of this file.
1 /**
2  * @file AssnsChainClusterMaker_module.cc
3  * @brief Test producer creating a few dummy clusters associated with hits.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date June 23, 2017
6  */
7 
8 // LArSoft libraries
12 #include "larcoreobj/SimpleTypesAndConstants/geo_types.h" // geo namespace
13 
14 // framework libraries
21 #include "fhiclcpp/types/Atom.h"
23 #include "fhiclcpp/types/Name.h"
24 #include "fhiclcpp/types/Comment.h"
26 
27 // C/C++ standard libraries
28 #include <utility> // std::move()
29 #include <memory> // std::make_unique()
30 #include <cmath> // std::sqrt()
31 #include <numeric> // std::accumulate()
32 
33 
34 namespace lar {
35  namespace test {
36 
37  // -------------------------------------------------------------------------
38  /**
39  * @brief Creates some dummy clusters and associations to hits.
40  *
41  * Configuration parameters
42  * =========================
43  *
44  * * *hits* (list of input tags): collections of the hits to be clustered
45  * * *hitsPerCluster* (unsigned integer, default: 100): number of hits
46  * associated with each cluster
47  *
48  */
50  public:
51 
52  struct Config {
53  using Name = fhicl::Name;
55 
57  Name("hits"),
58  Comment("collections of hits to be clustered")
59  };
60 
62  Name("hitsPerCluster"),
63  Comment("number of hits associated with each cluster"),
64  100
65  };
66 
67  }; // struct Config
68 
70 
72  : EDProducer{config}, hitTags(config().hits())
74  {
75  produces<std::vector<recob::Cluster>>();
76  produces<art::Assns<recob::Hit, recob::Cluster>>();
77  }
78 
79  virtual void produce(art::Event& event) override;
80 
81  private:
82  std::vector<art::InputTag> hitTags; ///< List of hit tags for clustering.
83  unsigned int nHitsPerCluster; ///< Maximum number of hits per cluster.
84 
85  /// Returns a list of hits to be clustered.
86  std::vector<art::Ptr<recob::Hit>> collectHits
87  (art::Event const& event) const;
88 
89  }; // AssnsChainClusterMaker
90 
91  // -------------------------------------------------------------------------
92 
93 
94  } // namespace test
95 } // namespace lar
96 
97 
98 // -----------------------------------------------------------------------------
99 namespace {
100 
101  template <typename T>
102  inline T sqr(T v) { return v*v; }
103 
104 } // local namespace
105 
106 // -----------------------------------------------------------------------------
108 
109  //
110  // prepare input: merge all hits in a single collection
111  //
112  std::vector<art::Ptr<recob::Hit>> hits = collectHits(event);
113 
114  //
115  // prepare output
116  //
117  auto clusters = std::make_unique<std::vector<recob::Cluster>>();
118  auto hitClusterAssns
119  = std::make_unique<art::Assns<recob::Hit, recob::Cluster>>();
120 
121  //
122  // create the clusters
123  //
124  unsigned int nClusters = hits.size() / nHitsPerCluster;
125  if (nClusters * nHitsPerCluster < hits.size()) ++nClusters;
126 
127  art::PtrMaker<recob::Cluster> ptrMaker(event);
128 
129  for (unsigned int i = 0; i < nClusters; ++i) {
130 
131  //
132  // assign hits to cluster
133  //
134  std::vector<art::Ptr<recob::Hit>> clusterHits;
135  std::size_t iHit = i;
136  while (iHit < hits.size()) {
137  clusterHits.push_back(hits[iHit]);
138  iHit += nClusters;
139  } // while
140 
141  //
142  // generate the cluster
143  //
144  clusters->emplace_back(
145  float(clusterHits.front()->WireID().Wire), // start_wire
146  1.0, // sigma_start_wire
147  clusterHits.front()->PeakTime(), // start_tick
148  clusterHits.front()->SigmaPeakTime(), // sigma_start_tick
149  clusterHits.front()->Integral(), // start_charge
150  0.0, // start_angle
151  0.0, // start_opening
152  float(clusterHits.back()->WireID().Wire), // end_wire
153  1.0, // sigma_end_wire
154  clusterHits.back()->PeakTime(), // end_tick
155  clusterHits.back()->SigmaPeakTime(), // sigma_end_tick
156  clusterHits.back()->Integral(), // end_charge
157  0.0, // end_angle
158  0.0, // end_opening
159  std::accumulate(clusterHits.cbegin(), clusterHits.cend(), 0.0,
160  [](float sum, art::Ptr<recob::Hit> const& hit)
161  { return sum + hit->Integral(); }
162  ), // integral
163  std::sqrt(std::accumulate(clusterHits.cbegin(), clusterHits.cend(), 0.0,
164  [](float sum, art::Ptr<recob::Hit> const& hit)
165  { return sum + sqr(hit->SigmaIntegral()); }
166  )), // integral_stddev
167  std::accumulate(clusterHits.cbegin(), clusterHits.cend(), 0.0,
168  [](float sum, art::Ptr<recob::Hit> const& hit)
169  { return sum + hit->SummedADC(); }
170  ), // summedADC
171  std::sqrt(std::accumulate(clusterHits.cbegin(), clusterHits.cend(), 0.0,
172  [](float sum, art::Ptr<recob::Hit> const& hit)
173  { return sum + hit->SummedADC(); }
174  )), // summedADC_stddev
175  clusterHits.size(), // n_hits
176  0.0, // multiple_hit_density
177  2.0, // width
178  recob::Cluster::ID_t(i + 1), // ID
179  clusterHits.front()->View(), // view
180  clusterHits.front()->WireID().asPlaneID(), // plane
182  );
183 
184  //
185  // generate associations
186  //
187  auto const clusterPtr = ptrMaker(i); // art pointer to the new cluster
188  for (art::Ptr<recob::Hit> const& hit: clusterHits)
189  hitClusterAssns->addSingle(hit, clusterPtr);
190 
191  } // for
192 
193  mf::LogInfo("AssnsChainClusterMaker")
194  << "Created " << clusters->size() << " clusters with about "
195  << nHitsPerCluster << " hits each from " << hits.size() << " hits and "
196  << hitClusterAssns->size() << " associations from "
197  << hitTags.size() << " collections";
198 
199  event.put(std::move(clusters));
200  event.put(std::move(hitClusterAssns));
201 
202 } // lar::test::AssnsChainClusterMaker::produce()
203 
204 
205 // -----------------------------------------------------------------------------
206 std::vector<art::Ptr<recob::Hit>> lar::test::AssnsChainClusterMaker::collectHits
207  (art::Event const& event) const
208 {
209 
210  std::vector<art::Ptr<recob::Hit>> allHits;
211 
212  for (auto const& tag: hitTags) {
213  auto hits = event.getValidHandle<std::vector<recob::Hit>>(tag);
214 
215  std::size_t const nHits = hits->size();
216  for (std::size_t i = 0; i < nHits; ++i)
217  allHits.emplace_back(hits, i);
218 
219  } // for
220 
221  return allHits;
222 } // lar::test::AssnsChainClusterMaker::collectHits()
223 
224 
225 // -----------------------------------------------------------------------------
227 
228 // -----------------------------------------------------------------------------
std::vector< art::InputTag > hitTags
List of hit tags for clustering.
std::size_t size() const noexcept
Definition: SequenceBase.h:33
Creates some dummy clusters and associations to hits.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
ChannelGroupService::Name Name
std::vector< art::Ptr< recob::Hit > > collectHits(art::Event const &event) const
Returns a list of hits to be clustered.
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
T sqr(T v)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
static Config * config
Definition: config.cpp:1054
def move(depos, offset)
Definition: depos.py:107
virtual void produce(art::Event &event) override
Definition of data types for geometry description.
Detector simulation of raw signals on wires.
Declaration of signal hit object.
#define Comment
LArSoft-specific namespace.
unsigned int nHitsPerCluster
Maximum number of hits per cluster.
int ID_t
Type of cluster ID.
Definition: Cluster.h:74
Event finding and building.