20 #include "art/Framework/Core/EDAnalyzer.h"
21 #include "art/Framework/Principal/Event.h"
22 #include "art/Framework/Principal/Handle.h"
23 #include "art/Framework/Core/ModuleMacros.h"
25 #include "canvas/Persistency/Common/Ptr.h"
26 #include "canvas/Persistency/Common/Assns.h"
27 #include "canvas/Persistency/Provenance/ProductID.h"
28 #include "canvas/Utilities/InputTag.h"
30 #include "messagefacility/MessageLogger/MessageLogger.h"
31 #include "fhiclcpp/types/Atom.h"
32 #include "fhiclcpp/types/Name.h"
33 #include "fhiclcpp/types/Comment.h"
74 Comment(
"label of the shower collection to be explored")
79 Comment(
"how many associated hits to print per line"),
83 fhicl::Atom<unsigned int>
nHits {
85 Comment(
"total number of expected hits"),
90 Comment(
"total number of expected clusters"),
95 Comment(
"total number of expected particle flow objects"),
100 Comment(
"total number of expected showers"),
109 virtual void analyze(art::Event
const& event)
override;
119 template <
typename ShowerHandle>
121 (art::Event
const& event, ShowerHandle
const& showers)
const;
123 template <
typename ShowerHandle>
125 (art::Event
const& event, ShowerHandle
const& showers)
const;
127 template <
typename ShowerHandle>
129 (art::Event
const& event, ShowerHandle
const& showers)
const;
142 : art::EDAnalyzer(config)
143 , showerTag(config().showers())
144 , nObjectsPerLine(config().hitsPerLine())
145 , nShowers(config().nShowers())
146 , nPFOs(config().nParticles())
147 , nClusters(config().nClusters())
148 , nHits(config().nHits())
158 auto showers =
event.getValidHandle<std::vector<recob::Shower>>(showerTag);
159 mf::LogVerbatim(
"AssnsChainTest") <<
event.id() <<
" contains "
160 << showers->size() <<
" showers from '" << showerTag.encode() <<
"'";
162 if (showers->size() != nShowers) {
163 throw cet::exception(
"AssnsChainTest")
164 <<
"Data product '" << showerTag.encode() <<
"' contains "
165 << showers->size() <<
" showers, " << nShowers <<
" were expected.\n";
168 mf::LogVerbatim(
"AssnsChainTest") <<
"\nPrinting: shower particle";
169 printAssociatedPFOs(event, showers);
171 mf::LogVerbatim(
"AssnsChainTest") <<
"\nPrinting: shower clusters";
172 printAssociatedClusters(event, showers);
174 mf::LogVerbatim(
"AssnsChainTest") <<
"\nPrinting: shower hits";
175 printAssociatedHits(event, showers);
181 template <
typename ShowerHandle>
183 (art::Event
const& event, ShowerHandle
const& showers)
const
190 showerHits(showers, event, showerTag);
191 assert(showerHits.
size() == showers->size());
197 std::set<art::Ptr<recob::Hit>> foundHits;
198 std::set<art::ProductID> foundHitProducts;
200 unsigned int const pageSize = nObjectsPerLine;
201 mf::LogVerbatim log(
"AssnsChainTest");
202 for (std::size_t iShower = 0; iShower < showers->size(); ++iShower) {
203 auto const& hits = showerHits.
at(iShower);
204 log <<
"\n #" << iShower <<
": " << hits.size() <<
" hits";
205 if (hits.empty())
continue;
207 unsigned int hitsLeft = pageSize;
208 for (art::Ptr<recob::Hit>
const&
hit: hits) {
209 if (foundHits.count(
hit) == 0) {
210 foundHits.insert(
hit);
211 foundHitProducts.insert(
hit.id());
214 mf::LogProblem(
"AssnsChainTest")
215 <<
"ERROR: Hit " <<
hit <<
" appears in more than one shower!";
218 if (hitsLeft-- == 0) {
227 mf::LogVerbatim(
"AssnsChainTest")
228 << foundHits.size() <<
" hits collected for "
229 << showers->size() <<
" showers ('"
230 << showers.provenance()->inputTag().encode() <<
"') from "
231 << foundHitProducts.size() <<
" data products:";
232 for (art::ProductID
const& PID: foundHitProducts) {
233 art::Handle<std::vector<recob::Hit>> hits;
234 if (event.get(PID, hits)) {
235 mf::LogVerbatim(
"AssnsChainTest") <<
" - '"
236 << hits.provenance()->inputTag().encode() <<
"' (contains "
237 << hits->size() <<
" hits)";
240 mf::LogVerbatim(
"AssnsChainTest") <<
" - <" << PID <<
"> (not found!)";
244 if (nDuplicates > 0) {
245 throw cet::exception(
"AssnsChainTest")
246 <<
"Test failed: " << nDuplicates
247 <<
" hits appear in more than one shower.\n";
249 if (foundHits.size() != nHits) {
250 throw cet::exception(
"AssnsChainTest")
251 <<
"Test failed: counted " << foundHits.size()
252 <<
" hits, expected " << nHits <<
".\n";
259 template <
typename ShowerHandle>
261 (art::Event
const& event, ShowerHandle
const& showers)
const
263 std::string
const objectsDesc =
"clusters";
269 (showers, event, showerTag);
270 assert(showerObjects.
size() == showers->size());
272 using ObjectPtr_t = decltype(showerObjects)::TargetPtr_t;
278 std::set<art::Ptr<recob::Cluster>> foundObjects;
279 std::set<art::ProductID> foundObjectProducts;
281 unsigned int const pageSize = nObjectsPerLine;
282 mf::LogVerbatim log(
"AssnsChainTest");
283 for (std::size_t iShower = 0; iShower < showers->size(); ++iShower) {
284 auto const& objects = showerObjects.
at(iShower);
285 log <<
"\n #" << iShower <<
": " << objects.size() <<
" " << objectsDesc;
286 if (objects.empty())
continue;
288 unsigned int objectsLeft = pageSize;
289 for (ObjectPtr_t
const&
object: objects) {
290 if (foundObjects.count(
object) == 0) {
291 foundObjects.insert(
object);
292 foundObjectProducts.insert(
object.
id());
295 mf::LogProblem(
"AssnsChainTest")
296 <<
"ERROR: Cluster " <<
object <<
" appears in more than one shower!";
299 if (objectsLeft-- == 0) {
300 objectsLeft = pageSize;
303 log <<
" " << object;
308 mf::LogVerbatim(
"AssnsChainTest")
309 << foundObjects.size() <<
" " << objectsDesc <<
" collected for "
310 << showers->size() <<
" showers ('"
311 << showers.provenance()->inputTag().encode() <<
"') from "
312 << foundObjectProducts.size() <<
" data products:";
313 for (art::ProductID
const& PID: foundObjectProducts) {
314 art::Handle<std::vector<recob::Cluster>> objects;
315 if (event.get(PID, objects)) {
316 mf::LogVerbatim(
"AssnsChainTest") <<
" - '"
317 << objects.provenance()->inputTag().encode() <<
"' (contains "
318 << objects->size() <<
" " << objectsDesc <<
")";
321 mf::LogVerbatim(
"AssnsChainTest") <<
" - <" << PID <<
"> (not found!)";
325 if (nDuplicates > 0) {
326 throw cet::exception(
"AssnsChainTest")
327 <<
"Test failed: " << nDuplicates
328 <<
" clusters appear in more than one shower.\n";
330 if (foundObjects.size() != nClusters) {
331 throw cet::exception(
"AssnsChainTest")
332 <<
"Test failed: counted " << foundObjects.size()
333 <<
" clusters, expected " << nClusters <<
".\n";
340 template <
typename ShowerHandle>
342 (art::Event
const& event, ShowerHandle
const& showers)
const
344 std::string
const objectsDesc =
"particle flow objects";
350 (showers, event, showerTag);
351 assert(showerObjects.
size() == showers->size());
353 using ObjectPtr_t = decltype(showerObjects)::TargetPtr_t;
359 std::set<art::Ptr<recob::PFParticle>> foundObjects;
360 std::set<art::ProductID> foundObjectProducts;
362 unsigned int const pageSize = nObjectsPerLine;
363 mf::LogVerbatim log(
"AssnsChainTest");
364 for (std::size_t iShower = 0; iShower < showers->size(); ++iShower) {
365 auto const& objects = showerObjects.
at(iShower);
366 log <<
"\n #" << iShower <<
": " << objects.size() <<
" " << objectsDesc;
368 unsigned int objectsLeft = pageSize;
369 for (ObjectPtr_t
const&
object: objects) {
370 if (foundObjects.count(
object) == 0) {
371 foundObjects.insert(
object);
372 foundObjectProducts.insert(
object.
id());
375 mf::LogProblem(
"AssnsChainTest")
376 <<
"ERROR: Particle " <<
object
377 <<
" appears in more than one shower!";
380 if (objectsLeft-- == 0) {
381 objectsLeft = pageSize;
384 log <<
" " << object;
387 if (objects.size() != 1) {
388 throw cet::exception(
"AssnsChainTest")
389 <<
"all showers are expected to have one PFParticle associated, while #"
390 << iShower <<
" has " << objects.size() <<
"\n";
395 mf::LogVerbatim(
"AssnsChainTest")
396 << foundObjects.size() <<
" " << objectsDesc <<
" collected for "
397 << showers->size() <<
" showers ('"
398 << showers.provenance()->inputTag().encode() <<
"') from "
399 << foundObjectProducts.size() <<
" data products:";
400 for (art::ProductID
const& PID: foundObjectProducts) {
401 art::Handle<std::vector<recob::PFParticle>> objects;
402 if (event.get(PID, objects)) {
403 mf::LogVerbatim(
"AssnsChainTest") <<
" - '"
404 << objects.provenance()->inputTag().encode() <<
"' (contains "
405 << objects->size() <<
" " << objectsDesc <<
")";
408 mf::LogVerbatim(
"AssnsChainTest") <<
" - <" << PID <<
"> (not found!)";
412 if (nDuplicates > 0) {
413 throw cet::exception(
"AssnsChainTest")
414 <<
"Test failed: " << nDuplicates
415 <<
" particle flow objects appear in more than one shower.\n";
417 if (foundObjects.size() != nPFOs) {
418 throw cet::exception(
"AssnsChainTest")
419 <<
"Test failed: counted " << foundObjects.size()
420 <<
" particle flow objects, expected " << nPFOs <<
".\n";
Utility to navigate chains of associations.
void printAssociatedHits(art::Event const &event, ShowerHandle const &showers) const
unsigned int nShowers
Total number of expected showers.
Declaration of signal hit object.
TargetPtrCollection_t const & at(std::size_t i) const
Returns all the Target objects associated to specified object.
fhicl::Atom< art::InputTag > showers
fhicl::Atom< unsigned int > nShowers
Prints all the hits associated to the specified shower.
unsigned int nPFOs
Total number of expected particles.
art::EDAnalyzer::Table< Config > Parameters
fhicl::Atom< unsigned int > nParticles
BEGIN_PROLOG vertical distance to the surface Name
Declaration of cluster object.
Query object collecting a list of associated objects.
unsigned int nHits
Total number of expected hits.
std::size_t size() const noexcept
Returns the number of Source objects we have information about.
fhicl::Atom< unsigned int > nClusters
unsigned int nClusters
Total number of expected clusters.
fhicl::Atom< unsigned int > nHits
art::InputTag showerTag
Label of the input collection of showers.
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
virtual void analyze(art::Event const &event) override
AssnsChainTest(Parameters const &config)
unsigned int nObjectsPerLine
Number of objects to print on one line.
void printAssociatedPFOs(art::Event const &event, ShowerHandle const &showers) const
void printAssociatedClusters(art::Event const &event, ShowerHandle const &showers) const
fhicl::Atom< unsigned int > hitsPerLine