LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
AssociationUtil.h
Go to the documentation of this file.
1 
72 #ifndef ASSOCIATIONUTIL_H
73 #define ASSOCIATIONUTIL_H
74 
75 // C/C++ standard libraries
76 #include <climits>
77 #include <memory>
78 #include <string>
79 #include <utility> // std::move(), std::pair<>
80 #include <vector>
81 
82 // framework libraries
94 
95 namespace util {
96 
97  // see https://cdcvs.fnal.gov/redmine/projects/art/wiki/Inter-Product_References
98  // for information about using art::Assns
99 
154  // MARK CreateAssn_01
155  template <class T, class U>
156  bool CreateAssn(art::Event& evt,
157  std::vector<T> const& a,
158  art::Ptr<U> const& b,
159  art::Assns<U, T>& assn,
160  std::string a_instance,
161  size_t index = UINT_MAX);
162 
209  // MARK CreateAssn_02
210  template <class T, class U>
211  inline bool CreateAssn(art::Event& evt,
212  std::vector<T> const& a,
213  art::Ptr<U> const& b,
214  art::Assns<U, T>& assn,
215  size_t index = UINT_MAX)
216  {
217  return CreateAssn(evt, a, b, assn, std::string(), index);
218  }
219 
233  // MARK CreateAssn_03
234  template <class T, class U>
235  bool CreateAssn(art::Event& evt,
236  art::Ptr<T> const& a,
237  art::Ptr<U> const& b,
238  art::Assns<U, T>& assn);
239 
257  // MARK CreateAssn_04
258  template <class T, class U>
259  bool CreateAssn(art::Event& evt,
260  std::vector<T> const& a,
261  art::PtrVector<U> const& b,
262  art::Assns<T, U>& assn,
263  size_t index = UINT_MAX);
264 
280  // method to create a 1 to many association, with the many being of type U
281  // index is the location in the input std::vector<T> of the object you wish to
282  // associate with the art::PtrVector<U>
283  // MARK CreateAssn_05
284  template <class T, class U>
285  bool CreateAssn(art::Event& evt,
286  art::Ptr<T> const& a,
287  std::vector<art::Ptr<U>> const& b,
288  art::Assns<T, U>& assn);
289 
307  // MARK CreateAssn_06
308  template <class T, class U>
309  bool CreateAssn(art::Event& evt,
310  std::vector<T> const& a,
311  std::vector<art::Ptr<U>> const& b,
312  art::Assns<T, U>& assn,
313  size_t index = UINT_MAX);
314 
341  // MARK CreateAssn_07
342  template <class T, class U>
343  bool CreateAssn(art::Event& evt,
344  std::vector<T> const& a,
345  std::vector<U> const& b,
346  art::Assns<T, U>& assn,
347  size_t startU,
348  size_t endU,
349  size_t index = UINT_MAX);
350 
376  // MARK CreateAssn_07a
377  template <class T, class U>
378  bool CreateAssn(art::Event& evt,
379  std::vector<T> const& a,
380  std::vector<U> const& b,
381  art::Assns<T, U>& assn,
382  std::vector<size_t> const& indices,
383  size_t index = UINT_MAX);
384 
422  // MARK CreateAssn_08
423  template <typename T, typename U, typename Iter>
424  bool CreateAssn(art::Event& evt,
425  art::Assns<T, U>& assn,
426  size_t first_index,
427  Iter from_second_index,
428  Iter to_second_index);
429 
431 
484  // MARK CreateAssnD_01
485  // MARK CreateAssnD_01a
486  template <typename T, typename U, typename D>
487  bool CreateAssnD(art::Event& evt,
488  art::Assns<T, U, D>& assn,
489  size_t first_index,
490  size_t second_index,
491  typename art::Assns<T, U, D>::data_t&& data);
492  // MARK CreateAssnD_01b
493  template <typename T, typename U, typename D>
494  bool CreateAssnD(art::Event& evt,
495  art::Assns<T, U, D>& assn,
496  size_t first_index,
497  size_t second_index,
498  typename art::Assns<T, U, D>::data_t const& data);
500 
501  // method to return all objects of type U that are not associated to
502  // objects of type T. Label is the module label that would have produced
503  // the associations and likely the objects of type T
504  // this method assumes there is a one to many relationship between T and U
505  // for example if you want to get all recob::Hits
506  // that are not associated to recob::Clusters
507  // std::vector<const recob::Hit*> hits = FindUNotAssociatedToU<recob::Cluster>(art::Handle<recob::Hit>, ...);
508  template <class T, class U>
509  std::vector<const U*> FindUNotAssociatedToT(art::Handle<U> b,
510  art::Event const& evt,
511  std::string const& label);
512 
513  // method to return all objects of type U that are not associated to
514  // objects of type T. Label is the module label that would have produced
515  // the associations and likely the objects of type T
516  // this method assumes there is a one to many relationship between T and U
517  // for example if you want to get all recob::Hits
518  // that are not associated to recob::Clusters
519  // std::vector< art::Ptr<recob::Hit> > hits = FindUNotAssociatedToTP<recob::Cluster>(art::Handle<recob::Hit>, ...);
520  template <class T, class U>
521  std::vector<art::Ptr<U>> FindUNotAssociatedToTP(art::Handle<U> b,
522  art::Event const& evt,
523  std::string const& label);
524 
525  // Methods make getting simple ART-independent association information.
526  // --- GetAssociatedVectorOneI takes in a handle to an association, and a handle to a product on the event.
527  // The ouput is a vector of with the same number of entries as the handle to the product, containing an index
528  // to the location of one associated product in that product's collection.
529  // --- GetAssociatedVectorOneP takes in a handle to an association, and a handle to a product on the event.
530  // The ouput is a vector of with the same number of entries as the handle to the product, containing a pointer
531  // to one associated product.
532  // --- GetAssociatedVectorManyI takes in a handle to an association, and a handle to a product on the event.
533  // The ouput is a vector of with the same number of entries as the handle to the product, containing a vector
534  // of indices that give the locations of all associated products in those products' collection.
535  // --- GetAssociatedVectorManyP takes in a handle to an association, and a handle to a product on the event.
536  // The ouput is a vector of with the same number of entries as the handle to the product, containing a vector
537  // of pointers to all associated products.
538 
539  template <class T, class U>
541  art::Handle<std::vector<T>> index_p);
542  template <class T, class U>
543  std::vector<const U*> GetAssociatedVectorOneP(art::Handle<art::Assns<T, U>> h,
544  art::Handle<std::vector<T>> index_p);
545 
546  template <class T, class U>
547  std::vector<std::vector<size_t>> GetAssociatedVectorManyI(art::Handle<art::Assns<T, U>> h,
548  art::Handle<std::vector<T>> index_p);
549  template <class T, class U>
550  std::vector<std::vector<const U*>> GetAssociatedVectorManyP(art::Handle<art::Assns<T, U>> h,
551  art::Handle<std::vector<T>> index_p);
552 
553 } // end namespace
554 
555 //----------------------------------------------------------------------
556 // MARK CreateAssn_01
557 template <class T, class U>
559  std::vector<T> const& a,
560  art::Ptr<U> const& b,
561  art::Assns<U, T>& assn,
562  std::string a_instance,
563  size_t index /* = UINT_MAX */
564 )
565 {
566  if (index == UINT_MAX) index = a.size() - 1;
567 
568  try {
569  assn.addSingle(b, art::PtrMaker<T>{evt, a_instance}(index));
570  return true;
571  }
572  catch (cet::exception& e) {
573  mf::LogWarning("AssociationUtil")
574  << "unable to create requested art:Assns, exception thrown: " << e;
575  return false;
576  }
577 
578 } // util::CreateAssn() [01]
579 
580 //----------------------------------------------------------------------
581 // MARK CreateAssn_03
582 template <class T, class U>
584  art::Ptr<T> const& a,
585  art::Ptr<U> const& b,
586  art::Assns<U, T>& assn)
587 {
588 
589  try {
590  assn.addSingle(b, a);
591  }
592  catch (cet::exception& e) {
593  mf::LogWarning("AssociationUtil")
594  << "unable to create requested art:Assns, exception thrown: " << e;
595  return false;
596  }
597 
598  return true;
599 } // util::CreateAssn() [03]
600 
601 //----------------------------------------------------------------------
602 // MARK CreateAssn_04
603 template <class T, class U>
605  std::vector<T> const& a,
606  art::PtrVector<U> const& b,
607  art::Assns<T, U>& assn,
608  size_t index /* = UINT_MAX */
609 )
610 {
611  if (index == UINT_MAX) index = a.size() - 1;
612 
613  try {
614  auto const aptr = art::PtrMaker<T>{evt}(index);
615  for (art::Ptr<U> const& b_item : b)
616  assn.addSingle(aptr, b_item);
617  }
618  catch (cet::exception& e) {
619  mf::LogWarning("AssociationUtil")
620  << "unable to create requested art:Assns, exception thrown: " << e;
621  return false;
622  }
623 
624  return true;
625 } // util::CreateAssn() [04]
626 
627 //----------------------------------------------------------------------
628 // MARK CreateAssn_05
629 template <class T, class U>
631  art::Ptr<T> const& a,
632  std::vector<art::Ptr<U>> const& b,
633  art::Assns<T, U>& assn)
634 {
635 
636  try {
637  for (art::Ptr<U> const& b_item : b)
638  assn.addSingle(a, b_item);
639  }
640  catch (cet::exception const& e) {
641  mf::LogWarning("AssociationUtil")
642  << "unable to create requested art:Assns, exception thrown: " << e;
643  return false;
644  }
645 
646  return true;
647 } // util::CreateAssn() [05]
648 
649 //----------------------------------------------------------------------
650 // MARK CreateAssn_06
651 template <class T, class U>
653  std::vector<T> const& a,
654  std::vector<art::Ptr<U>> const& b,
655  art::Assns<T, U>& assn,
656  size_t index /* = UINT_MAX */
657 )
658 {
659 
660  if (index == UINT_MAX) index = a.size() - 1;
661 
662  try {
663  auto const aptr = art::PtrMaker<T>{evt}(index);
664  for (art::Ptr<U> const& b_item : b)
665  assn.addSingle(aptr, b_item);
666  }
667  catch (cet::exception& e) {
668  mf::LogWarning("AssociationUtil")
669  << "unable to create requested art:Assns, exception thrown: " << e;
670  return false;
671  }
672 
673  return true;
674 } // util::CreateAssn() [06]
675 
676 //----------------------------------------------------------------------
677 // MARK CreateAssn_07
678 template <class T, class U>
680  std::vector<T> const& a,
681  std::vector<U> const& /* b */,
682  art::Assns<T, U>& assn,
683  size_t startU,
684  size_t endU,
685  size_t index /* = UINT_MAX */
686 )
687 {
688 
689  if (index == UINT_MAX) index = a.size() - 1;
690 
691  try {
692  auto const aptr = art::PtrMaker<T>{evt}(index);
693  art::PtrMaker<U> const make_bptr{evt};
694  for (size_t i = startU; i < endU; ++i) {
695  assn.addSingle(aptr, make_bptr(i));
696  }
697  }
698  catch (cet::exception& e) {
699  mf::LogWarning("AssociationUtil")
700  << "unable to create requested art:Assns, exception thrown: " << e;
701  return false;
702  }
703 
704  return true;
705 } // util::CreateAssn() [07]
706 
707 //----------------------------------------------------------------------
708 // MARK CreateAssn_07a
709 template <class T, class U>
711  std::vector<T> const& a,
712  std::vector<U> const& /* b */,
713  art::Assns<T, U>& assn,
714  std::vector<size_t> const& indices,
715  size_t index /* = UINT_MAX */
716 )
717 {
718 
719  if (index == UINT_MAX) index = a.size() - 1;
720 
721  try {
722  auto const aptr = art::PtrMaker<T>{evt}(index);
723  art::PtrMaker<U> const make_bptr{evt};
724  for (size_t index : indices) {
725  assn.addSingle(aptr, make_bptr(index));
726  }
727  }
728  catch (cet::exception& e) {
729  mf::LogWarning("AssociationUtil")
730  << "unable to create requested art:Assns, exception thrown: " << e;
731  return false;
732  }
733 
734  return true;
735 } // util::CreateAssn() [07a]
736 
737 //----------------------------------------------------------------------
738 // MARK CreateAssn_08
739 template <typename T, typename U, typename Iter>
741  art::Assns<T, U>& assn,
742  size_t first_index,
743  Iter from_second_index,
744  Iter to_second_index)
745 {
746 
747  try {
748  // we declare here that we want to associate the element first_index of the
749  // (only) data product of type std::vector<T> with other objects.
750  // This is the pointer to that element:
751  auto const first_ptr = art::PtrMaker<T>{evt}(first_index);
752 
753  // we are going to associate that element in a with a number of elements
754  // of the only data product of type std::vector<U>
755  art::PtrMaker<U> const make_second_ptr{evt};
756  for (; from_second_index != to_second_index; ++from_second_index) {
757  assn.addSingle(first_ptr, make_second_ptr(*from_second_index));
758  } // while
759  }
760  catch (cet::exception& e) {
761  mf::LogWarning("AssociationUtil")
762  << "unable to create requested art:Assns, exception thrown: " << e;
763  return false;
764  }
765 
766  return true;
767 } // util::CreateAssn() [08]
768 
769 //----------------------------------------------------------------------
770 // MARK CreateAssnD_01a
771 template <typename T, typename U, typename D>
773  art::Assns<T, U, D>& assn,
774  size_t first_index,
775  size_t second_index,
776  typename art::Assns<T, U, D>::data_t&& data)
777 {
778 
779  try {
780  // we declare here that we want to associate the element first_index of the
781  // (only) data product of type std::vector<T> with the other object
782  auto const first_ptr = art::PtrMaker<T>{evt}(first_index);
783 
784  // the same to associate the element second_index of the (only)
785  // data product of type std::vector<U> with the first object.
786  auto const second_ptr = art::PtrMaker<U>{evt}(second_index);
787 
788  assn.addSingle(first_ptr, second_ptr, std::move(data));
789  }
790  catch (cet::exception& e) {
791  mf::LogWarning("AssociationUtil")
792  << "unable to create requested art:Assns, exception thrown: " << e;
793  return false;
794  }
795 
796  return true;
797 } // util::CreateAssnD() [01a]
798 
799 template <typename T, typename U, typename D>
801  art::Assns<T, U, D>& assn,
802  size_t first_index,
803  size_t second_index,
804  typename art::Assns<T, U, D>::data_t const& data)
805 {
806 
807  try {
808  // we declare here that we want to associate the element first_index of the
809  // (only) data product of type std::vector<T> with the other object
810  auto const first_ptr = art::PtrMaker<T>{evt}(first_index);
811 
812  // the same to associate the element second_index of the (only)
813  // data product of type std::vector<U> with the first object.
814  auto const second_ptr = art::PtrMaker<U>{evt}(second_index);
815 
816  assn.addSingle(first_ptr, second_ptr, data);
817  }
818  catch (cet::exception& e) {
819  mf::LogWarning("AssociationUtil")
820  << "unable to create requested art:Assns, exception thrown: " << e;
821  return false;
822  }
823 
824  return true;
825 } // util::CreateAssnD() [01b]
826 
827 //----------------------------------------------------------------------
828 template <class T, class U>
829 inline std::vector<const U*> util::FindUNotAssociatedToT(art::Handle<U> b,
830  art::Event const& evt,
831  std::string const& label)
832 {
833  // Do a FindOne for type T for each object of type U
834  // If the FindOne returns an invalid maybe ref, add the pointer
835  // of object type U to the return vector
836 
837  std::vector<const U*> notAssociated;
838 
839  art::FindOne<T> const fa(b, evt, label);
840 
841  for (size_t u = 0; u < b->size(); ++u) {
842  cet::maybe_ref<T const> t(fa.at(u));
843  if (!t.isValid()) {
844  art::Ptr<U> ptr(b, u);
845  notAssociated.push_back(ptr.get());
846  }
847  }
848 
849  return notAssociated;
850 }
851 
852 //----------------------------------------------------------------------
853 template <class T, class U>
854 inline std::vector<art::Ptr<U>> util::FindUNotAssociatedToTP(art::Handle<U> b,
855  art::Event const& evt,
856  std::string const& label)
857 {
858  // Do a FindOneP for type T for each object of type U
859  // If the FindOne returns an invalid maybe ref, add the pointer
860  // of object type U to the return vector
861 
862  std::vector<art::Ptr<U>> notAssociated;
863 
864  art::FindOneP<T> const fa(b, evt, label);
865 
866  for (size_t u = 0; u < b->size(); ++u) {
867  cet::maybe_ref<T const> t(fa.at(u));
868  if (!t.isValid()) { notAssociated.emplace_back(b, u); }
869  }
870 
871  return notAssociated;
872 }
873 
874 template <class T, class U>
876  art::Handle<std::vector<T>> index_p)
877 {
878  std::vector<size_t> associated_index(index_p->size());
879  for (auto const& pair : *h)
880  associated_index.at(pair.first.key()) = pair.second.key();
881  return associated_index;
882 }
883 
884 template <class T, class U>
886  art::Handle<std::vector<T>> index_p)
887 {
888  std::vector<const U*> associated_pointer(index_p->size());
889  for (auto const& pair : *h)
890  associated_pointer.at(pair.first.key()) = &(*(pair.second));
891  return associated_pointer;
892 }
893 
894 template <class T, class U>
895 inline std::vector<std::vector<size_t>> util::GetAssociatedVectorManyI(
897  art::Handle<std::vector<T>> index_p)
898 {
899  std::vector<std::vector<size_t>> associated_indices(index_p->size());
900  for (auto const& pair : *h)
901  associated_indices.at(pair.first.key()).push_back(pair.second.key());
902  return associated_indices;
903 }
904 
905 template <class T, class U>
906 inline std::vector<std::vector<const U*>> util::GetAssociatedVectorManyP(
908  art::Handle<std::vector<T>> index_p)
909 {
910  std::vector<std::vector<const U*>> associated_pointers(index_p->size());
911  for (auto const& pair : *h)
912  associated_pointers.at(pair.first.key()).push_back(&(*(pair.second)));
913  return associated_pointers;
914 }
915 
916 //--------------------------------------------------------------------
917 // Functions to support unnecessary leading producer argument
918 //
919 // These are legacy function signatures that accept a reference to a
920 // producer module. Although the signatures are still supported,
921 // they should not be encouraged. They, along with the other
922 // CreateAssn(D) functions above, will be marked as [[deprecated]]
923 // once art supports Assns::addMany (expected in art 3.04).
924 //--------------------------------------------------------------------
925 
927 
928 namespace util {
929  template <typename Producer, typename... Args>
930  std::enable_if_t<std::is_base_of_v<art::EDProducer, Producer>, bool> CreateAssn(Producer const&,
931  Args&&... args)
932  {
933  return CreateAssn(std::forward<Args>(args)...);
934  }
935 
936  template <typename Producer, typename... Args>
937  std::enable_if_t<std::is_base_of_v<art::EDProducer, Producer>, bool> CreateAssnD(Producer const&,
938  Args&&... args)
939  {
940  return CreateAssnD(std::forward<Args>(args)...);
941  }
942 }
943 
944 #endif //ASSOCIATIONUTIL_H
bool CreateAssnD(art::Event &evt, art::Assns< T, U, D > &assn, size_t first_index, size_t second_index, typename art::Assns< T, U, D >::data_t &&data)
Creates a single one-to-one association with associated data.
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
D data_t
Definition: Assns.h:236
std::vector< const U * > GetAssociatedVectorOneP(art::Handle< art::Assns< T, U >> h, art::Handle< std::vector< T >> index_p)
std::vector< std::vector< const U * > > GetAssociatedVectorManyP(art::Handle< art::Assns< T, U >> h, art::Handle< std::vector< T >> index_p)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
std::vector< size_t > GetAssociatedVectorOneI(art::Handle< art::Assns< T, U >> h, art::Handle< std::vector< T >> index_p)
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
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.
std::vector< art::Ptr< U > > FindUNotAssociatedToTP(art::Handle< U > b, art::Event const &evt, std::string const &label)
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:549
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< const U * > FindUNotAssociatedToT(art::Handle< U > b, art::Event const &evt, std::string const &label)
TCEvent evt
Definition: DataStructs.cxx:8
Float_t e
Definition: plot.C:35
T const * get() const
Definition: Ptr.h:138
std::vector< std::vector< size_t > > GetAssociatedVectorManyI(art::Handle< art::Assns< T, U >> h, art::Handle< std::vector< T >> index_p)
Definition: fwd.h:26
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
TFile fa("Li7.root")