CMS 3D CMS Logo

ProductRegistry.cc
Go to the documentation of this file.
1 
12 
14 
21 
22 #include "TDictAttributeMap.h"
23 
24 #include <cassert>
25 #include <iterator>
26 #include <limits>
27 #include <set>
28 #include <sstream>
29 #include <ostream>
30 
31 namespace edm {
32 
34  productList_(),
35  transient_() {
36  }
37 
39  frozen_(false),
40  productProduced_(),
41  anyProductProduced_(false),
42  eventProductLookup_(new ProductResolverIndexHelper),
43  lumiProductLookup_(new ProductResolverIndexHelper),
44  runProductLookup_(new ProductResolverIndexHelper),
45  eventNextIndexValue_(0),
46  lumiNextIndexValue_(0),
47  runNextIndexValue_(0),
48 
49  branchIDToIndex_() {
50  for(bool& isProduced : productProduced_) isProduced = false;
51  }
52 
53  void
55  frozen_ = false;
56  for(bool& isProduced : productProduced_) isProduced = false;
57  anyProductProduced_ = false;
58 
59  // propagate_const<T> has no reset() function
60  eventProductLookup_ = std::make_unique<ProductResolverIndexHelper>();
61  lumiProductLookup_ = std::make_unique<ProductResolverIndexHelper>();
62  runProductLookup_ = std::make_unique<ProductResolverIndexHelper>();
63 
67 
68  branchIDToIndex_.clear();
69  }
70 
72  productList_(productList),
73  transient_() {
74  freezeIt(toBeFrozen);
75  }
76 
77  void
79  bool fromListener) {
80  assert(productDesc.produced());
81  throwIfFrozen();
82  std::pair<ProductList::iterator, bool> ret =
83  productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
84  if(!ret.second) {
85  auto const& previous = *productList_.find(BranchKey(productDesc));
86  if(previous.second.produced()) {
87  // Duplicate registration in current process
88  throw Exception(errors::LogicError , "Duplicate Product Identifier")
89  << "\nThe Framework requires a unique branch name for each product\n"
90  << "which consists of four parts: a friendly class name, module label,\n"
91  << "product instance name, and process name. A product has been\n"
92  << "registered with a duplicate branch name. The most common way\n"
93  << "to fix this error is to modify the product instance name in\n"
94  << "one of the offending 'produces' function calls. Another fix\n"
95  << "would be to delete one of them if they are for the same product.\n\n"
96  << " friendly class name = " << previous.second.friendlyClassName() << "\n"
97  << " module label = " << previous.second.moduleLabel() << "\n"
98  << " product instance name = " << previous.second.productInstanceName() << "\n"
99  << " process name = " << previous.second.processName() << "\n\n"
100  << "The following additional information is not used as part of\n"
101  << "the unique branch identifier.\n\n"
102  << " branch types = " << previous.second.branchType() << " " << productDesc.branchType() << "\n"
103  << " class name = " << previous.second.fullClassName() << "\n\n"
104  << "Note that if the four parts of the branch name are the same,\n"
105  << "then this error will occur even if the branch types differ!\n\n";
106  } else {
107  // Duplicate registration in previous process
108  throw Exception(errors::Configuration, "Duplicate Process Name.\n")
109  << "The process name " << productDesc.processName() << " was previously used for products in the input.\n"
110  << "This has caused branch name conflicts between input products and new products.\n"
111  << "Please modify the configuration file to use a distinct process name.\n"
112  << "Alternately, drop all input products using that process name and the\n"
113  << "descendants of those products.\n";
114  }
115  }
116  addCalled(productDesc, fromListener);
117  }
118 
119  void
121  std::string const& labelAlias,
122  std::string const& instanceAlias) {
123  assert(productDesc.produced());
124  assert(productDesc.branchID().isValid());
125  throwIfFrozen();
126  BranchDescription bd(productDesc, labelAlias, instanceAlias);
127  std::pair<ProductList::iterator, bool> ret =
128  productList_.insert(std::make_pair(BranchKey(bd), bd));
129  assert(ret.second);
130  transient_.aliasToOriginal_.emplace_back(labelAlias,
131  productDesc.moduleLabel());
132  addCalled(bd, false);
133  }
134 
135  void
137  assert(!productDesc.produced());
138  throwIfFrozen();
139  BranchKey k = BranchKey(productDesc);
140  ProductList::iterator iter = productList_.find(k);
141  if(iter == productList_.end()) {
142  productList_.insert(std::make_pair(k, productDesc));
143  } else {
144  assert(combinable(iter->second, productDesc));
145  iter->second.merge(productDesc);
146  }
147  }
148 
149  bool
152  for(ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end();
153  it != itEnd; ++it) {
154  if(it->second.branchType() == brType) {
155  return true;
156  }
157  }
158  return false;
159  }
160 
161  std::shared_ptr<ProductResolverIndexHelper const>
163  if (branchType == InEvent) return transient_.eventProductLookup();
164  if (branchType == InLumi) return transient_.lumiProductLookup();
165  return transient_.runProductLookup();
166  }
167 
168  std::shared_ptr<ProductResolverIndexHelper>
170  if (branchType == InEvent) return transient_.eventProductLookup();
171  if (branchType == InLumi) return transient_.lumiProductLookup();
172  return transient_.runProductLookup();
173  }
174 
175  void
176  ProductRegistry::setFrozen(bool initializeLookupInfo) {
177  if(frozen()) return;
178  freezeIt();
179  if(initializeLookupInfo) {
180  initializeLookupTables(nullptr, nullptr, nullptr);
181  }
183  }
184 
185  void
186  ProductRegistry::setFrozen(std::set<TypeID> const& productTypesConsumed,
187  std::set<TypeID> const& elementTypesConsumed,
188  std::string const& processName) {
189  if(frozen()) return;
190  freezeIt();
191  initializeLookupTables(&productTypesConsumed, &elementTypesConsumed, &processName);
193  }
194 
195  void
197  if(frozen()) {
198  throw cms::Exception("ProductRegistry", "throwIfFrozen")
199  << "cannot modify the ProductRegistry because it is frozen\n";
200  }
201  }
202 
203  void
205  if(!frozen()) {
206  throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
207  << "cannot read the ProductRegistry because it is not yet frozen\n";
208  }
209  }
210 
211  void
213  }
214 
215  std::vector<std::string>
217  std::vector<std::string> result;
218  result.reserve(productList().size());
219 
220  for(auto const& product : productList()) {
221  result.push_back(product.second.branchName());
222  }
223  return result;
224  }
225 
226  std::vector<BranchDescription const*>
228  std::vector<BranchDescription const*> result;
229  result.reserve(productList().size());
230 
231  for(auto const& product : productList()) {
232  result.push_back(&product.second);
233  }
234  return result;
235  }
236 
237  void
239  for(auto const& product : other) {
240  copyProduct(product.second);
241  }
242  }
243 
244  void
245  ProductRegistry::updateFromInput(std::vector<BranchDescription> const& other) {
246  for(BranchDescription const& branchDescription : other) {
247  copyProduct(branchDescription);
248  }
249  }
250 
251  void
252  ProductRegistry::setUnscheduledProducts(std::set<std::string> const& unscheduledLabels) {
253  throwIfFrozen();
254 
255  bool hasAliases = false;
256  std::vector<BranchID> onDemandIDs;
257  for(auto& prod: productList_) {
258  if(prod.second.produced() &&
259  prod.second.branchType() == InEvent &&
260  unscheduledLabels.end() != unscheduledLabels.find(prod.second.moduleLabel())) {
261 
262  prod.second.setOnDemand(true);
263  onDemandIDs.push_back(prod.second.branchID());
264  }
265  if(prod.second.produced() && prod.second.isAlias()) {
266  hasAliases = true;
267  }
268  }
269 
270  // Need to loop over EDAliases to set their on-demand flag based on the pointed-to branch
271  if(hasAliases) {
272  std::sort(onDemandIDs.begin(), onDemandIDs.end());
273  for(auto& prod: productList_) {
274  if(prod.second.isAlias()) {
275  if(std::binary_search(onDemandIDs.begin(), onDemandIDs.end(), prod.second.aliasForBranchID())) {
276  prod.second.setOnDemand(true);
277  }
278  }
279  }
280  }
281  }
282 
285  std::string const& fileName,
286  BranchDescription::MatchMode branchesMustMatch) {
287  std::ostringstream differences;
288 
289  ProductRegistry::ProductList::iterator j = productList_.begin();
290  ProductRegistry::ProductList::iterator s = productList_.end();
291  ProductRegistry::ProductList::const_iterator i = other.productList().begin();
292  ProductRegistry::ProductList::const_iterator e = other.productList().end();
293 
294  // Loop over entries in the main product registry.
295  while(j != s || i != e) {
296  if(j != s && j->second.produced()) {
297  // Ignore branches just produced (i.e. not in input file).
298  ++j;
299  } else if(j == s || (i != e && i->first < j->first)) {
300  if(i->second.present()) {
301  differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
302  differences << " but not in previous files.\n";
303  } else {
304  productList_.insert(*i);
305  transient_.branchIDToIndex_[i->second.branchID()] = getNextIndexValue(i->second.branchType());
306  ++nextIndexValue(i->second.branchType());
307  }
308  ++i;
309  } else if(i == e || (j != s && j->first < i->first)) {
310  if(j->second.present() && branchesMustMatch == BranchDescription::Strict) {
311  differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
312  differences << " but not in file '" << fileName << "'.\n";
313  }
314  ++j;
315  } else {
316  std::string difs = match(j->second, i->second, fileName);
317  if(difs.empty()) {
318  j->second.merge(i->second);
319  } else {
320  differences << difs;
321  }
322  ++i;
323  ++j;
324  }
325  }
326  return differences.str();
327  }
328 
329  void ProductRegistry::initializeLookupTables(std::set<TypeID> const* productTypesConsumed,
330  std::set<TypeID> const* elementTypesConsumed,
331  std::string const* processName) {
332 
333  std::map<TypeID, TypeID> containedTypeMap;
334  std::map<TypeID, std::vector<TypeWithDict> > containedTypeToBaseTypesMap;
335 
336  std::vector<std::string> missingDictionaries;
337  std::vector<std::string> branchNamesForMissing;
338  std::vector<std::string> producedTypes;
339 
341 
342  for(auto const& product : productList_) {
343  auto const& desc = product.second;
344 
345  checkForDuplicateProcessName(desc, processName);
346 
347  if(desc.produced() && !desc.transient()) {
348  setProductProduced(desc.branchType());
349  }
350 
351  //only do the following if the data is supposed to be available in the event
352  if(desc.present()) {
353 
354  // Check dictionaries (we already checked for the produced ones earlier somewhere else).
355  // We have to have the dictionaries to properly setup the lookup tables for support of
356  // Views. Also we need them to determine which present products are declared to be
357  // consumed in the case where the consumed type is a View<T>.
358  if (!desc.produced()) {
359  if (!checkDictionary(missingDictionaries, desc.className(), desc.unwrappedType())) {
360  checkDictionaryOfWrappedType(missingDictionaries, desc.className());
361  branchNamesForMissing.emplace_back(desc.branchName());
362  producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
363  continue;
364  }
365  }
366  TypeID typeID(desc.unwrappedType().typeInfo());
367 
368  auto iter = containedTypeMap.find(typeID);
369  bool alreadySawThisType = (iter != containedTypeMap.end());
370 
371  if (!desc.produced() && !alreadySawThisType) {
372  if (!checkDictionary(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
373  branchNamesForMissing.emplace_back(desc.branchName());
374  producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
375  continue;
376  }
377  }
378 
379  TypeID wrappedTypeID(desc.wrappedType().typeInfo());
380 
381  TypeID containedTypeID;
382  if (alreadySawThisType) {
383  containedTypeID = iter->second;
384  } else {
385  containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(wrappedTypeID, typeID.className());
386  }
387  bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
388 
389  std::vector<TypeWithDict>* baseTypesOfContainedType = nullptr;
390 
391  if (!alreadySawThisType) {
392  bool alreadyCheckedConstituents = desc.produced() && !desc.transient();
393  if (!alreadyCheckedConstituents && !desc.transient()) {
394  // This checks dictionaries of the wrapped class and all its constituent classes
395  if (!checkClassDictionaries(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
396  branchNamesForMissing.emplace_back(desc.branchName());
397  producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
398  continue;
399  }
400  }
401 
402  if (hasContainedType) {
403  auto iter = containedTypeToBaseTypesMap.find(containedTypeID);
404  if (iter == containedTypeToBaseTypesMap.end()) {
405  std::vector<TypeWithDict> baseTypes;
406  if (!public_base_classes(missingDictionaries, containedTypeID, baseTypes)) {
407  branchNamesForMissing.emplace_back(desc.branchName());
408  if (desc.produced()) {
409  producedTypes.emplace_back(desc.className() + std::string(" (produced in current process)"));
410  } else {
411  producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
412  }
413  continue;
414  }
415  iter = containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, baseTypes)).first;
416  }
417  baseTypesOfContainedType = &iter->second;
418  }
419 
420  // Do this after the dictionary checks of constituents so the list of branch names for missing types
421  // is complete
422  containedTypeMap.emplace(typeID, containedTypeID);
423  } else {
424  if (hasContainedType) {
425  auto iter = containedTypeToBaseTypesMap.find(containedTypeID);
426  if (iter != containedTypeToBaseTypesMap.end()) {
427  baseTypesOfContainedType = &iter->second;
428  }
429  }
430  }
431 
432  if(productTypesConsumed != nullptr && !desc.produced()) {
433  bool mainTypeConsumed = (productTypesConsumed->find(typeID) != productTypesConsumed->end());
434  bool containedTypeConsumed = hasContainedType && (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end());
435  if(hasContainedType && !containedTypeConsumed && baseTypesOfContainedType != nullptr) {
436  for(TypeWithDict const& baseType : *baseTypesOfContainedType) {
437  if(elementTypesConsumed->find(TypeID(baseType.typeInfo())) != elementTypesConsumed->end()) {
438  containedTypeConsumed = true;
439  break;
440  }
441  }
442  }
443  if(!containedTypeConsumed) {
444  if(mainTypeConsumed) {
445  // The main type is consumed, but either
446  // there is no contained type, or if there is,
447  // neither it nor any of its base classes are consumed.
448  // Set the contained type, if there is one, to void,
449  if(hasContainedType) {
450  containedTypeID = TypeID(typeid(void));
451  }
452  } else {
453  // The main type is not consumed, and either
454  // there is no contained type, or if there is,
455  // neither it nor any of its base classes are consumed.
456  // Don't insert anything in the lookup tables.
457  continue;
458  }
459  }
460  }
462  productLookup(desc.branchType())->insert(typeID,
463  desc.moduleLabel().c_str(),
464  desc.productInstanceName().c_str(),
465  desc.processName().c_str(),
466  containedTypeID,
467  baseTypesOfContainedType);
468 
469  transient_.branchIDToIndex_[desc.branchID()] = index;
470  }
471  }
472  if (!missingDictionaries.empty()) {
473  std::string context("Calling ProductRegistry::initializeLookupTables");
474  throwMissingDictionariesException(missingDictionaries, context, producedTypes, branchNamesForMissing);
475  }
476 
477  productLookup(InEvent)->setFrozen();
478  productLookup(InLumi)->setFrozen();
479  productLookup(InRun)->setFrozen();
480 
482  transient_.lumiNextIndexValue_ = productLookup(InLumi)->nextIndexValue();
483  transient_.runNextIndexValue_ = productLookup(InRun)->nextIndexValue();
484 
485  for(auto const& product : productList_) {
486  auto const& desc = product.second;
487  if (transient_.branchIDToIndex_.find(desc.branchID()) == transient_.branchIDToIndex_.end()) {
488  transient_.branchIDToIndex_[desc.branchID()] = getNextIndexValue(desc.branchType());
489  ++nextIndexValue(desc.branchType());
490  }
491  }
492  checkDictionariesOfConsumedTypes(productTypesConsumed, elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
493  }
494 
495  void
496  ProductRegistry::checkDictionariesOfConsumedTypes(std::set<TypeID> const* productTypesConsumed,
497  std::set<TypeID> const* elementTypesConsumed,
498  std::map<TypeID, TypeID> const& containedTypeMap,
499  std::map<TypeID, std::vector<TypeWithDict> >& containedTypeToBaseTypesMap) {
500 
501  std::vector<std::string> missingDictionaries;
502  std::set<std::string> consumedTypesWithMissingDictionaries;
503 
504  if (productTypesConsumed) {
505 
506 
507  // Check dictionaries for all classes declared to be consumed
508  for (auto const& consumedTypeID : *productTypesConsumed) {
509 
510  // We use the containedTypeMap to see which types have already
511  // had their dictionaries checked. We do not waste time rechecking
512  // those dictionaries.
513  if (containedTypeMap.find(consumedTypeID) == containedTypeMap.end()) {
514 
515  std::string wrappedName = wrappedClassName(consumedTypeID.className());
516  TypeWithDict wrappedType = TypeWithDict::byName(wrappedName);
517  if (!checkDictionary(missingDictionaries, wrappedName, wrappedType)) {
518  checkDictionary(missingDictionaries, consumedTypeID);
519  consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
520  continue;
521  }
522  bool transient = false;
523  TDictAttributeMap* wp = wrappedType.getClass()->GetAttributeMap();
524  if (wp && wp->HasKey("persistent") && !strcmp(wp->GetPropertyAsString("persistent"), "false")) {
525  transient = true;
526  }
527  if (transient) {
528  if(!checkDictionary(missingDictionaries, consumedTypeID)) {
529  consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
530  }
531 
532  TypeID containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(TypeID(wrappedType.typeInfo()), consumedTypeID.className());
533  bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
534  if (hasContainedType) {
535  if (containedTypeToBaseTypesMap.find(containedTypeID) == containedTypeToBaseTypesMap.end()) {
536  std::vector<TypeWithDict> bases;
537  // Run this to check for missing dictionaries, bases is not really used
538  if (!public_base_classes(missingDictionaries, containedTypeID, bases)) {
539  consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
540  }
541  containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, bases));
542  }
543  }
544  } else {
545  if (!checkClassDictionaries(missingDictionaries, wrappedName, wrappedType)) {
546  consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
547  }
548  }
549  }
550  }
551  if (!missingDictionaries.empty()) {
552  std::string context("Calling ProductRegistry::initializeLookupTables, checking dictionaries for consumed products");
553  throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, false);
554  }
555  }
556 
557  if (elementTypesConsumed) {
558  missingDictionaries.clear();
559  consumedTypesWithMissingDictionaries.clear();
560  for (auto const& consumedTypeID : *elementTypesConsumed) {
561  if (containedTypeToBaseTypesMap.find(consumedTypeID) == containedTypeToBaseTypesMap.end()) {
562  std::vector<TypeWithDict> bases;
563  // Run this to check for missing dictionaries, bases is not really used
564  if (!public_base_classes(missingDictionaries, consumedTypeID, bases)) {
565  consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
566  }
567  }
568  }
569  if (!missingDictionaries.empty()) {
570  std::string context("Calling ProductRegistry::initializeLookupTables, checking dictionaries for elements of products consumed using View");
571  throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, true);
572  }
573  }
574  }
575 
577  std::string const* processName) const {
578  if (processName &&
579  !desc.produced() &&
580  (*processName == desc.processName())) {
581 
582  throw Exception(errors::Configuration, "Duplicate Process Name.\n")
583  << "The process name " << *processName << " was previously used for products in the input.\n"
584  << "Please modify the configuration file to use a distinct process name.\n"
585  << "Alternately, drop all input products using that process name and the\n"
586  << "descendants of those products.\n";
587  }
588  }
589 
591  std::map<BranchID, ProductResolverIndex>::const_iterator itFind = transient_.branchIDToIndex_.find(iID);
592  if(itFind == transient_.branchIDToIndex_.end()) {
594  }
595  return itFind->second;
596  }
597 
598  void ProductRegistry::print(std::ostream& os) const {
599  for(auto const& product: productList_) {
600  os << product.second << "\n-----\n";
601  }
602  }
603 
604  ProductResolverIndex const&
606  if (branchType == InEvent) return transient_.eventNextIndexValue_;
607  if (branchType == InLumi) return transient_.lumiNextIndexValue_;
609  }
610 
613  if (branchType == InEvent) return transient_.eventNextIndexValue_;
614  if (branchType == InLumi) return transient_.lumiNextIndexValue_;
616  }
617 }
edm::propagate_const< std::shared_ptr< ProductResolverIndexHelper > > lumiProductLookup_
void setProductProduced(BranchType branchType)
BranchType const & branchType() const
void throwMissingDictionariesException(std::vector< std::string > &missingDictionaries, std::string const &context)
unsigned int ProductResolverIndex
void throwIfNotFrozen() const
TypeID getContainedTypeFromWrapper(TypeID const &wrappedtypeID, std::string const &className)
std::vector< std::string > allBranchNames() const
std::map< BranchKey, BranchDescription > ProductList
bool public_base_classes(std::vector< std::string > &missingDictionaries, TypeID const &typeID, std::vector< TypeWithDict > &baseTypes)
bool anyProducts(BranchType const brType) const
std::string const & processName() const
std::shared_ptr< ProductResolverIndexHelper const > lumiProductLookup() const
ProductList::size_type size() const
bool isValid() const
Definition: BranchID.h:24
void addLabelAlias(BranchDescription const &productdesc, std::string const &labelAlias, std::string const &instanceAlias)
std::shared_ptr< ProductResolverIndexHelper const > eventProductLookup() const
BranchType
Definition: BranchType.h:11
virtual void addCalled(BranchDescription const &, bool iFromListener)
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:74
ProductList const & productList() const
void initializeLookupTables(std::set< TypeID > const *productTypesConsumed, std::set< TypeID > const *elementTypesConsumed, std::string const *processName)
std::string const & moduleLabel() const
ProductResolverIndex eventNextIndexValue_
bool combinable(BranchDescription const &a, BranchDescription const &b)
bool checkDictionary(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
std::shared_ptr< ProductResolverIndexHelper const > runProductLookup() const
ProductResolverIndex lumiNextIndexValue_
void setUnscheduledProducts(std::set< std::string > const &unscheduledLabels)
void checkForDuplicateProcessName(BranchDescription const &desc, std::string const *processName) const
ProductResolverIndex & nextIndexValue(BranchType branchType)
bool checkClassDictionaries(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
std::vector< BranchDescription const * > allBranchDescriptions() const
std::string merge(ProductRegistry const &other, std::string const &fileName, BranchDescription::MatchMode branchesMustMatch=BranchDescription::Permissive)
BranchID const & branchID() const
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
void setFrozen(bool initializeLookupInfo=true)
void freezeIt(bool frozen=true)
void print(std::ostream &os) const
int k[5][pyjets_maxn]
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:92
ProductResolverIndex runNextIndexValue_
std::string wrappedClassName(std::string const &iFullName)
std::vector< std::pair< std::string, std::string > > aliasToOriginal_
std::shared_ptr< ProductResolverIndexHelper const > productLookup(BranchType branchType) const
ProductResolverIndex const & getNextIndexValue(BranchType branchType) const
HLT enums.
void throwIfFrozen() const
std::string const & className() const
Definition: TypeID.cc:43
void updateFromInput(ProductList const &other)
bool checkDictionaryOfWrappedType(std::vector< std::string > &missingDictionaries, TypeID const &unwrappedTypeID)
std::array< bool, NumBranchTypes > productProduced_
void checkDictionariesOfConsumedTypes(std::set< TypeID > const *productTypesConsumed, std::set< TypeID > const *elementTypesConsumed, std::map< TypeID, TypeID > const &containedTypeMap, std::map< TypeID, std::vector< TypeWithDict > > &containedTypeToBaseTypesMap)
edm::propagate_const< std::shared_ptr< ProductResolverIndexHelper > > eventProductLookup_
ProductResolverIndex indexFrom(BranchID const &iID) const
void addProduct(BranchDescription const &productdesc, bool iFromListener=false)
std::map< BranchID, ProductResolverIndex > branchIDToIndex_
edm::propagate_const< std::shared_ptr< ProductResolverIndexHelper > > runProductLookup_
def branchType(schema, name)
Definition: revisionDML.py:114
void copyProduct(BranchDescription const &productdesc)
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)