CMSSW/ FWCore/ Framework/ interface/ Event.h

The primary interface for accessing EDProducts from a single collision and inserting new derived products.

001 #ifndef FWCore_Framework_Event_h
002 #define FWCore_Framework_Event_h
003 
004 // -*- C++ -*-
005 //
006 // Package:     Framework
007 // Class  :     Event
008 //
009 /**\class Event Event.h FWCore/Framework/interface/Event.h
010 
011 Description: This is the primary interface for accessing EDProducts
012 from a single collision and inserting new derived products.
013 
014 For its usage, see "FWCore/Framework/interface/PrincipalGetAdapter.h"
015 
016 */
017 /*----------------------------------------------------------------------
018 ----------------------------------------------------------------------*/
019 
020 #include <memory>
021 #include <string>
022 #include <set>
023 #include <vector>
024 
025 #include "boost/shared_ptr.hpp"
026 
027 #include "DataFormats/Provenance/interface/EventID.h"
028 #include "DataFormats/Provenance/interface/EventSelectionID.h"
029 #include "DataFormats/Provenance/interface/ProductID.h"
030 #include "DataFormats/Provenance/interface/RunID.h"
031 
032 #include "FWCore/Common/interface/EventBase.h"
033 
034 #include "DataFormats/Common/interface/BasicHandle.h"
035 #include "DataFormats/Common/interface/Handle.h"
036 #include "DataFormats/Common/interface/OrphanHandle.h"
037 #include "DataFormats/Common/interface/Wrapper.h"
038 
039 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
040 #include "FWCore/Framework/interface/Frameworkfwd.h"
041 
042 namespace edm {
043 
044   class ConstBranchDescription;
045   class TriggerResultsByName;
046   class TriggerResults;
047   class TriggerNames;
048 
049   class Event : public EventBase {
050   public:
051     Event(EventPrincipal& ep, ModuleDescription const& md);
052     ~Event();
053 
054     // AUX functions are defined in EventBase
055     EventAuxiliary const& eventAuxiliary() const {return aux_;}
056 
057     LuminosityBlock const&
058     getLuminosityBlock() const {
059       return *luminosityBlock_;
060     }
061 
062     Run const&
063     getRun() const;
064 
065     RunNumber_t
066     run() const {return id().run();}
067 
068     template <typename PROD>
069     bool
070     get(ProductID const& oid, Handle<PROD>& result) const;
071 
072     // Template member overload to deal with Views.
073     template <typename ELEMENT>
074     bool
075     get(ProductID const& oid, Handle<View<ELEMENT> >& result) const ;
076 
077     EventSelectionIDVector const& eventSelectionIDs() const;
078 
079     ProcessHistoryID const& processHistoryID() const;
080 
081     ///Put a new product.
082     template <typename PROD>
083     OrphanHandle<PROD>
084     put(std::auto_ptr<PROD> product) {return put<PROD>(product, std::string());}
085 
086     ///Put a new product with a 'product instance name'
087     template <typename PROD>
088     OrphanHandle<PROD>
089     put(std::auto_ptr<PROD> product, std::string const& productInstanceName);
090 
091     ///Returns a RefProd to a product before that product has been placed into the Event.
092     /// The RefProd (and any Ref's made from it) will no work properly until after the
093     /// Event has been committed (which happens after leaving the EDProducer::produce method)
094     template <typename PROD>
095     RefProd<PROD>
096     getRefBeforePut() {return getRefBeforePut<PROD>(std::string());}
097 
098     template <typename PROD>
099     RefProd<PROD>
100     getRefBeforePut(std::string const& productInstanceName);
101 
102     template <typename PROD>
103     bool
104     get(SelectorBase const& sel, Handle<PROD>& result) const;
105 
106     template <typename PROD>
107     bool
108     getByLabel(InputTag const& tag, Handle<PROD>& result) const;
109 
110     template <typename PROD>
111     bool
112     getByLabel(std::string const& label, Handle<PROD>& result) const;
113 
114     template <typename PROD>
115     bool
116     getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const;
117 
118     template <typename PROD>
119     void
120     getMany(SelectorBase const& sel, std::vector<Handle<PROD> >& results) const;
121 
122     template <typename PROD>
123     bool
124     getByType(Handle<PROD>& result) const;
125 
126     template <typename PROD>
127     void
128     getManyByType(std::vector<Handle<PROD> >& results) const;
129 
130     // Template member overload to deal with Views.
131     template <typename ELEMENT>
132     bool
133     getByLabel(std::string const& label,
134                Handle<View<ELEMENT> >& result) const;
135 
136     template <typename ELEMENT>
137     bool
138     getByLabel(std::string const& label,
139                std::string const& productInstanceName,
140                Handle<View<ELEMENT> >& result) const;
141 
142     template <typename ELEMENT>
143     bool
144     getByLabel(InputTag const& tag, Handle<View<ELEMENT> >& result) const;
145 
146     template <typename ELEMENT>
147     void
148     fillView_(BasicHandle& bh,
149               Handle<View<ELEMENT> >& result) const;
150 
151     Provenance
152     getProvenance(BranchID const& theID) const;
153 
154     Provenance
155     getProvenance(ProductID const& theID) const;
156 
157     void
158     getAllProvenance(std::vector<Provenance const*>& provenances) const;
159 
160     // Return true if this Event has been subjected to a process with
161     // the given processName, and false otherwise.
162     // If true is returned, then ps is filled with the ParameterSet
163     // used to configure the identified process.
164     bool
165     getProcessParameterSet(std::string const& processName, ParameterSet& ps) const;
166 
167     ProcessHistory const&
168     processHistory() const;
169 
170     size_t size() const;
171 
172     virtual edm::TriggerNames const& triggerNames(edm::TriggerResults const& triggerResults) const;
173     virtual TriggerResultsByName triggerResultsByName(std::string const& process) const;
174 
175     typedef std::vector<std::pair<EDProduct*, ConstBranchDescription const*> > ProductPtrVec;
176 
177   private:
178     EventPrincipal const&
179     eventPrincipal() const;
180 
181     EventPrincipal&
182     eventPrincipal();
183 
184     ProductID
185     makeProductID(ConstBranchDescription const& desc) const;
186 
187     //override used by EventBase class
188     virtual BasicHandle getByLabelImpl(const std::type_info& iWrapperType, const std::type_info& iProductType, const InputTag& iTag) const;
189 
190     // commit_() is called to complete the transaction represented by
191     // this PrincipalGetAdapter. The friendships required seems gross, but any
192     // alternative is not great either.  Putting it into the
193     // public interface is asking for trouble
194     friend class ConfigurableInputSource;
195     friend class DaqSource;
196     friend class InputSource;
197     friend class RawInputSource;
198     friend class EDFilter;
199     friend class EDProducer;
200 
201     void commit_(std::vector<BranchID>* previousParentage=0, ParentageID* previousParentageId=0);
202     void commit_aux(ProductPtrVec& products, bool record_parents, std::vector<BranchID>* previousParentage=0, ParentageID* previousParentageId=0);
203 
204     BasicHandle
205     getByProductID_(ProductID const& oid) const;
206 
207     ProductPtrVec& putProducts() {return putProducts_;}
208     ProductPtrVec const& putProducts() const {return putProducts_;}
209 
210     ProductPtrVec& putProductsWithoutParents() {return putProductsWithoutParents_;}
211     ProductPtrVec const& putProductsWithoutParents() const {return putProductsWithoutParents_;}
212 
213 
214     PrincipalGetAdapter provRecorder_;
215 
216     // putProducts_ and putProductsWithoutParents_ are the holding
217     // pens for EDProducts inserted into this PrincipalGetAdapter. Pointers
218     // in these collections own the products to which they point.
219     //
220     ProductPtrVec putProducts_;               // keep parentage info for these
221     ProductPtrVec putProductsWithoutParents_; // ... but not for these
222 
223     EventAuxiliary const& aux_;
224     boost::shared_ptr<LuminosityBlock const> const luminosityBlock_;
225 
226     // gotBranchIDs_ must be mutable because it records all 'gets',
227     // which do not logically modify the PrincipalGetAdapter. gotBranchIDs_ is
228     // merely a cache reflecting what has been retreived from the
229     // Principal class.
230     typedef std::set<BranchID> BranchIDSet;
231     mutable BranchIDSet gotBranchIDs_;
232     void addToGotBranchIDs(Provenance const& prov) const;
233 
234     // We own the retrieved Views, and have to destroy them.
235     mutable std::vector<boost::shared_ptr<ViewBase> > gotViews_;
236   };
237 
238   // The following functions objects are used by Event::put, under the
239   // control of a metafunction if, to put the given pair into the
240   // right collection.
241   template <typename PROD>
242   struct RecordInParentless {
243     typedef Event::ProductPtrVec ptrvec_t;
244     void do_it(ptrvec_t& ignored,
245                ptrvec_t& used,
246                Wrapper<PROD>* wp,
247                ConstBranchDescription const* desc) const {
248       used.push_back(std::make_pair(wp, desc));
249     }
250   };
251 
252   template <typename PROD>
253   struct RecordInParentfull {
254     typedef Event::ProductPtrVec ptrvec_t;
255 
256     void do_it(ptrvec_t& used,
257                ptrvec_t& ignored,
258                Wrapper<PROD>* wp,
259                ConstBranchDescription const* desc) const {
260       used.push_back(std::make_pair(wp, desc));
261     }
262   };
263 
264 
265   template <typename PROD>
266   bool
267   Event::get(ProductID const& oid, Handle<PROD>& result) const
268   {
269     result.clear();
270     BasicHandle bh = this->getByProductID_(oid);
271     convert_handle(bh, result);  // throws on conversion error
272     if (bh.failedToGet()) {
273       return false;
274     }
275     addToGotBranchIDs(*bh.provenance());
276     return true;
277   }
278 
279   template <typename ELEMENT>
280   bool
281   Event::get(ProductID const& oid, Handle<View<ELEMENT> >& result) const
282   {
283       result.clear();
284       BasicHandle bh = this->getByProductID_(oid);
285 
286       if(bh.failedToGet()) {
287           boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound) );
288           *whyFailed
289               << "get View by ID failed: no product with ID = " << oid <<"\n";
290           Handle<View<ELEMENT> > temp(whyFailed);
291           result.swap(temp);
292           return false;
293       }
294 
295       fillView_(bh, result);
296       return true;
297   }
298 
299   template <typename PROD>
300   OrphanHandle<PROD>
301   Event::put(std::auto_ptr<PROD> product, std::string const& productInstanceName)
302   {
303     if (product.get() == 0) {                // null pointer is illegal
304       TypeID typeID(typeid(PROD));
305       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
306     }
307 
308     // The following will call post_insert if T has such a function,
309     // and do nothing if T has no such function.
310     typename boost::mpl::if_c<detail::has_postinsert<PROD>::value,
311       DoPostInsert<PROD>,
312       DoNotPostInsert<PROD> >::type maybe_inserter;
313     maybe_inserter(product.get());
314 
315     ConstBranchDescription const& desc =
316       provRecorder_.getBranchDescription(TypeID(*product), productInstanceName);
317 
318     Wrapper<PROD>* wp(new Wrapper<PROD>(product));
319 
320     typename boost::mpl::if_c<detail::has_donotrecordparents<PROD>::value,
321       RecordInParentless<PROD>,
322       RecordInParentfull<PROD> >::type parentage_recorder;
323     parentage_recorder.do_it(putProducts(),
324                              putProductsWithoutParents(),
325                              wp,
326                              &desc);
327 
328     //    putProducts().push_back(std::make_pair(wp, &desc));
329 
330     // product.release(); // The object has been copied into the Wrapper.
331     // The old copy must be deleted, so we cannot release ownership.
332 
333     return(OrphanHandle<PROD>(wp->product(), makeProductID(desc)));
334   }
335 
336   template <typename PROD>
337   RefProd<PROD>
338   Event::getRefBeforePut(std::string const& productInstanceName) {
339     PROD* p = 0;
340     ConstBranchDescription const& desc =
341       provRecorder_.getBranchDescription(TypeID(*p), productInstanceName);
342 
343     //should keep track of what Ref's have been requested and make sure they are 'put'
344     return RefProd<PROD>(makeProductID(desc), provRecorder_.prodGetter());
345   }
346 
347   template <typename PROD>
348   bool
349   Event::get(SelectorBase const& sel, Handle<PROD>& result) const {
350     bool ok = provRecorder_.get(sel, result);
351     if (ok) {
352       addToGotBranchIDs(*result.provenance());
353     }
354     return ok;
355   }
356 
357   template <typename PROD>
358   bool
359   Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const
360   {
361     bool ok = provRecorder_.getByLabel(tag, result);
362     if (ok) {
363       addToGotBranchIDs(*result.provenance());
364     }
365     return ok;
366   }
367 
368   template <typename PROD>
369   bool
370   Event::getByLabel(std::string const& label, Handle<PROD>& result) const
371   {
372     bool ok = provRecorder_.getByLabel(label, result);
373     if (ok) {
374       addToGotBranchIDs(*result.provenance());
375     }
376     return ok;
377   }
378 
379   template <typename PROD>
380   bool
381   Event::getByLabel(std::string const& label,
382                     std::string const& productInstanceName,
383                     Handle<PROD>& result) const {
384     bool ok = provRecorder_.getByLabel(label, productInstanceName, result);
385     if (ok) {
386       addToGotBranchIDs(*result.provenance());
387     }
388     return ok;
389   }
390 
391   template <typename PROD>
392   void
393   Event::getMany(SelectorBase const& sel, std::vector<Handle<PROD> >& results) const {
394     provRecorder_.getMany(sel, results);
395     for (typename std::vector<Handle<PROD> >::const_iterator it = results.begin(), itEnd = results.end();
396         it != itEnd; ++it) {
397       addToGotBranchIDs(*it->provenance());
398     }
399   }
400 
401   template <typename PROD>
402   bool
403   Event::getByType(Handle<PROD>& result) const
404   {
405     bool ok = provRecorder_.getByType(result);
406     if (ok) {
407       addToGotBranchIDs(*result.provenance());
408     }
409     return ok;
410   }
411 
412   template <typename PROD>
413   void
414   Event::getManyByType(std::vector<Handle<PROD> >& results) const
415   {
416     provRecorder_.getManyByType(results);
417     for (typename std::vector<Handle<PROD> >::const_iterator it = results.begin(), itEnd = results.end();
418         it != itEnd; ++it) {
419       addToGotBranchIDs(*it->provenance());
420     }
421   }
422 
423   template <typename ELEMENT>
424   bool
425   Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT> >& result) const {
426     return getByLabel(moduleLabel, std::string(), result);
427   }
428 
429   template <typename ELEMENT>
430   bool
431   Event::getByLabel(std::string const& moduleLabel,
432                     std::string const& productInstanceName,
433                     Handle<View<ELEMENT> >& result) const {
434     result.clear();
435 
436     TypeID typeID(typeid(ELEMENT));
437 
438     BasicHandle bh;
439     int nFound = provRecorder_.getMatchingSequenceByLabel_(typeID,
440                                                            moduleLabel,
441                                                            productInstanceName,
442                                                            bh);
443 
444     if (nFound == 0) {
445       boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound) );
446       *whyFailed
447         << "getByLabel: Found zero products matching all criteria\n"
448         << "Looking for sequence of type: " << typeID << "\n"
449         << "Looking for module label: " << moduleLabel << "\n"
450         << "Looking for productInstanceName: " << productInstanceName << "\n";
451       Handle<View<ELEMENT> > temp(whyFailed);
452       result.swap(temp);
453       return false;
454     }
455     if (nFound > 1) {
456       Exception e(errors::ProductNotFound);
457       e << "getByLabel: Found more than one product matching all criteria\n"
458         << "Looking for sequence of type: " << typeID << "\n"
459         << "Looking for module label: " << moduleLabel << "\n"
460         << "Looking for productInstanceName: " << productInstanceName << "\n";
461       e.raise();
462     }
463 
464     fillView_(bh, result);
465     return true;
466   }
467 
468   template <typename ELEMENT>
469     bool
470     Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT> >& result) const
471   {
472     result.clear();
473     if (tag.process().empty()) {
474       return getByLabel(tag.label(), tag.instance(), result);
475     } else {
476       TypeID typeID(typeid(ELEMENT));
477 
478       BasicHandle bh;
479       int nFound = provRecorder_.getMatchingSequenceByLabel_(typeID,
480                                                              tag.label(),
481                                                              tag.instance(),
482                                                              tag.process(),
483                                                              bh);
484 
485       if (nFound == 0) {
486         boost::shared_ptr<cms::Exception> whyFailed(new edm::Exception(edm::errors::ProductNotFound) );
487         *whyFailed
488           << "getByLabel: Found zero products matching all criteria\n"
489           << "Looking for sequence of type: " << typeID << "\n"
490           << "Looking for module label: " << tag.label() << "\n"
491           << "Looking for productInstanceName: " << tag.instance() << "\n"
492           << "Looking for processName: "<<tag.process() <<"\n";
493         Handle<View<ELEMENT> > temp(whyFailed);
494         result.swap(temp);
495         return false;
496       }
497       if (nFound > 1) {
498         Exception e (errors::ProductNotFound);
499         e << "getByLabel: Found more than one product matching all criteria\n"
500           << "Looking for sequence of type: " << typeID << "\n"
501           << "Looking for module label: " << tag.label() << "\n"
502           << "Looking for productInstanceName: " << tag.instance() << "\n"
503           << "Looking for processName: "<<tag.process() <<"\n";
504         e.raise();
505       }
506 
507       fillView_(bh, result);
508       return true;
509     }
510     return false;
511   }
512 
513   template <typename ELEMENT>
514   void
515   Event::fillView_(BasicHandle& bh, Handle<View<ELEMENT> >& result) const {
516     std::vector<void const*> pointersToElements;
517     // the following is a shared pointer.
518     // It is not initialized here
519     helper_vector_ptr helpers;
520     // the following must initialize the
521     //  shared pointer and fill the helper vector
522     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
523 
524     boost::shared_ptr<View<ELEMENT> >
525       newview(new View<ELEMENT>(pointersToElements, helpers));
526 
527     addToGotBranchIDs(*bh.provenance());
528     gotViews_.push_back(newview);
529     Handle<View<ELEMENT> > h(&*newview, bh.provenance());
530     result.swap(h);
531   }
532 
533 }
534 #endif

-- DavidCockerill - 24-Aug-2010

Edit | Attach | Watch | Print version | History: r1 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r1 - 2010-08-24 - DavidCockerill
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Main All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright &© 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback