CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EventPrincipal.cc
Go to the documentation of this file.
2 
23 
24 #include <algorithm>
25 #include <cassert>
26 #include <limits>
27 #include <memory>
28 
29 namespace edm {
31  std::shared_ptr<ProductRegistry const> reg,
32  std::shared_ptr<BranchIDListHelper const> branchIDListHelper,
33  std::shared_ptr<ThinnedAssociationsHelper const> thinnedAssociationsHelper,
34  ProcessConfiguration const& pc,
35  HistoryAppender* historyAppender,
36  unsigned int streamIndex) :
37  Base(reg, reg->productLookup(InEvent), pc, InEvent, historyAppender),
38  aux_(),
39  luminosityBlockPrincipal_(),
40  provRetrieverPtr_(new ProductProvenanceRetriever(streamIndex)),
41  unscheduledHandler_(),
42  moduleLabelsRunning_(),
43  eventSelectionIDs_(),
44  branchIDListHelper_(branchIDListHelper),
45  thinnedAssociationsHelper_(thinnedAssociationsHelper),
46  branchListIndexes_(),
47  branchListIndexToProcessIndex_(),
48  streamID_(streamIndex) {
50  }
51 
52  void
55  aux_ = EventAuxiliary();
57  provRetrieverPtr_->reset();
58  unscheduledHandler_.reset();
59  moduleLabelsRunning_.clear();
61  }
62 
63  void
65  ProcessHistoryRegistry const& processHistoryRegistry,
66  EventSelectionIDVector&& eventSelectionIDs,
67  BranchListIndexes&& branchListIndexes,
68  ProductProvenanceRetriever& provRetriever,
71  provRetrieverPtr_->deepSwap(provRetriever);
73  if(branchIDListHelper_->hasProducedProducts()) {
74  // Add index into BranchIDListRegistry for products produced this process
75  branchListIndexes_.push_back(branchIDListHelper_->producedBranchListIndex());
76  }
77  fillEventPrincipal(aux,processHistoryRegistry,reader);
78  }
79 
80  void
82  ProcessHistoryRegistry const& processHistoryRegistry,
83  EventSelectionIDVector&& eventSelectionIDs,
84  BranchListIndexes&& branchListIndexes) {
87  if(branchIDListHelper_->hasProducedProducts()) {
88  // Add index into BranchIDListRegistry for products produced this process
89  branchListIndexes_.push_back(branchIDListHelper_->producedBranchListIndex());
90  }
91  fillEventPrincipal(aux,processHistoryRegistry,nullptr);
92  }
93 
94  void
96  ProcessHistoryRegistry const& processHistoryRegistry,
98  if(aux.event() == invalidEventNumber) {
100  << "EventPrincipal::fillEventPrincipal, Invalid event number provided in EventAuxiliary, It is illegal for the event number to be 0\n";
101  }
102 
103  fillPrincipal(aux.processHistoryID(), processHistoryRegistry, reader);
104  aux_ = aux;
106 
107  if(branchListIndexes_.empty() and branchIDListHelper_->hasProducedProducts()) {
108  // Add index into BranchIDListRegistry for products produced this process
109  // if it hasn't already been filled in by the other fillEventPrincipal or by an earlier call to this function
110  branchListIndexes_.push_back(branchIDListHelper_->producedBranchListIndex());
111  }
112 
113  // Fill in helper map for Branch to ProductID mapping
114  ProcessIndex pix = 0;
115  for(auto const& blindex : branchListIndexes_) {
116  branchListIndexToProcessIndex_.insert(std::make_pair(blindex, pix));
117  ++pix;
118  }
119 
120  // Fill in the product ID's in the product holders.
121  for(auto const& prod : *this) {
122  if (prod->singleProduct()) {
123  prod->setProvenance(productProvenanceRetrieverPtr(), processHistory(), branchIDToProductID(prod->branchDescription().branchID()));
124  }
125  }
126  }
127 
128  void
129  EventPrincipal::setLuminosityBlockPrincipal(std::shared_ptr<LuminosityBlockPrincipal> const& lbp) {
131  }
132 
133  void
135  assert(run == luminosityBlockPrincipal_->run());
136  assert(lumi == luminosityBlockPrincipal_->luminosityBlock());
137  EventNumber_t event = aux_.id().event();
138  aux_.id() = EventID(run, lumi, event);
139  }
140 
141  RunPrincipal const&
144  }
145 
146  void
148  BranchDescription const& bd,
149  std::unique_ptr<WrapperBase> edp,
150  ProductProvenance const& productProvenance) {
151 
152  // assert commented out for DaqSource. When DaqSource no longer uses put(), the assert can be restored.
153  //assert(produced());
154  if(edp.get() == nullptr) {
155  throw Exception(errors::InsertFailure, "Null Pointer")
156  << "put: Cannot put because ptr to product is null."
157  << "\n";
158  }
159  productProvenanceRetrieverPtr()->insertIntoSet(productProvenance);
161  assert(phb);
162  checkUniquenessAndType(edp.get(), phb);
163  // ProductHolder assumes ownership
164  phb->putProduct(std::move(edp), productProvenance);
165  }
166 
167  void
169  BranchDescription const& bd,
170  std::unique_ptr<WrapperBase> edp,
171  ProductProvenance const& productProvenance) {
172 
173  assert(!bd.produced());
174  productProvenanceRetrieverPtr()->insertIntoSet(productProvenance);
176  assert(phb);
177  checkUniquenessAndType(edp.get(), phb);
178  // ProductHolder assumes ownership
179  phb->putProduct(std::move(edp), productProvenance);
180  }
181 
182  void
184  if(phb.branchDescription().produced()) return; // nothing to do.
185  if(phb.product()) return; // nothing to do.
186  if(phb.productUnavailable()) return; // nothing to do.
187  if(!reader()) return; // nothing to do.
188 
189  // must attempt to load from persistent store
190  BranchKey const bk = BranchKey(phb.branchDescription());
191  {
192  if(mcc) {
194  }
195  std::shared_ptr<void> guard(nullptr,[this,mcc](const void*){
196  if(mcc) {
198  }
199  });
200 
201  std::unique_ptr<WrapperBase> edp(reader()->getProduct(bk, this));
202 
203  // Now fix up the ProductHolder
204  checkUniquenessAndType(edp.get(), &phb);
205  phb.putProduct(std::move(edp));
206  }
207  }
208 
209  BranchID
211  if(!pid.isValid()) {
212  throw Exception(errors::ProductNotFound, "InvalidID")
213  << "get by product ID: invalid ProductID supplied\n";
214  }
215  return productIDToBranchID(pid, branchIDListHelper_->branchIDLists(), branchListIndexes_);
216  }
217 
218  ProductID
220  if(!bid.isValid()) {
221  throw Exception(errors::NotFound, "InvalidID")
222  << "branchIDToProductID: invalid BranchID supplied\n";
223  }
224  typedef BranchIDListHelper::BranchIDToIndexMap BIDToIndexMap;
225  typedef BIDToIndexMap::const_iterator Iter;
226  typedef std::pair<Iter, Iter> IndexRange;
227 
228  IndexRange range = branchIDListHelper_->branchIDToIndexMap().equal_range(bid);
229  for(Iter it = range.first; it != range.second; ++it) {
230  BranchListIndex blix = it->second.first;
231  std::map<BranchListIndex, ProcessIndex>::const_iterator i = branchListIndexToProcessIndex_.find(blix);
232  if(i != branchListIndexToProcessIndex_.end()) {
233  ProductIndex productIndex = it->second.second;
234  ProcessIndex processIndex = i->second;
235  return ProductID(processIndex+1, productIndex+1);
236  }
237  }
238  // cannot throw, because some products may legitimately not have product ID's (e.g. pile-up).
239  return ProductID();
240  }
241 
242  unsigned int
244  return streamID_.value();
245  }
246 
249  exception<<"get by product ID: The product with given id: "<<pid
250  <<"\ntype: "<<phb->productType()
251  <<"\nproduct instance name: "<<phb->productInstanceName()
252  <<"\nprocess name: "<<phb->processName()
253  <<"\nwas already deleted. This is a configuration error. Please change the configuration of the module which caused this exception to state it reads this data.";
254  throw exception;
255  }
256 
257  BasicHandle
259  BranchID bid = pidToBid(pid);
260  ConstProductHolderPtr const phb = getProductHolder(bid);
261  if(phb == nullptr) {
262  return BasicHandle(makeHandleExceptionFactory([pid]()->std::shared_ptr<cms::Exception> {
263  std::shared_ptr<cms::Exception> whyFailed(std::make_shared<Exception>(errors::ProductNotFound, "InvalidID"));
264  *whyFailed
265  << "get by product ID: no product with given id: " << pid << "\n";
266  return whyFailed;
267  }));
268  }
269 
270  // Was this already deleted?
271  if(phb->productWasDeleted()) {
273  }
274  // Check for case where we tried on demand production and
275  // it failed to produce the object
276  if(phb->onDemand()) {
277  return BasicHandle(makeHandleExceptionFactory([pid]()->std::shared_ptr<cms::Exception> {
278  std::shared_ptr<cms::Exception> whyFailed(std::make_shared<Exception>(errors::ProductNotFound, "InvalidID"));
279  *whyFailed
280  << "get by ProductID: could not get product with id: " << pid << "\n"
281  << "Unscheduled execution not allowed to get via ProductID.\n";
282  return whyFailed;
283  }));
284  }
286  phb->resolveProduct(status,false,nullptr);
287 
288  return BasicHandle(phb->productData());
289  }
290 
291  WrapperBase const*
293  return getByProductID(pid).wrapper();
294  }
295 
296  WrapperBase const*
297  EventPrincipal::getThinnedProduct(ProductID const& pid, unsigned int& key) const {
298 
299  BranchID parent = pidToBid(pid);
300 
301  // Loop over thinned containers which were made by selecting elements from the parent container
302  for(auto associatedBranches = thinnedAssociationsHelper_->parentBegin(parent),
303  iEnd = thinnedAssociationsHelper_->parentEnd(parent);
304  associatedBranches != iEnd; ++associatedBranches) {
305 
306  ThinnedAssociation const* thinnedAssociation =
307  getThinnedAssociation(associatedBranches->association());
308  if(thinnedAssociation == nullptr) continue;
309 
310  if(associatedBranches->parent() != pidToBid(thinnedAssociation->parentCollectionID())) {
311  continue;
312  }
313 
314  unsigned int thinnedIndex = 0;
315  // Does this thinned container have the element referenced by key?
316  // If yes, thinnedIndex is set to point to it in the thinned container
317  if(!thinnedAssociation->hasParentIndex(key, thinnedIndex)) {
318  continue;
319  }
320  // Get the thinned container and return a pointer if we can find it
321  ProductID const& thinnedCollectionPID = thinnedAssociation->thinnedCollectionID();
322  BasicHandle bhThinned = getByProductID(thinnedCollectionPID);
323  if(!bhThinned.isValid()) {
324  // Thinned container is not found, try looking recursively in thinned containers
325  // which were made by selecting elements from this thinned container.
326  WrapperBase const* wrapperBase = getThinnedProduct(thinnedCollectionPID, thinnedIndex);
327  if(wrapperBase != nullptr) {
328  key = thinnedIndex;
329  return wrapperBase;
330  } else {
331  continue;
332  }
333  }
334  key = thinnedIndex;
335  return bhThinned.wrapper();
336  }
337  return nullptr;
338  }
339 
340  void
342  std::vector<WrapperBase const*>& foundContainers,
343  std::vector<unsigned int>& keys) const {
344 
345  BranchID parent = pidToBid(pid);
346 
347  // Loop over thinned containers which were made by selecting elements from the parent container
348  for(auto associatedBranches = thinnedAssociationsHelper_->parentBegin(parent),
349  iEnd = thinnedAssociationsHelper_->parentEnd(parent);
350  associatedBranches != iEnd; ++associatedBranches) {
351 
352  ThinnedAssociation const* thinnedAssociation =
353  getThinnedAssociation(associatedBranches->association());
354  if(thinnedAssociation == nullptr) continue;
355 
356  if(associatedBranches->parent() != pidToBid(thinnedAssociation->parentCollectionID())) {
357  continue;
358  }
359 
360  unsigned nKeys = keys.size();
361  unsigned int doNotLookForThisIndex = std::numeric_limits<unsigned int>::max();
362  std::vector<unsigned int> thinnedIndexes(nKeys, doNotLookForThisIndex);
363  bool hasAny = false;
364  for(unsigned k = 0; k < nKeys; ++k) {
365  // Already found this one
366  if(foundContainers[k] != nullptr) continue;
367  // Already know this one is not in this thinned container
368  if(keys[k] == doNotLookForThisIndex) continue;
369  // Does the thinned container hold the entry of interest?
370  // Modifies thinnedIndexes[k] only if it returns true and
371  // sets it to the index in the thinned collection.
372  if(thinnedAssociation->hasParentIndex(keys[k], thinnedIndexes[k])) {
373  hasAny = true;
374  }
375  }
376  if(!hasAny) {
377  continue;
378  }
379  // Get the thinned container and set the pointers and indexes into
380  // it (if we can find it)
381  ProductID thinnedCollectionPID = thinnedAssociation->thinnedCollectionID();
382  BasicHandle bhThinned = getByProductID(thinnedCollectionPID);
383  if(!bhThinned.isValid()) {
384  // Thinned container is not found, try looking recursively in thinned containers
385  // which were made by selecting elements from this thinned container.
386  getThinnedProducts(thinnedCollectionPID, foundContainers, thinnedIndexes);
387  for(unsigned k = 0; k < nKeys; ++k) {
388  if(foundContainers[k] == nullptr) continue;
389  if(thinnedIndexes[k] == doNotLookForThisIndex) continue;
390  keys[k] = thinnedIndexes[k];
391  }
392  } else {
393  for(unsigned k = 0; k < nKeys; ++k) {
394  if(thinnedIndexes[k] == doNotLookForThisIndex) continue;
395  keys[k] = thinnedIndexes[k];
396  foundContainers[k] = bhThinned.wrapper();
397  }
398  }
399  }
400  }
401 
402  Provenance
404  BranchID bid = pidToBid(pid);
405  return getProvenance(bid, mcc);
406  }
407 
408  void
409  EventPrincipal::setUnscheduledHandler(std::shared_ptr<UnscheduledHandler> iHandler) {
410  unscheduledHandler_ = iHandler;
411  }
412 
413  std::shared_ptr<UnscheduledHandler>
415  return unscheduledHandler_;
416  }
417 
420  return eventSelectionIDs_;
421  }
422 
423  BranchListIndexes const&
425  return branchListIndexes_;
426  }
427 
430 
431  ConstProductHolderPtr const phb = getProductHolder(branchID);
432 
433  if(phb == nullptr) {
435  << "EventPrincipal::getThinnedAssociation, ThinnedAssociation ProductHolder cannot be found\n"
436  << "This should never happen. Contact a Framework developer";
437  }
439  ProductData const* productData = phb->resolveProduct(status,false,nullptr);
440  if (productData == nullptr) {
441  return nullptr;
442  }
443  WrapperBase const* product = productData->wrapper_.get();
444  if(!(typeid(edm::ThinnedAssociation) == product->dynamicTypeInfo())) {
446  << "EventPrincipal::getThinnedProduct, product has wrong type, not a ThinnedAssociation.\n";
447  }
449  return wrapper->product();
450  }
451 
452  bool
454  ModuleCallingContext const* mcc) const {
455 
456  // If it is a module already currently running in unscheduled
457  // mode, then there is a circular dependency related to which
458  // EDProducts modules require and produce. There is no safe way
459  // to recover from this. Here we check for this problem and throw
460  // an exception.
461  std::vector<std::string>::const_iterator i =
462  find_in_all(moduleLabelsRunning_, moduleLabel);
463 
464  if(i != moduleLabelsRunning_.end()) {
466  << "Hit circular dependency while trying to run an unscheduled module.\n"
467  << "The last module on the stack shown above requested data from the\n"
468  << "module with label: '" << moduleLabel << "'.\n"
469  << "This is illegal because this module is already running (it is in the\n"
470  << "stack shown above, it might or might not be asking for data from itself).\n"
471  << "More information related to resolving circular dependences can be found here:\n"
472  << "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideUnscheduledExecution#Circular_Dependence_Errors.";
473  }
474 
475  UnscheduledSentry sentry(&moduleLabelsRunning_, moduleLabel);
476 
477  if(unscheduledHandler_) {
478  if(mcc == nullptr) {
480  << "EventPrincipal::unscheduledFill, Attempting to run unscheduled production\n"
481  << "with a null pointer to the ModuleCalling Context. This should never happen.\n"
482  << "Contact a Framework developer";
483  }
485  std::shared_ptr<void> guard(nullptr,[this,mcc](const void*){
487  });
488  unscheduledHandler_->tryToFill(moduleLabel, *const_cast<EventPrincipal*>(this), mcc);
489  }
490  return true;
491  }
492 }
RunPrincipal const & runPrincipal() const
std::shared_ptr< ThinnedAssociationsHelper const > thinnedAssociationsHelper_
EventNumber_t event() const
Definition: EventID.h:41
void clearPrincipal()
Definition: Principal.cc:304
int i
Definition: DBlmapReader.cc:9
unsigned short BranchListIndex
WrapperBase * product() const
Definition: ProductHolder.h:81
void setLuminosityBlockPrincipal(std::shared_ptr< LuminosityBlockPrincipal > const &lbp)
EventSelectionIDVector const & eventSelectionIDs() const
ConstProductHolderPtr getProductHolder(BranchID const &oid) const
Definition: Principal.cc:429
StreamContext const * getStreamContext() const
std::shared_ptr< LuminosityBlockPrincipal > luminosityBlockPrincipal_
list parent
Definition: dbtoconf.py:74
std::type_info const & dynamicTypeInfo() const
Definition: WrapperBase.h:37
std::shared_ptr< UnscheduledHandler > unscheduledHandler_
BasicHandle getByProductID(ProductID const &oid) const
EventSelectionIDVector eventSelectionIDs_
BranchID pidToBid(ProductID const &pid) const
tuple lumi
Definition: fjr2json.py:35
BranchListIndexes branchListIndexes_
edm::ThinnedAssociation const * getThinnedAssociation(edm::BranchID const &branchID) const
Provenance getProvenance(ProductID const &pid, ModuleCallingContext const *mcc) const
std::map< BranchListIndex, ProcessIndex > branchListIndexToProcessIndex_
unsigned long long EventNumber_t
std::shared_ptr< BranchIDListHelper const > branchIDListHelper_
virtual void readFromSource_(ProductHolderBase const &phb, ModuleCallingContext const *mcc) const override
EventAuxiliary aux_
void putOnRead(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp, ProductProvenance const &productProvenance)
bool isValid() const
Definition: BranchID.h:24
BranchListIndexes const & branchListIndexes() const
unsigned int LuminosityBlockNumber_t
ProcessHistory const & processHistory() const
Definition: Principal.h:137
ProductID branchIDToProductID(BranchID const &bid) const
RunPrincipal const & runPrincipal() const
std::vector< EventSelectionID > EventSelectionIDVector
virtual bool unscheduledFill(std::string const &moduleLabel, ModuleCallingContext const *mcc) const override
virtual WrapperBase const * getThinnedProduct(ProductID const &pid, unsigned int &key) const override
static void throwProductDeletedException(ProductID const &pid, edm::EventPrincipal::ConstProductHolderPtr const phb)
void setUnscheduledHandler(std::shared_ptr< UnscheduledHandler > iHandler)
EventNumber_t const invalidEventNumber
std::vector< BranchListIndex > BranchListIndexes
BranchDescription const & branchDescription() const
Definition: ProductHolder.h:90
BranchID productIDToBranchID(ProductID const &pid, BranchIDLists const &lists, BranchListIndexes const &indexes)
ProcessHistoryID const & processHistoryID() const
Definition: Principal.h:141
std::shared_ptr< ProductProvenanceRetriever > productProvenanceRetrieverPtr() const
LuminosityBlockPrincipal const & luminosityBlockPrincipal() const
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
void checkUniquenessAndType(WrapperBase const *prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:805
WrapperBase const * wrapper() const
Definition: BasicHandle.h:99
std::shared_ptr< WrapperBase > wrapper_
Definition: ProductData.h:46
virtual WrapperBase const * getIt(ProductID const &pid) const override
T const * getProduct(RefCore const &ref)
Definition: RefCoreGet.h:36
BranchID const & branchID() const
ProductID const & thinnedCollectionID() const
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
std::multimap< BranchID, IndexPair > BranchIDToIndexMap
unsigned short ProcessIndex
Definition: ProductID.h:25
DelayedReader * reader() const
Definition: Principal.h:171
unsigned int value() const
Definition: StreamID.h:46
ForwardSequence::const_iterator find_in_all(ForwardSequence const &s, Datum const &d)
wrappers for std::find
Definition: Algorithms.h:32
virtual unsigned int transitionIndex_() const override
void put(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp, ProductProvenance const &productProvenance)
T const * product() const
Definition: Wrapper.h:38
std::shared_ptr< UnscheduledHandler > unscheduledHandler() const
tuple pid
Definition: sysUtil.py:22
string const
Definition: compareJSON.py:14
void setProcessHistoryID(ProcessHistoryID const &phid)
bool isValid() const
Definition: BasicHandle.h:91
ProcessHistoryID const & processHistoryID() const
EventID const & id() const
void fillEventPrincipal(EventAuxiliary const &aux, ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
std::shared_ptr< ProductProvenanceRetriever > provRetrieverPtr_
list key
Definition: combine.py:13
Base::ConstProductHolderPtr ConstProductHolderPtr
unsigned short ProductIndex
Definition: ProductID.h:26
EventPrincipal(std::shared_ptr< ProductRegistry const > reg, std::shared_ptr< BranchIDListHelper const > branchIDListHelper, std::shared_ptr< ThinnedAssociationsHelper const > thinnedAssociationsHelper, ProcessConfiguration const &pc, HistoryAppender *historyAppender, unsigned int streamIndex=0)
unsigned int RunNumber_t
ProductID const & parentCollectionID() const
signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> preModuleDelayedGetSignal_
bool isValid() const
Definition: ProductID.h:35
tuple status
Definition: ntuplemaker.py:245
bool hasParentIndex(unsigned int parentIndex, unsigned int &thinnedIndex) const
void setRunAndLumiNumber(RunNumber_t run, LuminosityBlockNumber_t lumi)
void fillPrincipal(ProcessHistoryID const &hist, ProcessHistoryRegistry const &phr, DelayedReader *reader)
Definition: Principal.cc:327
EventAuxiliary const & aux() const
virtual void getThinnedProducts(ProductID const &pid, std::vector< WrapperBase const * > &foundContainers, std::vector< unsigned int > &keys) const override
void putProduct(std::unique_ptr< WrapperBase > edp, ProductProvenance const &productProvenance)
EventNumber_t event() const
void emit(Args &&...args) const
Definition: Signal.h:47
ProductHolderBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:383
std::vector< std::string > moduleLabelsRunning_
static HepMC::HEPEVT_Wrapper wrapper
signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> postModuleDelayedGetSignal_
bool productUnavailable() const
Definition: ProductHolder.h:69