22 #include "TDictAttributeMap.h" 41 anyProductProduced_(
false),
45 eventNextIndexValue_(0),
46 lumiNextIndexValue_(0),
47 runNextIndexValue_(0),
82 std::pair<ProductList::iterator, bool> ret =
86 if(previous.second.produced()) {
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";
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";
127 std::pair<ProductList::iterator, bool> ret =
144 assert(
combinable(iter->second, productDesc));
145 iter->second.merge(productDesc);
154 if(it->second.branchType() == brType) {
161 std::shared_ptr<ProductResolverIndexHelper const>
168 std::shared_ptr<ProductResolverIndexHelper>
179 if(initializeLookupInfo) {
187 std::set<TypeID>
const& elementTypesConsumed,
199 <<
"cannot modify the ProductRegistry because it is frozen\n";
207 <<
"cannot read the ProductRegistry because it is not yet frozen\n";
215 std::vector<std::string>
217 std::vector<std::string>
result;
221 result.push_back(product.second.branchName());
226 std::vector<BranchDescription const*>
228 std::vector<BranchDescription const*>
result;
232 result.push_back(&product.second);
239 for(
auto const& product : other) {
255 bool hasAliases =
false;
256 std::vector<BranchID> onDemandIDs;
258 if(
prod.second.produced() &&
260 unscheduledLabels.end() != unscheduledLabels.find(
prod.second.moduleLabel())) {
262 prod.second.setOnDemand(
true);
263 onDemandIDs.push_back(
prod.second.branchID());
265 if(
prod.second.produced() &&
prod.second.isAlias()) {
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);
287 std::ostringstream differences;
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();
295 while(j != s || i != e) {
296 if(j != s && j->second.produced()) {
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";
309 }
else if(i == e || (j != s && j->first < i->first)) {
311 differences <<
"Branch '" << j->second.branchName() <<
"' is in previous files\n";
312 differences <<
" but not in file '" << fileName <<
"'.\n";
318 j->second.merge(i->second);
326 return differences.str();
330 std::set<TypeID>
const* elementTypesConsumed,
333 std::map<TypeID, TypeID> containedTypeMap;
334 std::map<TypeID, std::vector<TypeWithDict> > containedTypeToBaseTypesMap;
336 std::vector<std::string> missingDictionaries;
337 std::vector<std::string> branchNamesForMissing;
338 std::vector<std::string> producedTypes;
343 auto const& desc = product.second;
347 if(desc.produced() && !desc.transient()) {
358 if (!desc.produced()) {
359 if (!
checkDictionary(missingDictionaries, desc.className(), desc.unwrappedType())) {
361 branchNamesForMissing.emplace_back(desc.branchName());
362 producedTypes.emplace_back(desc.className() +
std::string(
" (read from input)"));
366 TypeID typeID(desc.unwrappedType().typeInfo());
368 auto iter = containedTypeMap.find(typeID);
369 bool alreadySawThisType = (iter != containedTypeMap.end());
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)"));
379 TypeID wrappedTypeID(desc.wrappedType().typeInfo());
382 if (alreadySawThisType) {
383 containedTypeID = iter->second;
387 bool hasContainedType = (containedTypeID !=
TypeID(
typeid(
void)) && containedTypeID !=
TypeID());
389 std::vector<TypeWithDict>* baseTypesOfContainedType =
nullptr;
391 if (!alreadySawThisType) {
392 bool alreadyCheckedConstituents = desc.produced() && !desc.transient();
393 if (!alreadyCheckedConstituents && !desc.transient()) {
396 branchNamesForMissing.emplace_back(desc.branchName());
397 producedTypes.emplace_back(desc.className() +
std::string(
" (read from input)"));
402 if (hasContainedType) {
403 auto iter = containedTypeToBaseTypesMap.find(containedTypeID);
404 if (iter == containedTypeToBaseTypesMap.end()) {
405 std::vector<TypeWithDict> baseTypes;
407 branchNamesForMissing.emplace_back(desc.branchName());
408 if (desc.produced()) {
409 producedTypes.emplace_back(desc.className() +
std::string(
" (produced in current process)"));
411 producedTypes.emplace_back(desc.className() +
std::string(
" (read from input)"));
415 iter = containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, baseTypes)).first;
417 baseTypesOfContainedType = &iter->second;
422 containedTypeMap.emplace(typeID, containedTypeID);
424 if (hasContainedType) {
425 auto iter = containedTypeToBaseTypesMap.find(containedTypeID);
426 if (iter != containedTypeToBaseTypesMap.end()) {
427 baseTypesOfContainedType = &iter->second;
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;
443 if(!containedTypeConsumed) {
444 if(mainTypeConsumed) {
449 if(hasContainedType) {
450 containedTypeID =
TypeID(
typeid(
void));
463 desc.moduleLabel().c_str(),
464 desc.productInstanceName().c_str(),
465 desc.processName().c_str(),
467 baseTypesOfContainedType);
472 if (!missingDictionaries.empty()) {
473 std::string context(
"Calling ProductRegistry::initializeLookupTables");
485 for(
auto const& product : productList_) {
486 auto const& desc = product.second;
497 std::set<TypeID>
const* elementTypesConsumed,
498 std::map<TypeID, TypeID>
const& containedTypeMap,
499 std::map<
TypeID, std::vector<TypeWithDict> >& containedTypeToBaseTypesMap) {
501 std::vector<std::string> missingDictionaries;
502 std::set<std::string> consumedTypesWithMissingDictionaries;
504 if (productTypesConsumed) {
508 for (
auto const& consumedTypeID : *productTypesConsumed) {
513 if (containedTypeMap.find(consumedTypeID) == containedTypeMap.end()) {
519 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
522 bool transient =
false;
523 TDictAttributeMap* wp = wrappedType.getClass()->GetAttributeMap();
524 if (wp && wp->HasKey(
"persistent") && !strcmp(wp->GetPropertyAsString(
"persistent"),
"false")) {
529 consumedTypesWithMissingDictionaries.emplace(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;
539 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
541 containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, bases));
546 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
551 if (!missingDictionaries.empty()) {
552 std::string context(
"Calling ProductRegistry::initializeLookupTables, checking dictionaries for consumed products");
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;
565 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
569 if (!missingDictionaries.empty()) {
570 std::string context(
"Calling ProductRegistry::initializeLookupTables, checking dictionaries for elements of products consumed using View");
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";
595 return itFind->second;
600 os << product.second <<
"\n-----\n";
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
void addLabelAlias(BranchDescription const &productdesc, std::string const &labelAlias, std::string const &instanceAlias)
std::shared_ptr< ProductResolverIndexHelper const > eventProductLookup() const
virtual void addCalled(BranchDescription const &, bool iFromListener)
static TypeWithDict byName(std::string const &name)
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)
void setFrozen(bool initializeLookupInfo=true)
void freezeIt(bool frozen=true)
void print(std::ostream &os) const
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
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
void throwIfFrozen() const
std::string const & className() const
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)
void copyProduct(BranchDescription const &productdesc)
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)