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