CMS 3D CMS Logo

BranchDescription.cc

Go to the documentation of this file.
00001 #include "DataFormats/Provenance/interface/BranchDescription.h"
00002 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 #include "FWCore/Utilities/interface/FriendlyName.h"
00005 #include "FWCore/Utilities/interface/WrappedClassName.h"
00006 #include <ostream>
00007 #include <sstream>
00008 #include <stdlib.h>
00009 
00010 /*----------------------------------------------------------------------
00011 
00012 
00013 ----------------------------------------------------------------------*/
00014 
00015 namespace edm {
00016   BranchDescription::Transients::Transients() :
00017     moduleDescriptionID_(),
00018     productIDtoAssign_(),
00019     branchName_(),
00020     wrappedName_(),
00021     produced_(false),
00022     present_(true),
00023     transient_(false),
00024     type_(),
00025     splitLevel_(),
00026     basketSize_() {
00027    }
00028 
00029   BranchDescription::BranchDescription() :
00030     branchType_(InEvent),
00031     moduleLabel_(),
00032     processName_(),
00033     branchID_(),
00034     productID_(),
00035     fullClassName_(),
00036     friendlyClassName_(),
00037     productInstanceName_(),
00038     psetIDs_(),
00039     processConfigurationIDs_(),
00040     branchAliases_(),
00041     transients_()
00042   {
00043     // do not call init here! It will result in an exception throw.
00044   }
00045 
00046   BranchDescription::BranchDescription(
00047                         BranchType const& branchType,
00048                         std::string const& mdLabel, 
00049                         std::string const& procName, 
00050                         std::string const& name, 
00051                         std::string const& fName, 
00052                         std::string const& pin,
00053                         ModuleDescription const& modDesc,
00054                         std::set<std::string> const& aliases) :
00055     branchType_(branchType),
00056     moduleLabel_(mdLabel),
00057     processName_(procName),
00058     branchID_(),
00059     productID_(),
00060     fullClassName_(name),
00061     friendlyClassName_(fName),
00062     productInstanceName_(pin),
00063     psetIDs_(),
00064     processConfigurationIDs_(),
00065     branchAliases_(aliases),
00066     transients_()
00067   {
00068     present() = true;
00069     produced() = true;
00070     moduleDescriptionID() = modDesc.id();
00071     psetIDs_.insert(modDesc.parameterSetID());
00072     processConfigurationIDs_.insert(modDesc.processConfigurationID());
00073     init();
00074   }
00075 
00076 
00077 
00078   BranchDescription::BranchDescription(
00079                         BranchType const& branchType,
00080                         std::string const& mdLabel, 
00081                         std::string const& procName, 
00082                         std::string const& name, 
00083                         std::string const& fName, 
00084                         std::string const& pin, 
00085                         ModuleDescriptionID const& mdID,
00086                         std::set<ParameterSetID> const& psIDs,
00087                         std::set<ProcessConfigurationID> const& procConfigIDs,
00088                         std::set<std::string> const& aliases) :
00089     branchType_(branchType),
00090     moduleLabel_(mdLabel),
00091     processName_(procName),
00092     branchID_(),
00093     productID_(),
00094     fullClassName_(name),
00095     friendlyClassName_(fName),
00096     productInstanceName_(pin),
00097     psetIDs_(psIDs),
00098     processConfigurationIDs_(procConfigIDs),
00099     branchAliases_(aliases),
00100     transients_()
00101   {
00102     present() = true;
00103     produced() = true;
00104     moduleDescriptionID() = mdID;
00105     init();
00106   }
00107 
00108   void
00109   BranchDescription::init() const {
00110     if (!branchName().empty()) {
00111       return;   // already called
00112     }
00113     throwIfInvalid_();
00114 
00115     char const underscore('_');
00116     char const period('.');
00117 
00118     if (friendlyClassName_.find(underscore) != std::string::npos) {
00119       throw cms::Exception("IllegalCharacter") << "Class name '" << friendlyClassName()
00120       << "' contains an underscore ('_'), which is illegal in the name of a product.\n";
00121     }
00122 
00123     if (moduleLabel_.find(underscore) != std::string::npos) {
00124       throw cms::Exception("IllegalCharacter") << "Module label '" << moduleLabel()
00125       << "' contains an underscore ('_'), which is illegal in a module label.\n";
00126     }
00127 
00128     if (productInstanceName_.find(underscore) != std::string::npos) {
00129       throw cms::Exception("IllegalCharacter") << "Product instance name '" << productInstanceName()
00130       << "' contains an underscore ('_'), which is illegal in a product instance name.\n";
00131     }
00132 
00133     if (processName_.find(underscore) != std::string::npos) {
00134       throw cms::Exception("IllegalCharacter") << "Process name '" << processName()
00135       << "' contains an underscore ('_'), which is illegal in a process name.\n";
00136     }
00137 
00138     branchName().reserve(friendlyClassName().size() +
00139                         moduleLabel().size() +
00140                         productInstanceName().size() +
00141                         processName().size() + 4);
00142     branchName() += friendlyClassName();
00143     branchName() += underscore;
00144     branchName() += moduleLabel();
00145     branchName() += underscore;
00146     branchName() += productInstanceName();
00147     branchName() += underscore;
00148     branchName() += processName();
00149     branchName() += period;
00150 
00151     if (!branchID_.isValid()) {
00152       branchID_.setID(branchName());
00153     }
00154 
00155     ROOT::Reflex::Type t = ROOT::Reflex::Type::ByName(fullClassName());
00156     ROOT::Reflex::PropertyList p = t.Properties();
00157     transient() = (p.HasProperty("persistent") ? p.PropertyAsString("persistent") == std::string("false") : false);
00158 
00159     wrappedName() = wrappedClassName(fullClassName());
00160     type() = ROOT::Reflex::Type::ByName(wrappedName());
00161     ROOT::Reflex::PropertyList wp = type().Properties();
00162     if (wp.HasProperty("splitLevel")) {
00163         splitLevel() = strtol(wp.PropertyAsString("splitLevel").c_str(), 0, 0);
00164         if (splitLevel() < 0) {
00165           throw cms::Exception("IllegalSplitLevel") << "' An illegal ROOT split level of " <<
00166           splitLevel() << " is specified for class " << wrappedName() << ".'\n";
00167         }
00168         ++splitLevel(); //Compensate for wrapper
00169     } else {
00170         splitLevel() = invalidSplitLevel; 
00171     }
00172     if (wp.HasProperty("basketSize")) {
00173         basketSize() = strtol(wp.PropertyAsString("basketSize").c_str(), 0, 0);
00174         if (basketSize() <= 0) {
00175           throw cms::Exception("IllegalBasketSize") << "' An illegal ROOT basket size of " <<
00176           basketSize() << " is specified for class " << wrappedName() << "'.\n";
00177         }
00178     } else {
00179         basketSize() = invalidBasketSize; 
00180     }
00181   }
00182 
00183   ParameterSetID const&
00184     BranchDescription::psetID() const {
00185     assert(!psetIDs().empty());
00186     if (psetIDs().size() != 1) {
00187       throw cms::Exception("Ambiguous")
00188         << "Your application requires all events on Branch '" << branchName()
00189         << "'\n to have the same provenance. This file has events with mixed provenance\n"
00190         << "on this branch.  Use a different input file.\n";
00191     }
00192     return *psetIDs().begin();
00193   }
00194 
00195   void
00196   BranchDescription::merge(BranchDescription const& other) {
00197     psetIDs_.insert(other.psetIDs().begin(), other.psetIDs().end());
00198     processConfigurationIDs_.insert(other.processConfigurationIDs().begin(), other.processConfigurationIDs().end());
00199     branchAliases_.insert(other.branchAliases().begin(), other.branchAliases().end());
00200     present() = present() || other.present();
00201     if (splitLevel() == invalidSplitLevel) splitLevel() = other.splitLevel();
00202     if (basketSize() == invalidBasketSize) basketSize() = other.basketSize();
00203   }
00204 
00205   void
00206   BranchDescription::write(std::ostream& os) const {
00207     os << "Branch Type = " << branchType() << std::endl;
00208     os << "Process Name = " << processName() << std::endl;
00209     os << "ModuleLabel = " << moduleLabel() << std::endl;
00210     os << "Branch ID = " << branchID() << '\n';
00211     os << "Class Name = " << fullClassName() << '\n';
00212     os << "Friendly Class Name = " << friendlyClassName() << '\n';
00213     os << "Product Instance Name = " << productInstanceName() << std::endl;
00214   }
00215 
00216   void throwExceptionWithText(const char* txt)
00217   {
00218     edm::Exception e(edm::errors::LogicError);
00219     e << "Problem using an incomplete BranchDescription\n"
00220       << txt 
00221       << "\nPlease report this error to the FWCore developers";
00222     throw e;
00223   }
00224 
00225   void
00226   BranchDescription::throwIfInvalid_() const
00227   {
00228     if (branchType_ >= edm::NumBranchTypes)
00229       throwExceptionWithText("Illegal BranchType detected");
00230 
00231     if (moduleLabel_.empty())
00232       throwExceptionWithText("Module label is not allowed to be empty");
00233 
00234     if (processName_.empty())
00235       throwExceptionWithText("Process name is not allowed to be empty");
00236 
00237     if (fullClassName_.empty())
00238       throwExceptionWithText("Full class name is not allowed to be empty");
00239 
00240     if (friendlyClassName_.empty())
00241       throwExceptionWithText("Friendly class name is not allowed to be empty");
00242 
00243     if (produced() && !moduleDescriptionID().isValid())
00244       throwExceptionWithText("Invalid ModuleDescriptionID detected");    
00245   }
00246 
00247   void
00248   BranchDescription::updateFriendlyClassName() {
00249     friendlyClassName_ = friendlyname::friendlyName(fullClassName());
00250   }
00251 
00252   bool
00253   operator<(BranchDescription const& a, BranchDescription const& b) {
00254     if (a.processName() < b.processName()) return true;
00255     if (b.processName() < a.processName()) return false;
00256     if (a.fullClassName() < b.fullClassName()) return true;
00257     if (b.fullClassName() < a.fullClassName()) return false;
00258     if (a.friendlyClassName() < b.friendlyClassName()) return true;
00259     if (b.friendlyClassName() < a.friendlyClassName()) return false;
00260     if (a.productInstanceName() < b.productInstanceName()) return true;
00261     if (b.productInstanceName() < a.productInstanceName()) return false;
00262     if (a.moduleLabel() < b.moduleLabel()) return true;
00263     if (b.moduleLabel() < a.moduleLabel()) return false;
00264     if (a.branchType() < b.branchType()) return true;
00265     if (b.branchType() < a.branchType()) return false;
00266     if (a.branchID() < b.branchID()) return true;
00267     if (b.branchID() < a.branchID()) return false;
00268     if (a.psetIDs() < b.psetIDs()) return true;
00269     if (b.psetIDs() < a.psetIDs()) return false;
00270     if (a.processConfigurationIDs() < b.processConfigurationIDs()) return true;
00271     if (b.processConfigurationIDs() < a.processConfigurationIDs()) return false;
00272     if (a.branchAliases() < b.branchAliases()) return true;
00273     if (b.branchAliases() < a.branchAliases()) return false;
00274     if (a.present() < b.present()) return true;
00275     if (b.present() < a.present()) return false;
00276     return false;
00277   }
00278 
00279   bool
00280   combinable(BranchDescription const& a, BranchDescription const& b) {
00281     return
00282     (a.branchType() == b.branchType()) &&
00283     (a.processName() == b.processName()) &&
00284     (a.fullClassName() == b.fullClassName()) &&
00285     (a.friendlyClassName() == b.friendlyClassName()) &&
00286     (a.productInstanceName() == b.productInstanceName()) &&
00287     (a.moduleLabel() == b.moduleLabel()) &&
00288     (a.branchID() == b.branchID());
00289   }
00290 
00291   bool
00292   operator==(BranchDescription const& a, BranchDescription const& b) {
00293     return combinable(a, b) &&
00294        (a.present() == b.present()) &&
00295        (a.psetIDs() == b.psetIDs()) &&
00296        (a.processConfigurationIDs() == b.processConfigurationIDs()) &&
00297        (a.branchAliases() == b.branchAliases());
00298   }
00299 
00300   std::string
00301   match(BranchDescription const& a, BranchDescription const& b,
00302         std::string const& fileName,
00303         BranchDescription::MatchMode m) {
00304     std::ostringstream differences;
00305     if (a.branchName() != b.branchName()) {
00306       differences << "Branch name '" << b.branchName() << "' does not match '" << a.branchName() << "'.\n";
00307       // Need not compare components of branch name individually.
00308       // (a.friendlyClassName() != b.friendlyClassName())
00309       // (a.moduleLabel() != b.moduleLabel())
00310       // (a.productInstanceName() != b.productInstanceName())
00311       // (a.processName() != b.processName())
00312     }
00313     if (a.branchType() != b.branchType()) {
00314       differences << "Branch '" << b.branchName() << "' is a(n) '" << b.branchType() << "' branch\n";
00315       differences << "    in file '" << fileName << "', but a(n) '" << a.branchType() << "' branch in previous files.\n";
00316     }
00317     if (a.branchID() != b.branchID()) {
00318       differences << "Branch '" << b.branchName() << "' has a branch ID of '" << b.branchID() << "'\n";
00319       differences << "    in file '" << fileName << "', but '" << a.branchID() << "' in previous files.\n";
00320     }
00321     if (a.fullClassName() != b.fullClassName()) {
00322       differences << "Products on branch '" << b.branchName() << "' have type '" << b.fullClassName() << "'\n";
00323       differences << "    in file '" << fileName << "', but '" << a.fullClassName() << "' in previous files.\n";
00324     }
00325     if (b.present() && !a.present()) {
00326       differences << "Branch '" << a.branchName() << "' was dropped in previous files but is present in '" << fileName << "'.\n";
00327     }
00328     if (m == BranchDescription::Strict) {
00329         if (b.psetIDs().size() > 1) {
00330           differences << "Branch '" << b.branchName() << "' uses more than one parameter set in file '" << fileName << "'.\n";
00331         } else if (a.psetIDs().size() > 1) {
00332           differences << "Branch '" << a.branchName() << "' uses more than one parameter set in previous files.\n";
00333         } else if (a.psetIDs() != b.psetIDs()) {
00334           differences << "Branch '" << b.branchName() << "' uses different parameter sets in file '" << fileName << "'.\n";
00335           differences << "    than in previous files.\n";
00336         }
00337 
00338         if (b.processConfigurationIDs().size() > 1) {
00339           differences << "Branch '" << b.branchName() << "' uses more than one process configuration in file '" << fileName << "'.\n";
00340         } else if (a.processConfigurationIDs().size() > 1) {
00341           differences << "Branch '" << a.branchName() << "' uses more than one process configuration in previous files.\n";
00342         } else if (a.processConfigurationIDs() != b.processConfigurationIDs()) {
00343           differences << "Branch '" << b.branchName() << "' uses different process configurations in file '" << fileName << "'.\n";
00344           differences << "    than in previous files.\n";
00345         }
00346     }
00347     return differences.str();
00348   }
00349 }

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