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  isTransform_(false),
31  dropped_(false),
32  transient_(false),
33  availableOnlyAtEndTransition_(false),
34  isMergeable_(false) {}
35 
37 
40  moduleLabel_(),
41  processName_(),
42  branchID_(),
48  transient_() {
49  // do not call init here! It will result in an exception throw.
50  }
51 
53  std::string const& moduleLabel,
54  std::string const& processName,
55  std::string const& className,
56  std::string const& friendlyClassName,
57  std::string const& productInstanceName,
58  std::string const& moduleName,
59  ParameterSetID const& parameterSetID,
60  TypeWithDict const& theTypeWithDict,
61  bool produced,
62  bool availableOnlyAtEndTransition,
63  std::set<std::string> const& aliases)
64  : branchType_(branchType),
65  moduleLabel_(moduleLabel),
66  processName_(processName),
67  branchID_(),
68  fullClassName_(className),
69  friendlyClassName_(friendlyClassName),
70  productInstanceName_(productInstanceName),
71  branchAliases_(aliases),
72  transient_() {
73  setDropped(false);
75  setOnDemand(false);
79  setUnwrappedType(theTypeWithDict);
80  init();
81  }
82 
84  std::string const& moduleLabelAlias,
85  std::string const& productInstanceAlias)
86  : branchType_(aliasForBranch.branchType()),
87  moduleLabel_(moduleLabelAlias),
88  processName_(aliasForBranch.processName()),
89  branchID_(),
90  fullClassName_(aliasForBranch.className()),
91  friendlyClassName_(aliasForBranch.friendlyClassName()),
92  productInstanceName_(productInstanceAlias),
93  branchAliases_(aliasForBranch.branchAliases()),
94  aliasForBranchID_(aliasForBranch.branchID()),
95  transient_() {
96  setDropped(false);
97  setProduced(aliasForBranch.produced());
98  setOnDemand(false); // will be re-set externally to the aliasForBranch.onDemand() after that one has been set
100  transient_.moduleName_ = aliasForBranch.moduleName();
101  transient_.parameterSetID_ = aliasForBranch.parameterSetID();
102  setUnwrappedType(aliasForBranch.unwrappedType());
103  init();
104  }
105 
107  if (!branchName().empty()) {
108  return; // already called
109  }
110  throwIfInvalid_();
111 
112  char const underscore('_');
113  char const period('.');
114 
115  if (friendlyClassName_.find(underscore) != std::string::npos) {
116  throw cms::Exception("IllegalCharacter")
117  << "Class name '" << friendlyClassName()
118  << "' contains an underscore ('_'), which is illegal in the name of a product.\n";
119  }
120 
121  // Module labels of non-persistent products are allowed to contain
122  // underscores. For module labels of persistent products, the module
123  // label is checked for underscores in the function initFromDictionary
124  // after we determine whether the product is persistent or not.
125 
126  if (productInstanceName_.find(underscore) != std::string::npos) {
127  throw cms::Exception("IllegalCharacter")
128  << "Product instance name '" << productInstanceName()
129  << "' contains an underscore ('_'), which is illegal in a product instance name.\n";
130  }
131 
132  if (processName_.find(underscore) != std::string::npos) {
133  throw cms::Exception("IllegalCharacter")
134  << "Process name '" << processName()
135  << "' contains an underscore ('_'), which is illegal in a process name.\n";
136  }
137 
139  brName.reserve(friendlyClassName().size() + moduleLabel().size() + productInstanceName().size() +
140  processName().size() + 4);
141  brName += friendlyClassName();
142  brName += underscore;
143  brName += moduleLabel();
144  brName += underscore;
145  brName += productInstanceName();
146  brName += underscore;
147  brName += processName();
148  brName += period;
149 
150  if (!branchID_.isValid()) {
151  branchID_.setID(brName);
152  }
153  }
154 
156  if (bool(wrappedType())) {
157  return; // already initialized;
158  }
159 
160  throwIfInvalid_();
161 
162  try {
164  // unwrapped type.
166  if (!bool(unwrappedType())) {
169  setTransient(false);
170  return;
171  }
172  } catch (edm::Exception& caughtException) {
173  caughtException.addContext(std::string{"While initializing meta data for branch: "} + branchName());
174  throw;
175  }
176 
178  try {
179  setWrappedType(wrType);
180  if (!bool(wrappedType())) {
183  return;
184  }
185  } catch (edm::Exception& caughtException) {
186  caughtException.addContext(std::string{"While initializing meta data for branch: "} + branchName());
187  throw;
188  }
189 
190  setTransient(false);
193  TDictAttributeMap* wp = wrappedType().getClass()->GetAttributeMap();
194  if (wp && wp->HasKey("persistent") && !strcmp(wp->GetPropertyAsString("persistent"), "false")) {
195  // Set transient if persistent == "false".
196  setTransient(true);
197  return;
198  } else {
199  // Module labels of persistent products cannot contain underscores,
200  // but for non-persistent products it is allowed because path names
201  // are used as module labels for path status products and there
202  // are many path names that include underscores.
203  char const underscore('_');
204  if (moduleLabel_.find(underscore) != std::string::npos) {
205  throw cms::Exception("IllegalCharacter")
206  << "Module label '" << moduleLabel()
207  << "' contains an underscore ('_'), which is illegal in a module label.\n";
208  }
209  }
210 
211  if (wp && wp->HasKey("splitLevel")) {
212  setSplitLevel(strtol(wp->GetPropertyAsString("splitLevel"), nullptr, 0));
213  if (splitLevel() < 0) {
214  throw cms::Exception("IllegalSplitLevel") << "' An illegal ROOT split level of " << splitLevel()
215  << " is specified for class " << wrappedName() << ".'\n";
216  }
217  setSplitLevel(splitLevel() + 1); //Compensate for wrapper
218  }
219  if (wp && wp->HasKey("basketSize")) {
220  setBasketSize(strtol(wp->GetPropertyAsString("basketSize"), nullptr, 0));
221  if (basketSize() <= 0) {
222  throw cms::Exception("IllegalBasketSize") << "' An illegal ROOT basket size of " << basketSize()
223  << " is specified for class " << wrappedName() << "'.\n";
224  }
225  }
226  }
227 
229  branchAliases_.insert(other.branchAliases().begin(), other.branchAliases().end());
230  if (splitLevel() == invalidSplitLevel)
231  setSplitLevel(other.splitLevel());
232  if (basketSize() == invalidBasketSize)
233  setBasketSize(other.basketSize());
234  }
235 
237  if (branchType_ != aliasForBranch.branchType()) {
238  throw Exception(errors::LogicError) << "BranchDescription::setSwitchAliasForBranch: branchType (" << branchType_
239  << ") differs from aliasForBranch (" << aliasForBranch.branchType()
240  << ").\nPlease report this error to the FWCore developers";
241  }
242  if (produced() != aliasForBranch.produced()) {
243  throw Exception(errors::LogicError) << "BranchDescription::setSwitchAliasForBranch: produced differs from "
244  "aliasForBranch.\nPlease report this error to the FWCore developers";
245  }
246  if (unwrappedTypeID().typeInfo() != aliasForBranch.unwrappedType().typeInfo()) {
248  << "BranchDescription::setSwitchAliasForBranch: unwrapped type info (" << unwrappedTypeID().name()
249  << ") differs from aliasForBranch (" << aliasForBranch.unwrappedType().typeInfo().name()
250  << ").\nPlease report this error to the FWCore developers";
251  }
252 
253  branchAliases_ = aliasForBranch.branchAliases();
256  }
257 
258  void BranchDescription::write(std::ostream& os) const {
259  os << "Branch Type = " << branchType() << std::endl;
260  os << "Process Name = " << processName() << std::endl;
261  os << "ModuleLabel = " << moduleLabel() << std::endl;
262  os << "Branch ID = " << branchID() << '\n';
263  os << "Class Name = " << fullClassName() << '\n';
264  os << "Friendly Class Name = " << friendlyClassName() << '\n';
265  os << "Product Instance Name = " << productInstanceName() << std::endl;
266  }
267 
268  void throwExceptionWithText(char const* txt) {
270  e << "Problem using an incomplete BranchDescription\n"
271  << txt << "\nPlease report this error to the FWCore developers";
272  throw e;
273  }
274 
277  throwExceptionWithText("Illegal BranchType detected");
278 
279  if (moduleLabel_.empty())
280  throwExceptionWithText("Module label is not allowed to be empty");
281 
282  if (processName_.empty())
283  throwExceptionWithText("Process name is not allowed to be empty");
284 
285  if (fullClassName_.empty())
286  throwExceptionWithText("Full class name is not allowed to be empty");
287 
288  if (friendlyClassName_.empty())
289  throwExceptionWithText("Friendly class name is not allowed to be empty");
290 
291  if (produced() && !parameterSetID().isValid())
292  throwExceptionWithText("Invalid ParameterSetID detected");
293  }
294 
297  clearBranchName();
298  initBranchName();
299  }
300 
302  if (a.processName() < b.processName())
303  return true;
304  if (b.processName() < a.processName())
305  return false;
306  if (a.fullClassName() < b.fullClassName())
307  return true;
308  if (b.fullClassName() < a.fullClassName())
309  return false;
310  if (a.friendlyClassName() < b.friendlyClassName())
311  return true;
312  if (b.friendlyClassName() < a.friendlyClassName())
313  return false;
314  if (a.productInstanceName() < b.productInstanceName())
315  return true;
316  if (b.productInstanceName() < a.productInstanceName())
317  return false;
318  if (a.moduleLabel() < b.moduleLabel())
319  return true;
320  if (b.moduleLabel() < a.moduleLabel())
321  return false;
322  if (a.branchType() < b.branchType())
323  return true;
324  if (b.branchType() < a.branchType())
325  return false;
326  if (a.branchID() < b.branchID())
327  return true;
328  if (b.branchID() < a.branchID())
329  return false;
330  if (a.branchAliases() < b.branchAliases())
331  return true;
332  if (b.branchAliases() < a.branchAliases())
333  return false;
334  if (a.present() < b.present())
335  return true;
336  if (b.present() < a.present())
337  return false;
338  return false;
339  }
340 
342  return (a.branchType() == b.branchType()) && (a.processName() == b.processName()) &&
343  (a.fullClassName() == b.fullClassName()) && (a.friendlyClassName() == b.friendlyClassName()) &&
344  (a.productInstanceName() == b.productInstanceName()) && (a.moduleLabel() == b.moduleLabel()) &&
345  (a.branchID() == b.branchID());
346  }
347 
349  return combinable(a, b) && (a.dropped() == b.dropped()) && (a.branchAliases() == b.branchAliases());
350  }
351 
353  std::ostringstream differences;
354  if (a.branchName() != b.branchName()) {
355  differences << "Branch name '" << b.branchName() << "' does not match '" << a.branchName() << "'.\n";
356  // Need not compare components of branch name individually.
357  // (a.friendlyClassName() != b.friendlyClassName())
358  // (a.moduleLabel() != b.moduleLabel())
359  // (a.productInstanceName() != b.productInstanceName())
360  // (a.processName() != b.processName())
361  }
362  if (a.branchType() != b.branchType()) {
363  differences << "Branch '" << b.branchName() << "' is a(n) '" << b.branchType() << "' branch\n";
364  differences << " in file '" << fileName << "', but a(n) '" << a.branchType()
365  << "' branch in previous files.\n";
366  }
367  if (a.branchID() != b.branchID()) {
368  differences << "Branch '" << b.branchName() << "' has a branch ID of '" << b.branchID() << "'\n";
369  differences << " in file '" << fileName << "', but '" << a.branchID() << "' in previous files.\n";
370  }
371  if (a.fullClassName() != b.fullClassName()) {
372  differences << "Products on branch '" << b.branchName() << "' have type '" << b.fullClassName() << "'\n";
373  differences << " in file '" << fileName << "', but '" << a.fullClassName() << "' in previous files.\n";
374  }
375  if (!b.dropped() && a.dropped()) {
376  differences << "Branch '" << a.branchName() << "' was dropped in the first input file but is present in '"
377  << fileName << "'.\n";
378  }
379  return differences.str();
380  }
381 } // 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:169
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