CMS 3D CMS Logo

ProductRegistry.cc

Go to the documentation of this file.
00001 
00011 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00012 #include "DataFormats/Provenance/interface/BranchType.h"
00013 #include "FWCore/Utilities/interface/ReflexTools.h"
00014 #include "FWCore/Utilities/interface/Exception.h"
00015 #include "FWCore/Utilities/interface/TypeID.h"
00016 #include "FWCore/Utilities/interface/WrappedClassName.h"
00017 #include <algorithm>
00018 #include <sstream>
00019 
00020 namespace edm {
00021   namespace {
00022     void checkDicts(BranchDescription const& productDesc) {
00023       if (productDesc.transient()) {
00024         checkDictionaries(productDesc.fullClassName(), true);
00025       } else {
00026         checkDictionaries(wrappedClassName(productDesc.fullClassName()), false);
00027       }
00028     }
00029   }
00030 
00031   ProductRegistry::ProductRegistry() :
00032       productList_(),
00033       nextID_(1),
00034       transients_() {
00035   }
00036 
00037   ProductRegistry::Transients::Transients() :
00038       frozen_(false),
00039       constProductList_(),
00040       productLookup_(),
00041       elementLookup_() {
00042   }
00043 
00044   ProductRegistry::ProductRegistry(ProductList const& productList, unsigned int nextID) :
00045       productList_(productList),
00046       nextID_(nextID),
00047       transients_() {
00048     frozen() = true;
00049   }
00050 
00051   void
00052   ProductRegistry::addProduct(BranchDescription const& productDesc,
00053                               bool fromListener) {
00054     assert(productDesc.produced());
00055     throwIfFrozen();
00056     productDesc.init();
00057     checkDicts(productDesc);
00058     productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
00059     addCalled(productDesc,fromListener);
00060   }
00061  
00062   void
00063   ProductRegistry::copyProduct(BranchDescription const& productDesc) {
00064     assert(!productDesc.produced());
00065     throwIfFrozen();
00066     productDesc.init();
00067     BranchKey k = BranchKey(productDesc);
00068     ProductList::iterator iter = productList_.find(k);
00069     if (iter == productList_.end()) {
00070       productList_.insert(std::make_pair(k, productDesc));
00071     } else {
00072       assert(combinable(iter->second, productDesc));
00073       iter->second.merge(productDesc);
00074     }
00075   }
00076   
00077   void
00078   ProductRegistry::setProductIDs(unsigned int startingID) {
00079     throwIfNotFrozen();
00080     if (startingID < nextID_) {
00081       startingID = nextID_;
00082     }
00083     --startingID;
00084     for (ProductList::iterator it = productList_.begin(), itEnd = productList_.end();
00085         it != itEnd; ++it) {
00086       if (it->second.produced() && it->second.branchType() == InEvent) {
00087         it->second.setProductIDtoAssign(ProductID(++startingID));
00088       }
00089     }
00090     setNextID(startingID + 1);
00091     initializeTransients();
00092   }
00093 
00094   bool
00095   ProductRegistry::anyProducts(BranchType brType) const {
00096     throwIfNotFrozen();
00097     for (ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end();
00098         it != itEnd; ++it) {
00099       if (it->second.branchType() == brType) {
00100         return true;
00101       }
00102     }
00103     return false;
00104   }
00105   
00106   void
00107   ProductRegistry::setFrozen() const {
00108     checkAllDictionaries();
00109     if(frozen()) return;
00110     frozen() = true;
00111     initializeTransients();
00112   }
00113   
00114   void
00115   ProductRegistry::throwIfFrozen() const {
00116     if (frozen()) {
00117       throw cms::Exception("ProductRegistry", "throwIfFrozen")
00118             << "cannot modify the ProductRegistry because it is frozen\n";
00119     }
00120   }
00121   
00122   void
00123   ProductRegistry::throwIfNotFrozen() const {
00124     if (!frozen()) {
00125       throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
00126             << "cannot read the ProductRegistry because it is not yet frozen\n";
00127     }
00128   }
00129   
00130   void
00131   ProductRegistry::addCalled(BranchDescription const&, bool) {
00132   }
00133 
00134   std::vector<std::string>
00135   ProductRegistry::allBranchNames() const
00136   {
00137     std::vector<std::string> result;
00138     result.reserve( productList().size() ); 
00139 
00140     ProductList::const_iterator it  = productList().begin();
00141     ProductList::const_iterator end = productList().end();
00142 
00143     for ( ; it != end; ++it ) result.push_back(it->second.branchName());
00144 
00145   return result;
00146   }
00147 
00148   std::vector<BranchDescription const*> 
00149   ProductRegistry::allBranchDescriptions() const
00150   {
00151     std::vector<BranchDescription const*> result;
00152     result.reserve( productList().size() );
00153 
00154     ProductList::const_iterator it  = productList().begin();
00155     ProductList::const_iterator end = productList().end();
00156     
00157     for ( ; it != end; ++it) result.push_back(&(it->second));    
00158     return result;
00159   }
00160   
00161   std::string
00162   ProductRegistry::merge(ProductRegistry const& other,
00163         std::string const& fileName,
00164         BranchDescription::MatchMode parametersMustMatch,
00165         BranchDescription::MatchMode branchesMustMatch) {
00166     std::ostringstream differences;
00167 
00168     ProductRegistry::ProductList::iterator j = productList_.begin();
00169     ProductRegistry::ProductList::iterator s = productList_.end();
00170     ProductRegistry::ProductList::const_iterator i = other.productList().begin();
00171     ProductRegistry::ProductList::const_iterator e = other.productList().end();
00172 
00173     // Loop over entries in the main product registry.
00174     while(j != s || i != e) {
00175       if (j != s && j->second.produced()) {
00176         // Ignore branches just produced (i.e. not in input file).
00177         ++j;
00178       } else if (j == s || i != e && i->first < j->first) {
00179         if (i->second.present()) {
00180           differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
00181           differences << "    but not in previous files.\n";
00182         } else {
00183           productList_.insert(*i);
00184         }
00185         ++i;
00186       } else if (i == e || j != s && j->first < i->first) {
00187         if (branchesMustMatch == BranchDescription::Strict) {
00188           differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
00189           differences << "    but not in file '" << fileName << "'.\n";
00190         }
00191         ++j;
00192       } else {
00193         std::string difs = match(j->second, i->second, fileName, parametersMustMatch);
00194         if (difs.empty()) {
00195           if (parametersMustMatch == BranchDescription::Permissive) j->second.merge(i->second);
00196         } else {
00197           differences << difs;
00198         }
00199         ++i;
00200         ++j;
00201       }
00202     }
00203     if (other.nextID() > nextID()) {
00204       setNextID(other.nextID());
00205       setProductIDs(other.nextID());
00206     }
00207     initializeTransients();
00208     return differences.str();
00209   }
00210 
00211   void ProductRegistry::initializeTransients() const {
00212     constProductList().clear();
00213     productLookup().clear();
00214     elementLookup().clear();
00215     for (ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i) {
00216       constProductList().insert(std::make_pair(i->first, ConstBranchDescription(i->second)));
00217 
00218       ProcessLookup& processLookup = productLookup()[i->first.friendlyClassName_];
00219       std::vector<BranchID>& vint = processLookup[i->first.processName_];
00220       vint.push_back(i->second.branchID());
00221       //[could use productID instead]
00222         
00223       ROOT::Reflex::Type type(ROOT::Reflex::Type::ByName(i->second.className()));
00224       if (bool(type)) {
00225         
00226         // Here we look in the object named "type" for a typedef
00227         // named "value_type" and get the Reflex::Type for it.
00228         // Then check to ensure the Reflex dictionary is defined
00229         // for this value_type.
00230         // I do not throw an exception here if the check fails
00231         // because there are known cases where the dictionary does
00232         // not exist and we do not need to support those cases.
00233         ROOT::Reflex::Type valueType;
00234         if ((is_RefVector(type, valueType) || 
00235              is_RefToBaseVector(type, valueType ) || 
00236              value_type_of(type, valueType)) 
00237             && bool(valueType)) {
00238           
00239           fillElementLookup(valueType, i->second.branchID(), i->first);
00240           
00241           // Repeat this for all public base classes of the value_type
00242           std::vector<ROOT::Reflex::Type> baseTypes;
00243           public_base_classes(valueType, baseTypes);
00244           
00245           for (std::vector<ROOT::Reflex::Type>::iterator iter = baseTypes.begin(),
00246                iend = baseTypes.end();
00247                iter != iend;
00248                ++iter) {
00249             fillElementLookup(*iter, i->second.branchID(), i->first);
00250           }
00251         }
00252       }
00253     }
00254   }
00255 
00256   void ProductRegistry::fillElementLookup(const ROOT::Reflex::Type & type,
00257                                           const BranchID& id,
00258                                           const BranchKey& bk) const
00259   {
00260     TypeID typeID(type.TypeInfo());
00261     std::string friendlyClassName = typeID.friendlyClassName();
00262     
00263     ProcessLookup& processLookup = elementLookup()[friendlyClassName];
00264     std::vector<BranchID>& vint = processLookup[bk.processName_];
00265     vint.push_back(id);    
00266   }
00267   
00268   void ProductRegistry::print(std::ostream& os) const {
00269     for (ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i) {
00270         os << i->second << "\n-----\n";
00271     }
00272   }
00273 
00274 }

Generated on Tue Jun 9 17:31:39 2009 for CMSSW by  doxygen 1.5.4