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