CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/Framework/interface/Event.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Event_h
00002 #define FWCore_Framework_Event_h
00003 
00004 // -*- C++ -*-
00005 //
00006 // Package:     Framework
00007 // Class  :     Event
00008 //
00017 /*----------------------------------------------------------------------
00018 ----------------------------------------------------------------------*/
00019 
00020 #include "DataFormats/Common/interface/BasicHandle.h"
00021 #include "DataFormats/Common/interface/Handle.h"
00022 #include "DataFormats/Common/interface/OrphanHandle.h"
00023 #include "DataFormats/Common/interface/Wrapper.h"
00024 
00025 #include "DataFormats/Provenance/interface/EventID.h"
00026 #include "DataFormats/Provenance/interface/EventSelectionID.h"
00027 #include "DataFormats/Provenance/interface/ProductID.h"
00028 #include "DataFormats/Provenance/interface/RunID.h"
00029 
00030 #include "FWCore/Common/interface/EventBase.h"
00031 #include "FWCore/Framework/interface/Frameworkfwd.h"
00032 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
00033 
00034 #include "boost/shared_ptr.hpp"
00035 
00036 #include <memory>
00037 #include <string>
00038 #include <set>
00039 #include <typeinfo>
00040 #include <vector>
00041 
00042 namespace edm {
00043 
00044   class ConstBranchDescription;
00045   class TriggerResultsByName;
00046   class TriggerResults;
00047   class TriggerNames;
00048 
00049   class Event : public EventBase {
00050   public:
00051     Event(EventPrincipal& ep, ModuleDescription const& md);
00052     ~Event();
00053 
00054     // AUX functions are defined in EventBase
00055     EventAuxiliary const& eventAuxiliary() const {return aux_;}
00056 
00057     LuminosityBlock const&
00058     getLuminosityBlock() const {
00059       return *luminosityBlock_;
00060     }
00061 
00062     Run const&
00063     getRun() const;
00064 
00065     RunNumber_t
00066     run() const {return id().run();}
00067 
00068     template <typename PROD>
00069     bool
00070     get(ProductID const& oid, Handle<PROD>& result) const;
00071 
00072     // Template member overload to deal with Views.
00073     template <typename ELEMENT>
00074     bool
00075     get(ProductID const& oid, Handle<View<ELEMENT> >& result) const ;
00076 
00077     EventSelectionIDVector const& eventSelectionIDs() const;
00078 
00079     ProcessHistoryID const& processHistoryID() const;
00080 
00082     template <typename PROD>
00083     OrphanHandle<PROD>
00084     put(std::auto_ptr<PROD> product) {return put<PROD>(product, std::string());}
00085 
00087     template <typename PROD>
00088     OrphanHandle<PROD>
00089     put(std::auto_ptr<PROD> product, std::string const& productInstanceName);
00090 
00094     template <typename PROD>
00095     RefProd<PROD>
00096     getRefBeforePut() {return getRefBeforePut<PROD>(std::string());}
00097 
00098     template <typename PROD>
00099     RefProd<PROD>
00100     getRefBeforePut(std::string const& productInstanceName);
00101 
00102     template <typename PROD>
00103     bool
00104     get(SelectorBase const& sel, Handle<PROD>& result) const;
00105 
00106     template <typename PROD>
00107     bool
00108     getByLabel(InputTag const& tag, Handle<PROD>& result) const;
00109 
00110     template <typename PROD>
00111     bool
00112     getByLabel(std::string const& label, Handle<PROD>& result) const;
00113 
00114     template <typename PROD>
00115     bool
00116     getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const;
00117 
00118     template <typename PROD>
00119     void
00120     getMany(SelectorBase const& sel, std::vector<Handle<PROD> >& results) const;
00121 
00122     template <typename PROD>
00123     bool
00124     getByType(Handle<PROD>& result) const;
00125 
00126     template <typename PROD>
00127     void
00128     getManyByType(std::vector<Handle<PROD> >& results) const;
00129 
00130     // Template member overload to deal with Views.
00131     template <typename ELEMENT>
00132     bool
00133     getByLabel(std::string const& label,
00134                Handle<View<ELEMENT> >& result) const;
00135 
00136     template <typename ELEMENT>
00137     bool
00138     getByLabel(std::string const& label,
00139                std::string const& productInstanceName,
00140                Handle<View<ELEMENT> >& result) const;
00141 
00142     template <typename ELEMENT>
00143     bool
00144     getByLabel(InputTag const& tag, Handle<View<ELEMENT> >& result) const;
00145 
00146     template <typename ELEMENT>
00147     void
00148     fillView_(BasicHandle& bh,
00149               Handle<View<ELEMENT> >& result) const;
00150 
00151     Provenance
00152     getProvenance(BranchID const& theID) const;
00153 
00154     Provenance
00155     getProvenance(ProductID const& theID) const;
00156 
00157     void
00158     getAllProvenance(std::vector<Provenance const*>& provenances) const;
00159 
00160     // Return true if this Event has been subjected to a process with
00161     // the given processName, and false otherwise.
00162     // If true is returned, then ps is filled with the ParameterSet
00163     // used to configure the identified process.
00164     bool
00165     getProcessParameterSet(std::string const& processName, ParameterSet& ps) const;
00166 
00167     ProcessHistory const&
00168     processHistory() const;
00169 
00170     size_t size() const;
00171 
00172     virtual edm::TriggerNames const& triggerNames(edm::TriggerResults const& triggerResults) const;
00173     virtual TriggerResultsByName triggerResultsByName(std::string const& process) const;
00174 
00175     typedef std::vector<std::pair<EDProduct*, ConstBranchDescription const*> > ProductPtrVec;
00176 
00177   private:
00178     EventPrincipal const&
00179     eventPrincipal() const;
00180 
00181     EventPrincipal&
00182     eventPrincipal();
00183 
00184     ProductID
00185     makeProductID(ConstBranchDescription const& desc) const;
00186 
00187     //override used by EventBase class
00188     virtual BasicHandle getByLabelImpl(std::type_info const& iWrapperType, std::type_info const& iProductType, InputTag const& iTag) const;
00189 
00190     // commit_() is called to complete the transaction represented by
00191     // this PrincipalGetAdapter. The friendships required seems gross, but any
00192     // alternative is not great either.  Putting it into the
00193     // public interface is asking for trouble
00194     friend class ConfigurableInputSource;
00195     friend class DaqSource;
00196     friend class InputSource;
00197     friend class RawInputSource;
00198     friend class EDFilter;
00199     friend class EDProducer;
00200 
00201     void commit_(std::vector<BranchID>* previousParentage= 0, ParentageID* previousParentageId = 0);
00202     void commit_aux(ProductPtrVec& products, bool record_parents, std::vector<BranchID>* previousParentage = 0, ParentageID* previousParentageId = 0);
00203 
00204     BasicHandle
00205     getByProductID_(ProductID const& oid) const;
00206 
00207     ProductPtrVec& putProducts() {return putProducts_;}
00208     ProductPtrVec const& putProducts() const {return putProducts_;}
00209 
00210     ProductPtrVec& putProductsWithoutParents() {return putProductsWithoutParents_;}
00211     ProductPtrVec const& putProductsWithoutParents() const {return putProductsWithoutParents_;}
00212 
00213     PrincipalGetAdapter provRecorder_;
00214 
00215     // putProducts_ and putProductsWithoutParents_ are the holding
00216     // pens for EDProducts inserted into this PrincipalGetAdapter. Pointers
00217     // in these collections own the products to which they point.
00218     //
00219     ProductPtrVec putProducts_;               // keep parentage info for these
00220     ProductPtrVec putProductsWithoutParents_; // ... but not for these
00221 
00222     EventAuxiliary const& aux_;
00223     boost::shared_ptr<LuminosityBlock const> const luminosityBlock_;
00224 
00225     // gotBranchIDs_ must be mutable because it records all 'gets',
00226     // which do not logically modify the PrincipalGetAdapter. gotBranchIDs_ is
00227     // merely a cache reflecting what has been retreived from the
00228     // Principal class.
00229     typedef std::set<BranchID> BranchIDSet;
00230     mutable BranchIDSet gotBranchIDs_;
00231     void addToGotBranchIDs(Provenance const& prov) const;
00232 
00233     // We own the retrieved Views, and have to destroy them.
00234     mutable std::vector<boost::shared_ptr<ViewBase> > gotViews_;
00235   };
00236 
00237   // The following functions objects are used by Event::put, under the
00238   // control of a metafunction if, to put the given pair into the
00239   // right collection.
00240   template <typename PROD>
00241   struct RecordInParentless {
00242     typedef Event::ProductPtrVec ptrvec_t;
00243     void do_it(ptrvec_t& ignored,
00244                ptrvec_t& used,
00245                Wrapper<PROD>* wp,
00246                ConstBranchDescription const* desc) const {
00247       used.push_back(std::make_pair(wp, desc));
00248     }
00249   };
00250 
00251   template <typename PROD>
00252   struct RecordInParentfull {
00253     typedef Event::ProductPtrVec ptrvec_t;
00254 
00255     void do_it(ptrvec_t& used,
00256                ptrvec_t& ignored,
00257                Wrapper<PROD>* wp,
00258                ConstBranchDescription const* desc) const {
00259       used.push_back(std::make_pair(wp, desc));
00260     }
00261   };
00262 
00263 
00264   template <typename PROD>
00265   bool
00266   Event::get(ProductID const& oid, Handle<PROD>& result) const {
00267     result.clear();
00268     BasicHandle bh = this->getByProductID_(oid);
00269     convert_handle(bh, result);  // throws on conversion error
00270     if (bh.failedToGet()) {
00271       return false;
00272     }
00273     addToGotBranchIDs(*bh.provenance());
00274     return true;
00275   }
00276 
00277   template <typename ELEMENT>
00278   bool
00279   Event::get(ProductID const& oid, Handle<View<ELEMENT> >& result) const {
00280       result.clear();
00281       BasicHandle bh = this->getByProductID_(oid);
00282 
00283       if(bh.failedToGet()) {
00284           boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound));
00285           *whyFailed
00286               << "get View by ID failed: no product with ID = " << oid <<"\n";
00287           Handle<View<ELEMENT> > temp(whyFailed);
00288           result.swap(temp);
00289           return false;
00290       }
00291 
00292       fillView_(bh, result);
00293       return true;
00294   }
00295 
00296   template <typename PROD>
00297   OrphanHandle<PROD>
00298   Event::put(std::auto_ptr<PROD> product, std::string const& productInstanceName) {
00299     if (product.get() == 0) {                // null pointer is illegal
00300       TypeID typeID(typeid(PROD));
00301       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
00302     }
00303 
00304     // The following will call post_insert if T has such a function,
00305     // and do nothing if T has no such function.
00306     typename boost::mpl::if_c<detail::has_postinsert<PROD>::value,
00307       DoPostInsert<PROD>,
00308       DoNotPostInsert<PROD> >::type maybe_inserter;
00309     maybe_inserter(product.get());
00310 
00311     ConstBranchDescription const& desc =
00312       provRecorder_.getBranchDescription(TypeID(*product), productInstanceName);
00313 
00314     Wrapper<PROD>* wp(new Wrapper<PROD>(product));
00315 
00316     typename boost::mpl::if_c<detail::has_donotrecordparents<PROD>::value,
00317       RecordInParentless<PROD>,
00318       RecordInParentfull<PROD> >::type parentage_recorder;
00319     parentage_recorder.do_it(putProducts(),
00320                              putProductsWithoutParents(),
00321                              wp,
00322                              &desc);
00323 
00324     //    putProducts().push_back(std::make_pair(wp, &desc));
00325 
00326     // product.release(); // The object has been copied into the Wrapper.
00327     // The old copy must be deleted, so we cannot release ownership.
00328 
00329     return(OrphanHandle<PROD>(wp->product(), makeProductID(desc)));
00330   }
00331 
00332   template <typename PROD>
00333   RefProd<PROD>
00334   Event::getRefBeforePut(std::string const& productInstanceName) {
00335     PROD* p = 0;
00336     ConstBranchDescription const& desc =
00337       provRecorder_.getBranchDescription(TypeID(*p), productInstanceName);
00338 
00339     //should keep track of what Ref's have been requested and make sure they are 'put'
00340     return RefProd<PROD>(makeProductID(desc), provRecorder_.prodGetter());
00341   }
00342 
00343   template <typename PROD>
00344   bool
00345   Event::get(SelectorBase const& sel, Handle<PROD>& result) const {
00346     bool ok = provRecorder_.get(sel, result);
00347     if (ok) {
00348       addToGotBranchIDs(*result.provenance());
00349     }
00350     return ok;
00351   }
00352 
00353   template <typename PROD>
00354   bool
00355   Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
00356     bool ok = provRecorder_.getByLabel(tag, result);
00357     if (ok) {
00358       addToGotBranchIDs(*result.provenance());
00359     }
00360     return ok;
00361   }
00362 
00363   template <typename PROD>
00364   bool
00365   Event::getByLabel(std::string const& label, Handle<PROD>& result) const {
00366     bool ok = provRecorder_.getByLabel(label, result);
00367     if (ok) {
00368       addToGotBranchIDs(*result.provenance());
00369     }
00370     return ok;
00371   }
00372 
00373   template <typename PROD>
00374   bool
00375   Event::getByLabel(std::string const& label,
00376                     std::string const& productInstanceName,
00377                     Handle<PROD>& result) const {
00378     bool ok = provRecorder_.getByLabel(label, productInstanceName, result);
00379     if (ok) {
00380       addToGotBranchIDs(*result.provenance());
00381     }
00382     return ok;
00383   }
00384 
00385   template <typename PROD>
00386   void
00387   Event::getMany(SelectorBase const& sel, std::vector<Handle<PROD> >& results) const {
00388     provRecorder_.getMany(sel, results);
00389     for (typename std::vector<Handle<PROD> >::const_iterator it = results.begin(), itEnd = results.end();
00390         it != itEnd; ++it) {
00391       addToGotBranchIDs(*it->provenance());
00392     }
00393   }
00394 
00395   template <typename PROD>
00396   bool
00397   Event::getByType(Handle<PROD>& result) const {
00398     bool ok = provRecorder_.getByType(result);
00399     if (ok) {
00400       addToGotBranchIDs(*result.provenance());
00401     }
00402     return ok;
00403   }
00404 
00405   template <typename PROD>
00406   void
00407   Event::getManyByType(std::vector<Handle<PROD> >& results) const {
00408     provRecorder_.getManyByType(results);
00409     for (typename std::vector<Handle<PROD> >::const_iterator it = results.begin(), itEnd = results.end();
00410         it != itEnd; ++it) {
00411       addToGotBranchIDs(*it->provenance());
00412     }
00413   }
00414 
00415   template <typename ELEMENT>
00416   bool
00417   Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT> >& result) const {
00418     return getByLabel(moduleLabel, std::string(), result);
00419   }
00420 
00421   template <typename ELEMENT>
00422   bool
00423   Event::getByLabel(std::string const& moduleLabel,
00424                     std::string const& productInstanceName,
00425                     Handle<View<ELEMENT> >& result) const {
00426     result.clear();
00427 
00428     TypeID typeID(typeid(ELEMENT));
00429 
00430     BasicHandle bh;
00431     int nFound = provRecorder_.getMatchingSequenceByLabel_(typeID,
00432                                                            moduleLabel,
00433                                                            productInstanceName,
00434                                                            bh);
00435 
00436     if (nFound == 0) {
00437       boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound));
00438       *whyFailed
00439         << "getByLabel: Found zero products matching all criteria\n"
00440         << "Looking for sequence of type: " << typeID << "\n"
00441         << "Looking for module label: " << moduleLabel << "\n"
00442         << "Looking for productInstanceName: " << productInstanceName << "\n";
00443       Handle<View<ELEMENT> > temp(whyFailed);
00444       result.swap(temp);
00445       return false;
00446     }
00447     if (nFound > 1) {
00448       Exception e(errors::ProductNotFound);
00449       e << "getByLabel: Found more than one product matching all criteria\n"
00450         << "Looking for sequence of type: " << typeID << "\n"
00451         << "Looking for module label: " << moduleLabel << "\n"
00452         << "Looking for productInstanceName: " << productInstanceName << "\n";
00453       e.raise();
00454     }
00455 
00456     fillView_(bh, result);
00457     return true;
00458   }
00459 
00460   template <typename ELEMENT>
00461     bool
00462     Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT> >& result) const {
00463     result.clear();
00464     if (tag.process().empty()) {
00465       return getByLabel(tag.label(), tag.instance(), result);
00466     } else {
00467       TypeID typeID(typeid(ELEMENT));
00468 
00469       BasicHandle bh;
00470       int nFound = provRecorder_.getMatchingSequenceByLabel_(typeID,
00471                                                              tag.label(),
00472                                                              tag.instance(),
00473                                                              tag.process(),
00474                                                              bh);
00475 
00476       if (nFound == 0) {
00477         boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound));
00478         *whyFailed
00479           << "getByLabel: Found zero products matching all criteria\n"
00480           << "Looking for sequence of type: " << typeID << "\n"
00481           << "Looking for module label: " << tag.label() << "\n"
00482           << "Looking for productInstanceName: " << tag.instance() << "\n"
00483           << "Looking for processName: "<<tag.process() <<"\n";
00484         Handle<View<ELEMENT> > temp(whyFailed);
00485         result.swap(temp);
00486         return false;
00487       }
00488       if (nFound > 1) {
00489         Exception e (errors::ProductNotFound);
00490         e << "getByLabel: Found more than one product matching all criteria\n"
00491           << "Looking for sequence of type: " << typeID << "\n"
00492           << "Looking for module label: " << tag.label() << "\n"
00493           << "Looking for productInstanceName: " << tag.instance() << "\n"
00494           << "Looking for processName: "<<tag.process() <<"\n";
00495         e.raise();
00496       }
00497 
00498       fillView_(bh, result);
00499       return true;
00500     }
00501     return false;
00502   }
00503 
00504   template <typename ELEMENT>
00505   void
00506   Event::fillView_(BasicHandle& bh, Handle<View<ELEMENT> >& result) const {
00507     std::vector<void const*> pointersToElements;
00508     // the following is a shared pointer.
00509     // It is not initialized here
00510     helper_vector_ptr helpers;
00511     // the following must initialize the
00512     //  shared pointer and fill the helper vector
00513     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
00514 
00515     boost::shared_ptr<View<ELEMENT> >
00516       newview(new View<ELEMENT>(pointersToElements, helpers));
00517 
00518     addToGotBranchIDs(*bh.provenance());
00519     gotViews_.push_back(newview);
00520     Handle<View<ELEMENT> > h(&*newview, bh.provenance());
00521     result.swap(h);
00522   }
00523 }
00524 #endif