LArSoft  v06_85_00
Liquid Argon Software toolkit - http://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 <vector>
77 #include <string>
78 #include <utility> // std::move()
79 
80 // framework libraries
92 
93 namespace util {
94 
95  // see https://cdcvs.fnal.gov/redmine/projects/art/wiki/Inter-Product_References
96  // for information about using art::Assns
97 
153  // MARK CreateAssn_01
154  template<class PRODUCER, class T, class U>
155  bool CreateAssn(PRODUCER const& prod,
156  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 indx=UINT_MAX
162  );
163 
211  // MARK CreateAssn_02
212  template<class PRODUCER, class T, class U>
213  inline bool CreateAssn(PRODUCER const& prod,
214  art::Event &evt,
215  std::vector<T> const&a,
216  art::Ptr<U> const&b,
217  art::Assns<U,T> &assn,
218  size_t indx=UINT_MAX)
219  { return CreateAssn(prod, evt, a, b, assn, std::string(), indx); }
220 
221 
236  // MARK CreateAssn_03
237  template<class PRODUCER, class T, class U>
238  bool CreateAssn(
239  PRODUCER const& prod,
240  art::Event & evt,
241  art::Ptr<T> const& a,
242  art::Ptr<U> const& b,
243  art::Assns<U,T> & assn
244  );
245 
264  // MARK CreateAssn_04
265  template<class PRODUCER, class T, class U>
266  bool CreateAssn(
267  PRODUCER const& prod,
268  art::Event & evt,
269  std::vector<T> const& a,
270  art::PtrVector<U> const& b,
271  art::Assns<T,U> & assn,
272  size_t indx = UINT_MAX
273  );
274 
291  // method to create a 1 to many association, with the many being of type U
292  // indx is the location in the input std::vector<T> of the object you wish to
293  // associate with the art::PtrVector<U>
294  // MARK CreateAssn_05
295  template<class PRODUCER, class T, class U>
296  bool CreateAssn(
297  PRODUCER const& prod,
298  art::Event & evt,
299  art::Ptr<T> const& a,
300  std::vector<art::Ptr<U>> const& b,
301  art::Assns<T,U> & assn
302  );
303 
322  // MARK CreateAssn_06
323  template<class PRODUCER, class T, class U>
324  bool CreateAssn(
325  PRODUCER const& prod,
326  art::Event & evt,
327  std::vector<T> const& a,
328  std::vector<art::Ptr<U>> const& b,
329  art::Assns<T,U> & assn,
330  size_t indx = UINT_MAX
331  );
332 
360  // MARK CreateAssn_07
361  template<class PRODUCER, class T, class U>
362  bool CreateAssn(
363  PRODUCER const& prod,
364  art::Event & evt,
365  std::vector<T> const& a,
366  std::vector<U> const& b,
367  art::Assns<T,U> & assn,
368  size_t startU,
369  size_t endU,
370  size_t indx = UINT_MAX
371  );
372 
399  // MARK CreateAssn_07a
400  template<class PRODUCER, class T, class U>
401  bool CreateAssn(
402  PRODUCER const& prod,
403  art::Event & evt,
404  std::vector<T> const& a,
405  std::vector<U> const& b,
406  art::Assns<T,U> & assn,
407  std::vector<size_t> const& indices,
408  size_t indx = UINT_MAX
409  );
410 
449  // MARK CreateAssn_08
450  template <typename PRODUCER, typename T, typename U, typename Iter>
451  bool CreateAssn(
452  PRODUCER const& prod,
453  art::Event & evt,
454  art::Assns<T,U> & assn,
455  size_t first_index,
456  Iter from_second_index,
457  Iter to_second_index
458  );
459 
461 
515  // MARK CreateAssnD_01
516  // MARK CreateAssnD_01a
517  template <typename PRODUCER, typename T, typename U, typename D>
518  bool CreateAssnD(
519  PRODUCER const& prod,
520  art::Event & evt,
521  art::Assns<T,U,D> & assn,
522  size_t first_index,
523  size_t second_index,
524  typename art::Assns<T,U,D>::data_t&& data
525  );
526  // MARK CreateAssnD_01b
527  template <typename PRODUCER, typename T, typename U, typename D>
528  bool CreateAssnD(
529  PRODUCER const& prod,
530  art::Event & evt,
531  art::Assns<T,U,D> & assn,
532  size_t first_index,
533  size_t second_index,
534  typename art::Assns<T,U,D>::data_t const& data
535  );
537 
538 
539  // method to return all objects of type U that are not associated to
540  // objects of type T. Label is the module label that would have produced
541  // the associations and likely the objects of type T
542  // this method assumes there is a one to many relationship between T and U
543  // for example if you want to get all recob::Hits
544  // that are not associated to recob::Clusters
545  // std::vector<const recob::Hit*> hits = FindUNotAssociatedToU<recob::Cluster>(art::Handle<recob::Hit>, ...);
546  template<class T, class U> std::vector<const U*> FindUNotAssociatedToT(art::Handle<U> b,
547  art::Event const& evt,
548  std::string const& label);
549 
550  // method to return all objects of type U that are not associated to
551  // objects of type T. Label is the module label that would have produced
552  // the associations and likely the objects of type T
553  // this method assumes there is a one to many relationship between T and U
554  // for example if you want to get all recob::Hits
555  // that are not associated to recob::Clusters
556  // std::vector< art::Ptr<recob::Hit> > hits = FindUNotAssociatedToTP<recob::Cluster>(art::Handle<recob::Hit>, ...);
557  template<class T, class U> std::vector< art::Ptr<U> > FindUNotAssociatedToTP(art::Handle<U> b,
558  art::Event const& evt,
559  std::string const& label);
560 
561  // Methods make getting simple ART-independent association information.
562  // --- GetAssociatedVectorOneI takes in a handle to an association, and a handle to a product on the event.
563  // The ouput is a vector of with the same number of entries as the handle to the product, containing an index
564  // to the location of one associated product in that product's collection.
565  // --- GetAssociatedVectorOneP takes in a handle to an association, and a handle to a product on the event.
566  // The ouput is a vector of with the same number of entries as the handle to the product, containing a pointer
567  // to one associated product.
568  // --- GetAssociatedVectorManyI takes in a handle to an association, and a handle to a product on the event.
569  // The ouput is a vector of with the same number of entries as the handle to the product, containing a vector
570  // of indices that give the locations of all associated products in those products' collection.
571  // --- GetAssociatedVectorManyP takes in a handle to an association, and a handle to a product on the event.
572  // The ouput is a vector of with the same number of entries as the handle to the product, containing a vector
573  // of pointers to all associated products.
574 
575  template<class T,class U> std::vector<size_t> GetAssociatedVectorOneI(art::Handle< art::Assns<T,U> > h,
576  art::Handle< std::vector<T> > index_p);
577  template<class T,class U> std::vector<const U*> GetAssociatedVectorOneP(art::Handle< art::Assns<T,U> > h,
578  art::Handle< std::vector<T> > index_p);
579 
580  template<class T,class U> std::vector< std::vector<size_t> > GetAssociatedVectorManyI(art::Handle< art::Assns<T,U> > h,
581  art::Handle< std::vector<T> > index_p);
582  template<class T,class U> std::vector< std::vector<const U*> > GetAssociatedVectorManyP(art::Handle< art::Assns<T,U> > h,
583  art::Handle< std::vector<T> > index_p);
584 
585 
586 }// end namespace
587 
588 //----------------------------------------------------------------------
589 // MARK CreateAssn_01
590 template<class PRODUCER, class T, class U>
592  PRODUCER const& prod,
593  art::Event & evt,
594  std::vector<T> const& a,
595  art::Ptr<U> const& b,
596  art::Assns<U,T> & assn,
597  std::string a_instance,
598  size_t indx /* = UINT_MAX */
599  )
600 {
601  if (indx == UINT_MAX) indx = a.size()-1;
602 
603  try{
604  art::ProductID aid = prod.template getProductID< std::vector<T>>( a_instance);
605  art::Ptr<T> aptr(aid, indx, evt.productGetter(aid));
606  assn.addSingle(b, aptr);
607  return true;
608  }
609  catch(cet::exception &e){
610  mf::LogWarning("AssociationUtil")
611  << "unable to create requested art:Assns, exception thrown: " << e;
612  return false;
613  }
614 
615 } // util::CreateAssn() [01]
616 
617 
618 //----------------------------------------------------------------------
619 // MARK CreateAssn_03
620 template<class PRODUCER, class T, class U>
622  PRODUCER const& /* prod */,
623  art::Event & /* evt */,
624  art::Ptr<T> const& a,
625  art::Ptr<U> const& b,
626  art::Assns<U,T> & assn
627 ) {
628 
629  try{
630  assn.addSingle(b, a);
631  }
632  catch(cet::exception &e){
633  mf::LogWarning("AssociationUtil")
634  << "unable to create requested art:Assns, exception thrown: " << e;
635  return false;
636  }
637 
638  return true;
639 } // util::CreateAssn() [03]
640 
641 
642 //----------------------------------------------------------------------
643 // MARK CreateAssn_04
644 template<class PRODUCER, class T, class U>
646  PRODUCER const& prod,
647  art::Event & evt,
648  std::vector<T> const& a,
649  art::PtrVector<U> const& b,
650  art::Assns<T,U> & assn,
651  size_t indx /* = UINT_MAX */
652 ) {
653  if(indx == UINT_MAX) indx = a.size() - 1;
654 
655  try{
656  art::ProductID aid = prod.template getProductID< std::vector<T> >();
657  art::Ptr<T> aptr(aid, indx, evt.productGetter(aid));
658  for(art::Ptr<U> const& b_item: b) assn.addSingle(aptr, b_item);
659  }
660  catch(cet::exception &e){
661  mf::LogWarning("AssociationUtil")
662  << "unable to create requested art:Assns, exception thrown: " << e;
663  return false;
664  }
665 
666  return true;
667 } // util::CreateAssn() [04]
668 
669 //----------------------------------------------------------------------
670 // MARK CreateAssn_05
671 template<class PRODUCER, class T, class U>
673  PRODUCER const& /* prod */,
674  art::Event & /* evt */,
675  art::Ptr<T> const& a,
676  std::vector<art::Ptr<U>> const& b,
677  art::Assns<T,U> & assn
678 ) {
679 
680  try{
681  for (art::Ptr<U> const& b_item: b) assn.addSingle(a, b_item);
682  }
683  catch(cet::exception const& e){
684  mf::LogWarning("AssociationUtil")
685  << "unable to create requested art:Assns, exception thrown: " << e;
686  return false;
687  }
688 
689  return true;
690 } // util::CreateAssn() [05]
691 
692 //----------------------------------------------------------------------
693 // MARK CreateAssn_06
694 template<class PRODUCER, class T, class U>
696  PRODUCER const& prod,
697  art::Event & evt,
698  std::vector<T> const& a,
699  std::vector<art::Ptr<U>> const& b,
700  art::Assns<T,U> & assn,
701  size_t indx /* = UINT_MAX */
702 ) {
703 
704  if (indx == UINT_MAX) indx = a.size() - 1;
705 
706  try{
707  art::ProductID aid = prod.template getProductID< std::vector<T> >();
708  art::Ptr<T> aptr(aid, indx, evt.productGetter(aid));
709  for (art::Ptr<U> const& b_item: b) assn.addSingle(aptr, b_item);
710  }
711  catch(cet::exception &e){
712  mf::LogWarning("AssociationUtil")
713  << "unable to create requested art:Assns, exception thrown: " << e;
714  return false;
715  }
716 
717  return true;
718 } // util::CreateAssn() [06]
719 
720 //----------------------------------------------------------------------
721 // MARK CreateAssn_07
722 template<class PRODUCER, class T, class U>
724  PRODUCER const& prod,
725  art::Event & evt,
726  std::vector<T> const& a,
727  std::vector<U> const& /* b */,
728  art::Assns<T,U> & assn,
729  size_t startU,
730  size_t endU,
731  size_t indx /* = UINT_MAX */
732 ) {
733 
734  if(indx == UINT_MAX) indx = a.size() - 1;
735 
736  try{
737  art::ProductID aid = prod.template getProductID< std::vector<T> >();
738  art::ProductID bid = prod.template getProductID< std::vector<U> >();
739  art::Ptr<T> aptr(aid, indx, evt.productGetter(aid));
740  auto const* getter = evt.productGetter(bid); // I don't want to know what it is
741  for(size_t i = startU; i < endU; ++i){
742  art::Ptr<U> bptr(bid, i, getter);
743  assn.addSingle(aptr, bptr);
744  }
745  }
746  catch(cet::exception &e){
747  mf::LogWarning("AssociationUtil")
748  << "unable to create requested art:Assns, exception thrown: " << e;
749  return false;
750  }
751 
752  return true;
753 } // util::CreateAssn() [07]
754 
755 //----------------------------------------------------------------------
756 // MARK CreateAssn_07a
757 template<class PRODUCER, class T, class U>
759  PRODUCER const& prod,
760  art::Event & evt,
761  std::vector<T> const& a,
762  std::vector<U> const& /* b */,
763  art::Assns<T,U> & assn,
764  std::vector<size_t> const& indices,
765  size_t indx /* = UINT_MAX */
766 ) {
767 
768  if(indx == UINT_MAX) indx = a.size() - 1;
769 
770  try{
771  art::ProductID aid = prod.template getProductID< std::vector<T> >();
772  art::ProductID bid = prod.template getProductID< std::vector<U> >();
773  art::Ptr<T> aptr(aid, indx, evt.productGetter(aid));
774  auto const* getter = evt.productGetter(bid); // I don't want to know what it is
775  for(size_t index: indices){
776  art::Ptr<U> bptr(bid, index, getter);
777  assn.addSingle(aptr, bptr);
778  }
779  }
780  catch(cet::exception &e){
781  mf::LogWarning("AssociationUtil")
782  << "unable to create requested art:Assns, exception thrown: " << e;
783  return false;
784  }
785 
786  return true;
787 } // util::CreateAssn() [07a]
788 
789 //----------------------------------------------------------------------
790 // MARK CreateAssn_08
791 template <typename PRODUCER, typename T, typename U, typename Iter>
793  PRODUCER const& prod,
794  art::Event & evt,
795  art::Assns<T,U> & assn,
796  size_t first_index,
797  Iter from_second_index,
798  Iter to_second_index
799 ) {
800 
801  try{
802  // We need the "product ID" of what is going to become a data product.
803  // The data product ID is unique for the combination of process, producer,
804  // data type and product (instance) label.
805  //
806  art::ProductID first_id = prod.template getProductID< std::vector<T> >();
807  art::ProductID second_id = prod.template getProductID< std::vector<U> >();
808 
809  // we declare here that we want to associate the element first_index of the
810  // (only) data product of type std::vector<T> with other objects.
811  // This is the pointer to that element:
812  art::Ptr<T> first_ptr(first_id, first_index, evt.productGetter(first_id));
813 
814  // we are going to associate that element in a with a number of elements
815  // of the only data product of type std::vector<U>
816  auto const* getter = evt.productGetter(second_id); // auto, spare me the details
817  while (from_second_index != to_second_index) {
818  art::Ptr<U> second_ptr(second_id, *from_second_index, getter);
819  assn.addSingle(first_ptr, second_ptr);
820  ++from_second_index;
821  } // while
822  }
823  catch(cet::exception &e){
824  mf::LogWarning("AssociationUtil")
825  << "unable to create requested art:Assns, exception thrown: " << e;
826  return false;
827  }
828 
829  return true;
830 } // util::CreateAssn() [08]
831 
832 
833 //----------------------------------------------------------------------
834 // MARK CreateAssnD_01a
835 template <typename PRODUCER, typename T, typename U, typename D>
837  PRODUCER const& prod,
838  art::Event & evt,
839  art::Assns<T,U,D> & assn,
840  size_t first_index,
841  size_t second_index,
842  typename art::Assns<T,U,D>::data_t&& data
843 ) {
844 
845  try{
846  // We need the "product ID" of what is going to become a data product.
847  // The data product ID is unique for the combination of process, producer,
848  // data type and product (instance) label.
849  //
850  // we declare here that we want to associate the element first_index of the
851  // (only) data product of type std::vector<T> with the other object
852  art::ProductID first_id = prod.template getProductID< std::vector<T> >();
853  art::Ptr<T> first_ptr(first_id, first_index, evt.productGetter(first_id));
854 
855  // the same to associate the element second_index of the (only)
856  // data product of type std::vector<U> with the first object.
857  art::ProductID second_id = prod.template getProductID< std::vector<U> >();
858  art::Ptr<U> second_ptr
859  (second_id, second_index, evt.productGetter(second_id));
860 
861  assn.addSingle(first_ptr, second_ptr, std::move(data));
862  }
863  catch(cet::exception &e){
864  mf::LogWarning("AssociationUtil")
865  << "unable to create requested art:Assns, exception thrown: " << e;
866  return false;
867  }
868 
869  return true;
870 } // util::CreateAssnD() [01a]
871 
872 template <typename PRODUCER, typename T, typename U, typename D>
874  PRODUCER const& prod,
875  art::Event & evt,
876  art::Assns<T,U,D> & assn,
877  size_t first_index,
878  size_t second_index,
879  typename art::Assns<T,U,D>::data_t const& data
880 ) {
881 
882  try{
883  // We need the "product ID" of what is going to become a data product.
884  // The data product ID is unique for the combination of process, producer,
885  // data type and product (instance) label.
886  //
887  // we declare here that we want to associate the element first_index of the
888  // (only) data product of type std::vector<T> with the other object
889  art::ProductID first_id = prod.template getProductID< std::vector<T> >();
890  art::Ptr<T> first_ptr(first_id, first_index, evt.productGetter(first_id));
891 
892  // the same to associate the element second_index of the (only)
893  // data product of type std::vector<U> with the first object.
894  art::ProductID second_id = prod.template getProductID< std::vector<U> >();
895  art::Ptr<U> second_ptr
896  (second_id, second_index, evt.productGetter(second_id));
897 
898  assn.addSingle(first_ptr, second_ptr, data);
899  }
900  catch(cet::exception &e){
901  mf::LogWarning("AssociationUtil")
902  << "unable to create requested art:Assns, exception thrown: " << e;
903  return false;
904  }
905 
906  return true;
907 } // util::CreateAssnD() [01b]
908 
909 
910 //----------------------------------------------------------------------
911 template<class T, class U> inline std::vector<const U*> util::FindUNotAssociatedToT(art::Handle<U> b,
912  art::Event const& evt,
913  std::string const& label)
914 {
915 
916  // Do a FindOne for type T for each object of type U
917  // If the FindOne returns an invalid maybe ref, add the pointer
918  // of object type U to the return vector
919 
920  std::vector<const U*> notAssociated;
921 
922  art::FindOne<T> fa(b, evt, label);
923 
924  for(size_t u = 0; u < b->size(); ++u){
925  cet::maybe_ref<T const> t(fa.at(u));
926  if( !t.isValid() ){
927  art::Ptr<U> ptr(b, u);
928  notAssociated.push_back(ptr.get());
929  }
930  }
931 //
932  return notAssociated;
933 }
934 
935 //----------------------------------------------------------------------
936 template<class T, class U> inline std::vector< art::Ptr<U> > util::FindUNotAssociatedToTP(art::Handle<U> b,
937  art::Event const& evt,
938  std::string const& label)
939 {
940 
941  // Do a FindOneP for type T for each object of type U
942  // If the FindOne returns an invalid maybe ref, add the pointer
943  // of object type U to the return vector
944 
945  std::vector< art::Ptr<U> > notAssociated;
946 
947  art::FindOneP<T> fa(b, evt, label);
948 
949  for(size_t u = 0; u < b->size(); ++u){
950  cet::maybe_ref<T const> t(fa.at(u));
951  if( !t.isValid() ){
952  art::Ptr<U> ptr(b, u);
953  notAssociated.push_back(ptr);
954  }
955  }
956 
957  return notAssociated;
958 }
959 
960 
961 
962 template<class T,class U> inline std::vector<size_t> util::GetAssociatedVectorOneI(art::Handle< art::Assns<T,U> > h,
963  art::Handle< std::vector<T> > index_p)
964 {
965  std::vector<size_t> associated_index(index_p->size());
966  for(auto const& pair : *h)
967  associated_index.at(pair.first.key()) = pair.second.key();
968  return associated_index;
969 }
970 
971 template<class T,class U> inline std::vector<const U*> util::GetAssociatedVectorOneP(art::Handle< art::Assns<T,U> > h,
972  art::Handle< std::vector<T> > index_p)
973 {
974  std::vector<const U*> associated_pointer(index_p->size());
975  for(auto const& pair : *h)
976  associated_pointer.at(pair.first.key()) = &(*(pair.second));
977  return associated_pointer;
978 }
979 
980 template<class T,class U> inline std::vector< std::vector<size_t> > util::GetAssociatedVectorManyI(art::Handle< art::Assns<T,U> > h,
981  art::Handle< std::vector<T> > index_p)
982 {
983  std::vector< std::vector<size_t> > associated_indices(index_p->size());
984  for(auto const& pair : *h)
985  associated_indices.at(pair.first.key()).push_back(pair.second.key());
986  return associated_indices;
987 }
988 
989 template<class T,class U> inline std::vector< std::vector<const U*> > util::GetAssociatedVectorManyP(art::Handle< art::Assns<T,U> > h,
990  art::Handle< std::vector<T> > index_p)
991 {
992  std::vector< std::vector<const U*> > associated_pointers(index_p->size());
993  for(auto const& pair : *h)
994  associated_pointers.at(pair.first.key()).push_back( &(*(pair.second)) );
995  return associated_pointers;
996 }
997 
998 
999 #endif //ASSOCIATIONUTIL_H
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
D data_t
Definition: Assns.h:214
const std::string label
std::vector< const U * > GetAssociatedVectorOneP(art::Handle< art::Assns< T, U > > h, art::Handle< std::vector< T > > index_p)
EDProductGetter const * productGetter(ProductID const) const
Definition: Event.cc:64
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::vector< size_t > GetAssociatedVectorOneI(art::Handle< art::Assns< T, U > > h, art::Handle< std::vector< T > > index_p)
bool CreateAssnD(PRODUCER const &prod, 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.
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(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
TFile fa("Li7.root")
T const * get() const
Definition: Ptr.h:321
std::vector< art::Ptr< U > > FindUNotAssociatedToTP(art::Handle< U > b, art::Event const &evt, std::string const &label)
std::vector< std::vector< size_t > > GetAssociatedVectorManyI(art::Handle< art::Assns< T, U > > h, art::Handle< std::vector< T > > index_p)
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:489
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< const U * > FindUNotAssociatedToT(art::Handle< U > b, art::Event const &evt, std::string const &label)
Float_t e
Definition: plot.C:34
Definition: fwd.h:25
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::vector< std::vector< const U * > > GetAssociatedVectorManyP(art::Handle< art::Assns< T, U > > h, art::Handle< std::vector< T > > index_p)