BranchDescription.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
11 
12 #include <cassert>
13 #include <ostream>
14 
15 using namespace std;
16 
18 
19 namespace {
20 
21  [[noreturn]] void
22  throwExceptionWithText(char const* txt)
23  {
25  << "Problem using an incomplete BranchDescription\n"
26  << txt << "\nPlease report this error to the ART developers\n";
27  }
28 
29 } // unnamed namespace
30 
31 namespace art {
32 
33  BranchDescription::BranchDescription(
34  BranchType const bt,
35  TypeLabel const& tl,
36  std::string const& moduleLabel,
37  ParameterSetID const& modulePSetID,
38  ProcessConfiguration const& processConfig)
40  tl.hasEmulatedModule() ? tl.emulatedModule() :
42  processConfig.processName(),
43  tl.className(),
45  modulePSetID,
46  processConfig.id(),
49  tl.supportsView(),
50  tl.transient()}
51  {}
52 
54  BranchType const branchType,
55  std::string const& moduleLabel,
56  std::string const& processName,
60  ProcessConfigurationID const& processConfigurationID,
61  Transients::validity_state const validity,
62  bool const supportsView,
63  bool const transient)
64  : branchType_{branchType}
71  {
72  guts().validity_ = validity;
73  guts().transient_ = transient;
74  psetIDs_.insert(psetID);
75  processConfigurationIDs_.insert(processConfigurationID);
79  }
80 
81  void
83  {
84  if (!transientsFluffed_()) {
85  return;
86  }
87  if (!productID_.isValid()) {
88  productID_.setID(guts().branchName_);
89  }
90  }
91 
92  void
94  {
95  if (transientsFluffed_()) {
96  return;
97  }
98  transients_.get().branchName_ = canonicalProductName(
100  transients_.get().wrappedName_ = wrappedClassName(producedClassName_);
101  }
102 
103  ParameterSetID const&
105  {
106  assert(!psetIDs().empty());
107  if (psetIDs().size() != 1) {
108  throw Exception(errors::Configuration, "AmbiguousProvenance")
109  << "Your application requires all events on Branch '"
110  << guts().branchName_
111  << "'\n to have the same provenance. This file has events with "
112  "mixed provenance\n"
113  << "on this branch. Use a different input file.\n";
114  }
115  return *psetIDs().begin();
116  }
117 
118  void
120  {
121  psetIDs_.insert(other.psetIDs().begin(), other.psetIDs().end());
122  processConfigurationIDs_.insert(other.processConfigurationIDs().begin(),
123  other.processConfigurationIDs().end());
125  guts().splitLevel_ = other.guts().splitLevel_;
126  }
127  if (guts().basketSize_ == invalidBasketSize) {
128  guts().basketSize_ = other.guts().basketSize_;
129  }
130  // FIXME: This is probably wrong! We are going from defaulted compression
131  // to a possibly different compression, bad.
132  if (guts().compression_ == invalidCompression) {
133  guts().compression_ = other.guts().compression_;
134  }
135  }
136 
137  void
138  BranchDescription::write(ostream& os) const
139  {
140  os << "Branch Type = " << branchType_ << endl;
141  os << "Process Name = " << processName() << endl;
142  os << "ModuleLabel = " << moduleLabel() << endl;
143  os << "Product ID = " << productID() << '\n';
144  os << "Class Name = " << producedClassName() << '\n';
145  os << "Friendly Class Name = " << friendlyClassName() << '\n';
146  os << "Product Instance Name = " << productInstanceName() << endl;
147  }
148 
149  void
151  {
152  using std::swap;
153  swap(branchType_, other.branchType_);
156  swap(productID_, other.productID_);
161  swap(psetIDs_, other.psetIDs_);
163  swap(transients_, other.transients_);
164  }
165 
166  // Note: throws
167  void
169  {
170  constexpr char underscore('_');
171  if (transientsFluffed_()) {
172  return;
173  }
174  if (branchType_ >= NumBranchTypes) {
175  throwExceptionWithText("Illegal BranchType detected");
176  }
177  if (moduleLabel_.empty()) {
178  throwExceptionWithText("Module label is not allowed to be empty");
179  }
180  if (processName_.empty()) {
181  throwExceptionWithText("Process name is not allowed to be empty");
182  }
183  if (producedClassName_.empty()) {
184  throwExceptionWithText("Full class name is not allowed to be empty");
185  }
186  if (friendlyClassName_.empty()) {
187  throwExceptionWithText("Friendly class name is not allowed to be empty");
188  }
189  if (friendlyClassName_.find(underscore) != string::npos) {
190  throw Exception(errors::LogicError, "IllegalCharacter")
191  << "Class name '" << friendlyClassName()
192  << "' contains an underscore ('_'), which is illegal in the "
193  << "name of a product.\n";
194  }
195  if (moduleLabel_.find(underscore) != string::npos) {
196  throw Exception(errors::Configuration, "IllegalCharacter")
197  << "Module label '" << moduleLabel()
198  << "' contains an underscore ('_'), which is illegal in a "
199  << "module label.\n";
200  }
201  if (productInstanceName_.find(underscore) != string::npos) {
202  throw Exception(errors::Configuration, "IllegalCharacter")
203  << "Product instance name '" << productInstanceName()
204  << "' contains an underscore ('_'), which is illegal in a "
205  << "product instance name.\n";
206  }
207  if (processName_.find(underscore) != string::npos) {
208  throw Exception(errors::Configuration, "IllegalCharacter")
209  << "Process name '" << processName()
210  << "' contains an underscore ('_'), which is illegal in a "
211  << "process name.\n";
212  }
213  }
214 
215  bool
217  {
218  return !guts().branchName_.empty();
219  }
220 
221  bool
223  {
224  return psetIDs().size() == 1;
225  }
226 
227  set<ProcessConfigurationID> const&
229  {
231  }
232 
235  {
236  return transients_.get();
237  }
238 
241  {
242  return transients_.get();
243  }
244 
245  bool
247  {
248  if (a.processName() < b.processName()) {
249  return true;
250  }
251  if (b.processName() < a.processName()) {
252  return false;
253  }
254  if (a.producedClassName() < b.producedClassName()) {
255  return true;
256  }
257  if (b.producedClassName() < a.producedClassName()) {
258  return false;
259  }
260  if (a.friendlyClassName() < b.friendlyClassName()) {
261  return true;
262  }
263  if (b.friendlyClassName() < a.friendlyClassName()) {
264  return false;
265  }
267  return true;
268  }
270  return false;
271  }
272  if (a.moduleLabel() < b.moduleLabel()) {
273  return true;
274  }
275  if (b.moduleLabel() < a.moduleLabel()) {
276  return false;
277  }
278  if (a.branchType() < b.branchType()) {
279  return true;
280  }
281  if (b.branchType() < a.branchType()) {
282  return false;
283  }
284  if (a.productID() < b.productID()) {
285  return true;
286  }
287  if (b.productID() < a.productID()) {
288  return false;
289  }
290  if (a.psetIDs() < b.psetIDs()) {
291  return true;
292  }
293  if (b.psetIDs() < a.psetIDs()) {
294  return false;
295  }
297  return true;
298  }
300  return false;
301  }
302  return false;
303  }
304 
305  bool
307  {
308  return (a.branchType() == b.branchType()) &&
309  (a.processName() == b.processName()) &&
310  (a.producedClassName() == b.producedClassName()) &&
311  (a.friendlyClassName() == b.friendlyClassName()) &&
313  (a.moduleLabel() == b.moduleLabel()) &&
314  (a.productID() == b.productID());
315  }
316 
317  bool
319  {
320  return combinable(a, b) && (a.psetIDs() == b.psetIDs()) &&
322  }
323 
324  std::ostream&
325  operator<<(std::ostream& os, BranchDescription const& p)
326  {
327  p.write(os);
328  return os;
329  }
330 
331 } // namespace art
std::string const & productInstanceName() const
Definition: TypeLabel.h:51
fhicl::ParameterSetID const & psetID() const
std::string const & emulatedModule() const
Definition: TypeLabel.cc:31
void merge(BranchDescription const &other)
std::set< fhicl::ParameterSetID > const & psetIDs() const noexcept
void fluffTransients_() const
bool hasEmulatedModule() const
Definition: TypeLabel.h:56
std::string string
Definition: nybbler.cc:12
std::string wrappedClassName(std::string const &className)
static int constexpr invalidCompression
STL namespace.
bool supportsView() const noexcept
friend bool operator<(BranchDescription const &, BranchDescription const &)
std::set< ProcessConfigurationID > processConfigurationIDs_
std::set< ProcessConfigurationID > const & processConfigurationIDs() const noexcept
bool supportsView() const
Definition: TypeLabel.h:61
ProcessConfigurationID id() const
std::string const & processName() const noexcept
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
BranchType branchType() const noexcept
std::ostream & operator<<(std::ostream &os, const GroupSelector &gs)
bt
Definition: tracks.py:83
void swap(Handle< T > &a, Handle< T > &b)
const double a
constexpr bool isValid() const noexcept
Definition: ProductID.h:34
static int constexpr invalidSplitLevel
p
Definition: test.py:223
void swap(BranchDescription &other)
std::string canonicalProductName(std::string const &friendlyClassName, std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName)
void setID(std::string const &canonicalProductName)
Definition: ProductID.cc:13
void write(std::ostream &os) const
std::string friendlyName(std::string const &iFullName)
std::string const & moduleLabel() const noexcept
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::set< fhicl::ParameterSetID > psetIDs_
bool transientsFluffed_() const noexcept
bool isPsetIDUnique() const noexcept
bool transient() const
Definition: TypeLabel.h:66
std::string const & productInstanceName() const noexcept
BranchType
Definition: BranchType.h:20
std::string const & producedClassName() const noexcept
static bool * b
Definition: config.cpp:1043
std::string const & processName() const noexcept
friend bool combinable(BranchDescription const &, BranchDescription const &)
std::string const & friendlyClassName() const noexcept
static int constexpr invalidBasketSize
std::string className() const
Definition: TypeLabel.h:40
friend bool operator==(BranchDescription const &, BranchDescription const &)
Transient< Transients > transients_
ProductID productID() const noexcept
Transients & guts() noexcept
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
QTextStream & endl(QTextStream &s)
Definition: Hash.h:32