LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArPandoraEvent.h
Go to the documentation of this file.
1 
7 #ifndef LAR_PANDORA_EVENT_H
8 #define LAR_PANDORA_EVENT_H 1
9 
11 
13 
25 
26 namespace art {
27  class EDProducer;
28 }
33 
34 #include <algorithm>
35 #include <map>
36 #include <memory>
37 #include <string>
38 #include <utility> // std::pair<>
39 
40 namespace lar_pandora {
41 
46  public:
50  template <typename T>
51  using Collection = std::vector<art::Ptr<T>>;
52 
53  template <typename R, typename D>
54  using PairVector = std::vector<std::pair<art::Ptr<R>, D>>;
55 
59  template <typename L, typename R, typename D>
60  using Association = std::map<art::Ptr<L>, PairVector<R, D>>;
61 
62  // Collection typedef specializations
74 
75  // Association typedef specializations
86 
93 
97  class Labels {
98  public:
102  enum LabelType {
128  ShowerToPCAxisLabel
129  };
130 
135  Labels(const std::string& pfParticleProducerLabel, const std::string& hitProducerLabel);
136 
142  Labels(const std::string& pfParticleProducerLabel,
143  const std::string& trackProducerLabel,
144  const std::string& showerProducerLabel,
145  const std::string& hitProducerLabel);
146 
154  const std::string& GetLabel(const LabelType type) const;
155 
162  void SetLabel(const LabelType type, const std::string& label);
163 
164  private:
165  std::map<LabelType, std::string> m_labels;
166  };
167 
176  LArPandoraEvent(art::EDProducer* pProducer,
177  art::Event* pEvent,
178  const Labels& inputLabels,
179  const bool shouldProduceT0s = false);
180 
188  LArPandoraEvent(const LArPandoraEvent& event, const PFParticleVector& selectedPFParticles);
189 
193  void WriteToEvent() const;
194 
195  private:
199  void GetCollections();
200 
207  template <typename T>
208  void GetCollection(const Labels::LabelType& inputLabel, Collection<T>& outputCollection) const;
209 
217  template <typename L, typename R, typename D>
218  void GetAssociationMap(const Collection<L>& collectionL,
219  const Labels::LabelType& inputLabel,
220  Association<L, R, D>& outputAssociationMap) const;
221 
229  template <typename L, typename R>
230  void GetAssociationMap(const Collection<L>& collectionL,
231  const Labels::LabelType& inputLabel,
232  Association<L, R, void*>& outputAssociationMap) const;
233 
241  template <typename L, typename R, typename D>
242  void CollectAssociated(const art::Ptr<L>& anObject,
243  const Association<L, R, D>& associationLtoR,
244  Collection<R>& associatedR) const;
245 
256  template <typename L, typename R, typename D>
257  void GetFilteredAssociationMap(const Collection<L>& collectionL,
258  const Collection<R>& collectionR,
259  const Association<L, R, D>& inputAssociationLtoR,
260  Association<L, R, D>& outputAssociationLtoR) const;
261 
267  template <typename T>
268  void WriteCollection(const Collection<T>& collection) const;
269 
278  template <typename L, typename R, typename D>
279  void WriteAssociation(const Association<L, R, D>& associationMap,
280  const Collection<L>& collectionL,
281  const Collection<R>& collectionR,
282  const bool thisProducesR = true) const;
283 
292  template <typename L, typename R>
293  void WriteAssociation(const Association<L, R, void*>& associationMap,
294  const Collection<L>& collectionL,
295  const Collection<R>& collectionR,
296  const bool thisProducesR = true) const;
297 
306  template <typename T>
307  size_t GetIndex(const art::Ptr<T> object, const Collection<T>& collection) const;
308 
313  bool
315 
316  // Collections
317  PFParticleCollection m_pfParticles;
318  SpacePointCollection m_spacePoints;
319  ClusterCollection m_clusters;
320  VertexCollection m_vertices;
321  SliceCollection m_slices;
322  TrackCollection m_tracks;
323  ShowerCollection m_showers;
324  T0Collection m_t0s;
325  PFParticleMetadataCollection m_metadata;
326  PCAxisCollection m_pcAxes;
327  HitCollection m_hits;
328 
329  // Association maps
330  PFParticleToSpacePointAssoc
332  PFParticleToClusterAssoc
334  PFParticleToVertexAssoc
336  PFParticleToSliceAssoc m_pfParticleSliceMap;
337  PFParticleToTrackAssoc m_pfParticleTrackMap;
338  PFParticleToShowerAssoc
340  PFParticleToT0Assoc m_pfParticleT0Map;
343  PFParticleToPCAxisAssoc
345  SpacePointToHitAssoc m_spacePointHitMap;
346  ClusterToHitAssoc m_clusterHitMap;
347  SliceToHitAssoc m_sliceHitMap;
348  TrackToHitAssoc m_trackHitMap;
349  ShowerToHitAssoc m_showerHitMap;
350  ShowerToPCAxisAssoc m_showerPCAxisMap;
351  };
352 
353  //------------------------------------------------------------------------------------------------------------------------------------------
354 
355  template <typename T>
356  inline void LArPandoraEvent::GetCollection(const Labels::LabelType& inputLabel,
357  Collection<T>& outputCollection) const
358  {
359  const auto& handle(m_pEvent->getValidHandle<std::vector<T>>(m_labels.GetLabel(inputLabel)));
360 
361  for (unsigned int i = 0; i != handle->size(); i++)
362  outputCollection.emplace_back(handle, i);
363  }
364 
365  //------------------------------------------------------------------------------------------------------------------------------------------
366 
367  template <typename L, typename R, typename D>
368  inline void LArPandoraEvent::GetAssociationMap(const Collection<L>& collectionL,
369  const Labels::LabelType& inputLabel,
370  Association<L, R, D>& outputAssociationMap) const
371  {
372  const auto& assocHandle(
373  m_pEvent->getValidHandle<art::Assns<L, R, D>>(m_labels.GetLabel(inputLabel)));
374 
375  // Check that there are no associaions from objects not in collectionL
376  for (const auto& entry : *assocHandle) {
377  auto it(std::find(collectionL.begin(), collectionL.end(), entry.first));
378  if (it == collectionL.end())
379  throw cet::exception("LArPandora") << " LArPandoraEvent::GetAssociationMap -- Found object "
380  "in association that isn't in the supplied collection"
381  << std::endl;
382  }
383 
384  // Ensure there is an entry for every object of type L
385  for (const auto& objectL : collectionL)
386  outputAssociationMap[objectL];
387 
388  // Fill the association map
389  for (const auto& entry : *assocHandle)
390  outputAssociationMap.at(entry.first).emplace_back(entry.second, *entry.data);
391  }
392 
393  //------------------------------------------------------------------------------------------------------------------------------------------
394 
395  template <typename L, typename R>
396  inline void LArPandoraEvent::GetAssociationMap(
397  const Collection<L>& collectionL,
398  const Labels::LabelType& inputLabel,
399  Association<L, R, void*>& outputAssociationMap) const
400  {
401  const auto& assocHandle(
402  m_pEvent->getValidHandle<art::Assns<L, R>>(m_labels.GetLabel(inputLabel)));
403 
404  // Check that there are no associaions from objects not in collectionL
405  for (const auto& entry : *assocHandle) {
406  auto it(std::find(collectionL.begin(), collectionL.end(), entry.first));
407  if (it == collectionL.end())
408  throw cet::exception("LArPandora") << " LArPandoraEvent::GetAssociationMap -- Found object "
409  "in association that isn't in the supplied collection"
410  << std::endl;
411  }
412 
413  // Ensure there is an entry for every object of type L
414  for (const auto& objectL : collectionL)
415  outputAssociationMap[objectL];
416 
417  // Fill the association map
418  for (const auto& entry : *assocHandle)
419  outputAssociationMap.at(entry.first).emplace_back(entry.second, nullptr);
420  }
421 
422  //------------------------------------------------------------------------------------------------------------------------------------------
423 
424  template <typename L, typename R, typename D>
425  inline void LArPandoraEvent::CollectAssociated(const art::Ptr<L>& anObject,
426  const Association<L, R, D>& associationLtoR,
427  Collection<R>& associatedR) const
428  {
429  if (associationLtoR.find(anObject) == associationLtoR.end())
430  throw cet::exception("LArPandora")
431  << " LArPandoraEvent::CollectAssociated -- Can not find association for object supplied."
432  << std::endl;
433 
434  for (const auto& entry : associationLtoR.at(anObject)) {
435  // Ensure we don't repeat objects in the output collection
436  if (std::find(associatedR.begin(), associatedR.end(), entry.first) == associatedR.end())
437  associatedR.push_back(entry.first);
438  }
439  }
440 
441  //------------------------------------------------------------------------------------------------------------------------------------------
442 
443  template <typename L, typename R, typename D>
444  inline void LArPandoraEvent::GetFilteredAssociationMap(
445  const Collection<L>& collectionL,
446  const Collection<R>& collectionR,
447  const Association<L, R, D>& inputAssociationLtoR,
448  Association<L, R, D>& outputAssociationLtoR) const
449  {
450  for (const auto& objectL : collectionL) {
451  if (inputAssociationLtoR.find(objectL) == inputAssociationLtoR.end())
452  throw cet::exception("LArPandora")
453  << " LArPandoraEvent::GetFilteredAssociationMap -- Can not find association for object "
454  "in supplied collection."
455  << std::endl;
456 
457  if (outputAssociationLtoR.find(objectL) != outputAssociationLtoR.end())
458  throw cet::exception("LArPandora")
459  << " LArPandoraEvent::GetFilteredAssociationMap -- Repeated objects in input collectionL"
460  << std::endl;
461 
462  for (const auto& entry : inputAssociationLtoR.at(objectL)) {
463  if (std::find(collectionR.begin(), collectionR.end(), entry.first) == collectionR.end())
464  continue;
465 
466  outputAssociationLtoR[objectL].push_back(entry);
467  }
468  }
469  }
470 
471  //------------------------------------------------------------------------------------------------------------------------------------------
472 
473  template <typename T>
474  inline void LArPandoraEvent::WriteCollection(const Collection<T>& collection) const
475  {
476  std::unique_ptr<std::vector<T>> output(new std::vector<T>);
477 
478  for (const auto& object : collection)
479  output->push_back(*object);
480 
481  m_pEvent->put(std::move(output));
482  }
483 
484  //------------------------------------------------------------------------------------------------------------------------------------------
485 
486  template <typename L, typename R, typename D>
487  inline void LArPandoraEvent::WriteAssociation(const Association<L, R, D>& associationMap,
488  const Collection<L>& collectionL,
489  const Collection<R>& collectionR,
490  const bool thisProducesR) const
491  {
492  // The output assocation to populate
493  std::unique_ptr<art::Assns<L, R, D>> outputAssn(new art::Assns<L, R, D>);
494 
495  // NB. The art::Ptrs in the stored collections refer to the producer that originally created the objects (e.g. Pandora pat-rec). To make
496  // correct associations, we need to make new art::Ptrs to refer to the *copies* of the objects made by this producer. This is done using
497  // the PtrMaker utility.
498  const art::PtrMaker<L> makePtrL(*m_pEvent);
499 
500  for (auto it = associationMap.begin(); it != associationMap.end(); ++it) {
501  const auto indexL(this->GetIndex(it->first, collectionL));
502  const auto outputPtrL(makePtrL(indexL));
503 
504  for (const auto& entry : it->second) {
505  const auto& objectR(entry.first);
506  const auto& objectD(entry.second);
507 
508  if (thisProducesR) {
509  const art::PtrMaker<R> makePtrR(*m_pEvent);
510  const auto indexR(this->GetIndex(objectR, collectionR));
511  outputAssn->addSingle(outputPtrL, makePtrR(indexR), objectD);
512  }
513  else {
514  outputAssn->addSingle(outputPtrL, objectR, objectD);
515  }
516  }
517  }
518 
519  m_pEvent->put(std::move(outputAssn));
520  }
521 
522  //------------------------------------------------------------------------------------------------------------------------------------------
523 
524  template <typename L, typename R>
525  inline void LArPandoraEvent::WriteAssociation(const Association<L, R, void*>& associationMap,
526  const Collection<L>& collectionL,
527  const Collection<R>& collectionR,
528  const bool thisProducesR) const
529  {
530  // The output assocation to populate
531  std::unique_ptr<art::Assns<L, R>> outputAssn(new art::Assns<L, R>);
532 
533  // NB. The art::Ptrs in the stored collections refer to the producer that originally created the objects (e.g. Pandora pat-rec). To make
534  // correct associations, we need to make new art::Ptrs to refer to the *copies* of the objects made by this producer. This is done using
535  // the PtrMaker utility.
536  const art::PtrMaker<L> makePtrL(*m_pEvent);
537 
538  for (auto it = associationMap.begin(); it != associationMap.end(); ++it) {
539  const auto indexL(this->GetIndex(it->first, collectionL));
540  const auto outputPtrL(makePtrL(indexL));
541 
542  for (const auto& entry : it->second) {
543  const auto& objectR(entry.first);
544 
545  if (thisProducesR) {
546  const art::PtrMaker<R> makePtrR(*m_pEvent);
547  const auto indexR(this->GetIndex(objectR, collectionR));
548  outputAssn->addSingle(outputPtrL, makePtrR(indexR));
549  }
550  else {
551  outputAssn->addSingle(outputPtrL, objectR);
552  }
553  }
554  }
555 
556  m_pEvent->put(std::move(outputAssn));
557  }
558 
559  //------------------------------------------------------------------------------------------------------------------------------------------
560 
561  template <typename T>
562  inline size_t LArPandoraEvent::GetIndex(const art::Ptr<T> object,
563  const Collection<T>& collection) const
564  {
565  const auto it(std::find(collection.begin(), collection.end(), object));
566  if (it == collection.end())
567  throw cet::exception("LArPandora")
568  << " LArPandoraEvent::GetIndex -- Can't find input object in the supplied collection."
569  << std::endl;
570 
571  return static_cast<size_t>(std::distance(collection.begin(), it));
572  }
573 
574 } // namespace lar_pandora
575 
576 #endif // #ifndef LAR_PANDORA_EVENT_H
Association< recob::PFParticle, recob::PCAxis, void * > PFParticleToPCAxisAssoc
HitCollection m_hits
The input collection of Hits.
PFParticleToVertexAssoc m_pfParticleVertexMap
The input associations: PFParticle -> Vertex.
Collection< recob::Cluster > ClusterCollection
LArPandoraEvent class.
ClusterCollection m_clusters
The input collection of Clusters.
T0Collection m_t0s
The input collection of T0s.
SliceToHitAssoc m_sliceHitMap
The input associations: Slice -> Hit.
SpacePointToHitAssoc m_spacePointHitMap
The input associations: SpacePoint -> Hit.
Declaration of signal hit object.
Association< recob::Cluster, recob::Hit, void * > ClusterToHitAssoc
Association< recob::PFParticle, recob::SpacePoint, void * > PFParticleToSpacePointAssoc
PFParticleToTrackAssoc m_pfParticleTrackMap
The input associations: PFParticle -> Track.
Collection< larpandoraobj::PFParticleMetadata > PFParticleMetadataCollection
PFParticleToClusterAssoc m_pfParticleClusterMap
The input associations: PFParticle -> Cluster.
PFParticleToPCAxisAssoc m_pfParticlePCAxisMap
The input associations: PFParticle -> PCAxis.
Class to keep data related to recob::Hit associated with recob::Track.
Association< recob::Shower, recob::PCAxis, void * > ShowerToPCAxisAssoc
Association< recob::PFParticle, recob::Track, void * > PFParticleToTrackAssoc
PCAxisCollection m_pcAxes
The input collection of PCAxes.
PFParticleCollection m_pfParticles
The input collection of PFParticles.
ClusterToHitAssoc m_clusterHitMap
The input associations: Cluster -> Hit.
Association< recob::Slice, recob::Hit, void * > SliceToHitAssoc
Collection< recob::PCAxis > PCAxisCollection
Association< recob::Track, recob::Hit, recob::TrackHitMeta > TrackToHitAssoc
PFParticleToPFParticleMetadataAssoc m_pfParticleMetadataMap
The input associations: PFParticle -> Metadata.
Collection< recob::SpacePoint > SpacePointCollection
Collection< recob::Hit > HitCollection
SpacePointCollection m_spacePoints
The input collection of SpacePoints.
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
ShowerToHitAssoc m_showerHitMap
The input associations: Shower -> Hit.
Association< recob::PFParticle, anab::T0, void * > PFParticleToT0Assoc
std::vector< art::Ptr< T >> Collection
Shorthand for a collection of objects of type T.
Collection< anab::T0 > T0Collection
Provides recob::Track data product.
Association< recob::SpacePoint, recob::Hit, void * > SpacePointToHitAssoc
art::Event * m_pEvent
The event to consider.
PFParticleToT0Assoc m_pfParticleT0Map
The input associations: PFParticle -> T0.
Association< recob::PFParticle, recob::Shower, void * > PFParticleToShowerAssoc
Declaration of cluster object.
Association< recob::PFParticle, recob::Vertex, void * > PFParticleToVertexAssoc
Association< recob::PFParticle, larpandoraobj::PFParticleMetadata, void * > PFParticleToPFParticleMetadataAssoc
Collection< recob::Slice > SliceCollection
Collection< recob::Shower > ShowerCollection
PFParticleToSliceAssoc m_pfParticleSliceMap
The input associations: PFParticle -> Slice.
ShowerToPCAxisAssoc m_showerPCAxisMap
The input associations: PCAxis -> Shower.
art::EDProducer * m_pProducer
The producer which should write the output collections and associations.
Association< recob::Shower, recob::Hit, void * > ShowerToHitAssoc
Association< recob::PFParticle, recob::Cluster, void * > PFParticleToClusterAssoc
Class to handle the required producer labels.
TrackToHitAssoc m_trackHitMap
The input associations: Track -> Hit.
std::vector< std::pair< art::Ptr< R >, D >> PairVector
SliceCollection m_slices
The input collection of Slices.
PFParticleToShowerAssoc m_pfParticleShowerMap
The input associations: PFParticle -> Shower.
Definition: MVAAlg.h:12
Labels m_labels
A set of labels describing the producers for each input collection.
std::map< art::Ptr< L >, PairVector< R, D >> Association
General purpose short-hand with optional D parameter.
Collection< recob::PFParticle > PFParticleCollection
Collection< recob::Vertex > VertexCollection
VertexCollection m_vertices
The input collection of Vertices.
helper function for LArPandoraInterface producer module
ShowerCollection m_showers
The input collection of Showers.
PFParticleMetadataCollection m_metadata
The input collection of PFParticle metadata.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Event finding and building.
TrackCollection m_tracks
The input collection of Tracks.
Collection< recob::Track > TrackCollection
Association< recob::PFParticle, recob::Slice, void * > PFParticleToSliceAssoc
std::map< LabelType, std::string > m_labels
Map holding the labels.
PFParticleToSpacePointAssoc m_pfParticleSpacePointMap
The input associations: PFParticle -> SpacePoint.
bool m_shouldProduceT0s
If T0s should be produced (usually only true for use cases with multiple drift volumes) ...