CMS 3D CMS Logo

BranchDescription.cc
Go to the documentation of this file.
2 
9 
10 #include "TDictAttributeMap.h"
11 
12 #include <cassert>
13 #include <ostream>
14 #include <sstream>
15 
16 class TClass;
17 
18 namespace edm {
20  : parameterSetID_(),
21  moduleName_(),
22  branchName_(),
23  wrappedName_(),
24  wrappedType_(),
25  unwrappedType_(),
26  splitLevel_(),
27  basketSize_(),
28  produced_(false),
29  onDemand_(false),
30  dropped_(false),
31  transient_(false),
32  availableOnlyAtEndTransition_(false),
33  isMergeable_(false) {}
34 
36 
39  moduleLabel_(),
40  processName_(),
41  branchID_(),
47  transient_() {
48  // do not call init here! It will result in an exception throw.
49  }
50 
52  std::string const& moduleLabel,
53  std::string const& processName,
54  std::string const& className,
55  std::string const& friendlyClassName,
56  std::string const& productInstanceName,
57  std::string const& moduleName,
58  ParameterSetID const& parameterSetID,
59  TypeWithDict const& theTypeWithDict,
60  bool produced,
61  bool availableOnlyAtEndTransition,
62  std::set<std::string> const& aliases)
63  : branchType_(branchType),
64  moduleLabel_(moduleLabel),
65  processName_(processName),
66  branchID_(),
67  fullClassName_(className),
68  friendlyClassName_(friendlyClassName),
69  productInstanceName_(productInstanceName),
70  branchAliases_(aliases),
71  transient_() {
72  setDropped(false);
74  setOnDemand(false);
78  setUnwrappedType(theTypeWithDict);
79  init();
80  }
81 
83  std::string const& moduleLabelAlias,
84  std::string const& productInstanceAlias)
85  : branchType_(aliasForBranch.branchType()),
86  moduleLabel_(moduleLabelAlias),
87  processName_(aliasForBranch.processName()),
88  branchID_(),
89  fullClassName_(aliasForBranch.className()),
90  friendlyClassName_(aliasForBranch.friendlyClassName()),
91  productInstanceName_(productInstanceAlias),
92  branchAliases_(aliasForBranch.branchAliases()),
93  aliasForBranchID_(aliasForBranch.branchID()),
94  transient_() {
95  setDropped(false);
96  setProduced(aliasForBranch.produced());
97  setOnDemand(false); // will be re-set externally to the aliasForBranch.onDemand() after that one has been set
99  transient_.moduleName_ = aliasForBranch.moduleName();
100  transient_.parameterSetID_ = aliasForBranch.parameterSetID();
101  setUnwrappedType(aliasForBranch.unwrappedType());
102  init();
103  }
104 
106  if (!branchName().empty()) {
107  return; // already called
108  }
109  throwIfInvalid_();
110 
111  char const underscore('_');
112  char const period('.');
113 
114  if (friendlyClassName_.find(underscore) != std::string::npos) {
115  throw cms::Exception("IllegalCharacter")
116  << "Class name '" << friendlyClassName()
117  << "' contains an underscore ('_'), which is illegal in the name of a product.\n";
118  }
119 
120  // Module labels of non-persistent products are allowed to contain
121  // underscores. For module labels of persistent products, the module
122  // label is checked for underscores in the function initFromDictionary
123  // after we determine whether the product is persistent or not.
124 
125  if (productInstanceName_.find(underscore) != std::string::npos) {
126  throw cms::Exception("IllegalCharacter")
127  << "Product instance name '" << productInstanceName()
128  << "' contains an underscore ('_'), which is illegal in a product instance name.\n";
129  }
130 
131  if (processName_.find(underscore) != std::string::npos) {
132  throw cms::Exception("IllegalCharacter")
133  << "Process name '" << processName()
134  << "' contains an underscore ('_'), which is illegal in a process name.\n";
135  }
136 
138  brName.reserve(friendlyClassName().size() + moduleLabel().size() + productInstanceName().size() +
139  processName().size() + 4);
140  brName += friendlyClassName();
141  brName += underscore;
142  brName += moduleLabel();
143  brName += underscore;
144  brName += productInstanceName();
145  brName += underscore;
146  brName += processName();
147  brName += period;
148 
149  if (!branchID_.isValid()) {
150  branchID_.setID(brName);
151  }
152  }
153 
155  if (bool(wrappedType())) {
156  return; // already initialized;
157  }
158 
159  throwIfInvalid_();
160 
161  try {
163  // unwrapped type.
165  if (!bool(unwrappedType())) {
168  setTransient(false);
169  return;
170  }
171  } catch (edm::Exception& caughtException) {
172  caughtException.addContext(std::string{"While initializing meta data for branch: "} + branchName());
173  throw;
174  }
175 
177  try {
178  setWrappedType(wrType);
179  if (!bool(wrappedType())) {
182  return;
183  }
184  } catch (edm::Exception& caughtException) {
185  caughtException.addContext(std::string{"While initializing meta data for branch: "} + branchName());
186  throw;
187  }
188 
189  setTransient(false);
192  TDictAttributeMap* wp = wrappedType().getClass()->GetAttributeMap();
193  if (wp && wp->HasKey("persistent") && !strcmp(wp->GetPropertyAsString("persistent"), "false")) {
194  // Set transient if persistent == "false".
195  setTransient(true);
196  return;
197  } else {
198  // Module labels of persistent products cannot contain underscores,
199  // but for non-persistent products it is allowed because path names
200  // are used as module labels for path status products and there
201  // are many path names that include underscores.
202  char const underscore('_');
203  if (moduleLabel_.find(underscore) != std::string::npos) {
204  throw cms::Exception("IllegalCharacter")
205  << "Module label '" << moduleLabel()
206  << "' contains an underscore ('_'), which is illegal in a module label.\n";
207  }
208  }
209 
210  if (wp && wp->HasKey("splitLevel")) {
211  setSplitLevel(strtol(wp->GetPropertyAsString("splitLevel"), nullptr, 0));
212  if (splitLevel() < 0) {
213  throw cms::Exception("IllegalSplitLevel") << "' An illegal ROOT split level of " << splitLevel()
214  << " is specified for class " << wrappedName() << ".'\n";
215  }
216  setSplitLevel(splitLevel() + 1); //Compensate for wrapper
217  }
218  if (wp && wp->HasKey("basketSize")) {
219  setBasketSize(strtol(wp->GetPropertyAsString("basketSize"), nullptr, 0));
220  if (basketSize() <= 0) {
221  throw cms::Exception("IllegalBasketSize") << "' An illegal ROOT basket size of " << basketSize()
222  << " is specified for class " << wrappedName() << "'.\n";
223  }
224  }
225  }
226 
228  branchAliases_.insert(other.branchAliases().begin(), other.branchAliases().end());
229  if (splitLevel() == invalidSplitLevel)
230  setSplitLevel(other.splitLevel());
231  if (basketSize() == invalidBasketSize)
232  setBasketSize(other.basketSize());
233  }
234 
236  if (branchType_ != aliasForBranch.branchType()) {
237  throw Exception(errors::LogicError) << "BranchDescription::setSwitchAliasForBranch: branchType (" << branchType_
238  << ") differs from aliasForBranch (" << aliasForBranch.branchType()
239  << ").\nPlease report this error to the FWCore developers";
240  }
241  if (produced() != aliasForBranch.produced()) {
242  throw Exception(errors::LogicError) << "BranchDescription::setSwitchAliasForBranch: produced differs from "
243  "aliasForBranch.\nPlease report this error to the FWCore developers";
244  }
245  if (unwrappedTypeID().typeInfo() != aliasForBranch.unwrappedType().typeInfo()) {
247  << "BranchDescription::setSwitchAliasForBranch: unwrapped type info (" << unwrappedTypeID().name()
248  << ") differs from aliasForBranch (" << aliasForBranch.unwrappedType().typeInfo().name()
249  << ").\nPlease report this error to the FWCore developers";
250  }
251 
252  branchAliases_ = aliasForBranch.branchAliases();
255  }
256 
257  void BranchDescription::write(std::ostream& os) const {
258  os << "Branch Type = " << branchType() << std::endl;
259  os << "Process Name = " << processName() << std::endl;
260  os << "ModuleLabel = " << moduleLabel() << std::endl;
261  os << "Branch ID = " << branchID() << '\n';
262  os << "Class Name = " << fullClassName() << '\n';
263  os << "Friendly Class Name = " << friendlyClassName() << '\n';
264  os << "Product Instance Name = " << productInstanceName() << std::endl;
265  }
266 
267  void throwExceptionWithText(char const* txt) {
269  e << "Problem using an incomplete BranchDescription\n"
270  << txt << "\nPlease report this error to the FWCore developers";
271  throw e;
272  }
273 
276  throwExceptionWithText("Illegal BranchType detected");
277 
278  if (moduleLabel_.empty())
279  throwExceptionWithText("Module label is not allowed to be empty");
280 
281  if (processName_.empty())
282  throwExceptionWithText("Process name is not allowed to be empty");
283 
284  if (fullClassName_.empty())
285  throwExceptionWithText("Full class name is not allowed to be empty");
286 
287  if (friendlyClassName_.empty())
288  throwExceptionWithText("Friendly class name is not allowed to be empty");
289 
290  if (produced() && !parameterSetID().isValid())
291  throwExceptionWithText("Invalid ParameterSetID detected");
292  }
293 
296  clearBranchName();
297  initBranchName();
298  }
299 
301  if (a.processName() < b.processName())
302  return true;
303  if (b.processName() < a.processName())
304  return false;
305  if (a.fullClassName() < b.fullClassName())
306  return true;
307  if (b.fullClassName() < a.fullClassName())
308  return false;
309  if (a.friendlyClassName() < b.friendlyClassName())
310  return true;
311  if (b.friendlyClassName() < a.friendlyClassName())
312  return false;
313  if (a.productInstanceName() < b.productInstanceName())
314  return true;
315  if (b.productInstanceName() < a.productInstanceName())
316  return false;
317  if (a.moduleLabel() < b.moduleLabel())
318  return true;
319  if (b.moduleLabel() < a.moduleLabel())
320  return false;
321  if (a.branchType() < b.branchType())
322  return true;
323  if (b.branchType() < a.branchType())
324  return false;
325  if (a.branchID() < b.branchID())
326  return true;
327  if (b.branchID() < a.branchID())
328  return false;
329  if (a.branchAliases() < b.branchAliases())
330  return true;
331  if (b.branchAliases() < a.branchAliases())
332  return false;
333  if (a.present() < b.present())
334  return true;
335  if (b.present() < a.present())
336  return false;
337  return false;
338  }
339 
341  return (a.branchType() == b.branchType()) && (a.processName() == b.processName()) &&
342  (a.fullClassName() == b.fullClassName()) && (a.friendlyClassName() == b.friendlyClassName()) &&
343  (a.productInstanceName() == b.productInstanceName()) && (a.moduleLabel() == b.moduleLabel()) &&
344  (a.branchID() == b.branchID());
345  }
346 
348  return combinable(a, b) && (a.dropped() == b.dropped()) && (a.branchAliases() == b.branchAliases());
349  }
350 
352  std::ostringstream differences;
353  if (a.branchName() != b.branchName()) {
354  differences << "Branch name '" << b.branchName() << "' does not match '" << a.branchName() << "'.\n";
355  // Need not compare components of branch name individually.
356  // (a.friendlyClassName() != b.friendlyClassName())
357  // (a.moduleLabel() != b.moduleLabel())
358  // (a.productInstanceName() != b.productInstanceName())
359  // (a.processName() != b.processName())
360  }
361  if (a.branchType() != b.branchType()) {
362  differences << "Branch '" << b.branchName() << "' is a(n) '" << b.branchType() << "' branch\n";
363  differences << " in file '" << fileName << "', but a(n) '" << a.branchType()
364  << "' branch in previous files.\n";
365  }
366  if (a.branchID() != b.branchID()) {
367  differences << "Branch '" << b.branchName() << "' has a branch ID of '" << b.branchID() << "'\n";
368  differences << " in file '" << fileName << "', but '" << a.branchID() << "' in previous files.\n";
369  }
370  if (a.fullClassName() != b.fullClassName()) {
371  differences << "Products on branch '" << b.branchName() << "' have type '" << b.fullClassName() << "'\n";
372  differences << " in file '" << fileName << "', but '" << a.fullClassName() << "' in previous files.\n";
373  }
374  if (!b.dropped() && a.dropped()) {
375  differences << "Branch '" << a.branchName() << "' was dropped in the first input file but is present in '"
376  << fileName << "'.\n";
377  }
378  return differences.str();
379  }
380 } // namespace edm
size
Write out results.
bool operator<(DetSet< T > const &x, DetSet< T > const &y)
Definition: DetSet.h:89
constexpr bool operator==(ELseverityLevel const &e1, ELseverityLevel const &e2) noexcept
const char * name() const
Definition: TypeIDBase.h:44
ParameterSetID const & parameterSetID() const
static int const invalidSplitLevel
BranchID const & branchID() const
static int const invalidBasketSize
BranchType const & branchType() const
void setOnDemand(bool isOnDemand)
std::string const & fullClassName() const
std::string const & moduleName() const
TypeID unwrappedTypeID() const
std::string const & processName() const
TypeWithDict const & unwrappedType() const
std::string const & friendlyClassName() const
bool isValid() const
Definition: Hash.h:141
BranchType
Definition: BranchType.h:11
void setWrappedType(TypeWithDict const &type)
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:74
bool isValid() const
Definition: BranchID.h:22
void setTransient(bool isTransient)
std::string friendlyName(std::string const &iFullName)
std::string const & branchName() const
bool combinable(BranchDescription const &a, BranchDescription const &b)
std::string const & productInstanceName() const
void setWrappedName(std::string const &name)
void setSplitLevel(int level)
void setDropped(bool isDropped)
std::string const & wrappedName() const
void throwExceptionWithText(char const *txt)
std::type_info const & typeInfo() const
std::string wrappedClassName(std::string const &iFullName)
double b
Definition: hdecay.h:118
void addContext(std::string const &context)
Definition: Exception.cc:165
void write(std::ostream &os) const
TClass * getClass() const
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:27
std::set< std::string > branchAliases_
bool availableOnlyAtEndTransition() const
HLT enums.
double a
Definition: hdecay.h:119
void setUnwrappedType(TypeWithDict const &type)
void setBasketSize(int size)
void setProduced(bool isProduced)
void setSwitchAliasForBranch(BranchDescription const &aliasForBranch)
std::string const & moduleLabel() const
TypeWithDict const & wrappedType() const
std::string className(const T &t)
Definition: ClassName.h:31
std::set< std::string > const & branchAliases() const
void setID(std::string const &branchName)
Definition: BranchID.h:20
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)
void merge(BranchDescription const &other)
BranchID const & originalBranchID() const