LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
Source.h
Go to the documentation of this file.
1 #ifndef art_Framework_IO_Sources_Source_h
2 #define art_Framework_IO_Sources_Source_h
3 // vim: set sw=2 expandtab :
4 
5 // ======================================================================
6 //
7 // The Source class template is used to create InputSources which
8 // are capable of reading Runs, SubRuns and Events from non-standard
9 // input files. Sources instantiated from Source are *not* random
10 // access sources.
11 //
12 // The Source class template requires the use of a type T as its
13 // template parameter, satisfying the conditions outlined below. In
14 // one's XXX_module.cc class one must provide a type alias and module macro
15 // call along the lines of:
16 //
17 // namespace arttest {
18 // using GeneratorTest = art::Source<GeneratorTestDetail>;
19 // }
20 //
21 // DEFINE_ART_INPUT_SOURCE(arttest::GeneratorTest)
22 //
23 // However, there are several "flavors" of InputSource possible using
24 // this template, and one may wish to specify them using the "type
25 // traits" found in SourceTraits.h. Type traits are simple class
26 // templates that are used to signal properties of the classes used as
27 // their template arguments. Specialization is common. There are many
28 // examples of type traits in the standard, such as std::is_const<T> or
29 // std::is_integral<T>. Any traits you wish to specialize must be
30 // defined *after* the definition of your detail class T, but *before*
31 // the type alias above which will attempt to instantiate them. See
32 // SourceTraits.h for descriptions of the different traits one might
33 // wish to apply.
34 //
35 // The type T must supply the following non-static member functions:
36 //
37 // * Construct an object of type T. The ParameterSet provided will be
38 // that constructed by the 'source' statement in the job
39 // configuration file. The ProductRegistryHelper must be used to
40 // register products to be reconstituted by this source.
41 //
42 // T(fhicl::ParameterSet const&,
43 // art::ProductRegistryHelper&,
44 // art::SourceHelper const&);
45 //
46 // * Open the file of the given name, returning a new fileblock in
47 // fb. If readFile is unable to return a valid FileBlock it should
48 // throw. Suggestions for suitable exceptions are:
49 // art::Exception(art::errors::FileOpenError) or
50 // art::Exception(art::errors::FileReadError).
51 //
52 // void readFile(std::string const& filename,
53 // art::FileBlock*& fb);
54 //
55 // * Read the next part of the current file. Return false if nothing
56 // was read; return true and set the appropriate 'out' arguments if
57 // something was read.
58 //
59 // bool readNext(art::RunPrincipal const* const inR,
60 // art::SubRunPrincipal const* const inSR,
61 // art::RunPrincipal*& outR,
62 // art::SubRunPrincipal*& outSR,
63 // art::EventPrincipal*& outE);
64 //
65 // * After readNext has returned false, the behavior differs
66 // depending on whether Source_Generator<XXX>::value is true or
67 // false. If false (the default), then readFile(...) will be called
68 // provided there is an unused string remaining in
69 // source.fileNames. If true, then the source will finish unless
70 // there exists an *optional* function:
71 //
72 // bool hasMoreData(); // or
73 //
74 // bool hasMoreData() const;
75 //
76 // which returns true.
77 //
78 // * Close the current input file.
79 //
80 // void closeCurrentFile();
81 //
82 // ======================================================================
83 
90 #include "art/Framework/Core/fwd.h"
103 #include "cetlib/exempt_ptr.h"
104 #include "cetlib/metaprogramming.h"
105 #include "fhiclcpp/ParameterSet.h"
106 #include "fhiclcpp/types/Atom.h"
108 #include "fhiclcpp/types/Sequence.h"
110 
111 #include <algorithm>
112 #include <memory>
113 #include <type_traits>
114 
115 namespace art {
116 
117  template <typename T>
118  class Source;
119 
120  template <typename T>
121  class SourceTable {
122  public:
123  using value_type = T;
124 
125  auto const&
126  operator()() const
127  {
128  return fragment_();
129  }
130 
131  private:
133  };
134 
135  namespace detail {
136 
137  // Template metaprogramming.
138 
139  template <typename T, typename = void>
140  struct has_hasMoreData : std::false_type {};
141 
142  template <typename T>
144  T,
145  cet::enable_if_function_exists_t<bool (T::*)(), &T::hasMoreData>>
146  : std::true_type {};
147 
148  template <typename T>
150  T,
151  cet::enable_if_function_exists_t<bool (T::*)() const, &T::hasMoreData>>
152  : std::true_type {};
153 
154  template <typename T>
156  bool
158  {
159  return t.hasMoreData();
160  }
161  };
162 
163  template <typename T>
165  bool
167  {
168  return false;
169  }
170  };
171 
173  // Does the detail object have a Parameters type?
174  template <typename T, typename = void>
175  struct maybe_has_Parameters : std::false_type {
177  };
178 
179  template <typename T>
180  struct maybe_has_Parameters<T, std::void_t<typename T::Parameters>>
181  : std::true_type {
182  using user_config_t = typename T::Parameters;
183  struct Config {
184  struct SourceConfig {
186  fhicl::Sequence<std::string> fileNames{fhicl::Name("fileNames"), {}};
187  fhicl::Atom<int64_t> maxSubRuns{fhicl::Name("maxSubRuns"), -1};
188  fhicl::Atom<int64_t> maxEvents{fhicl::Name("maxEvents"), -1};
189  };
192  };
194  };
195 
196  } // namespace detail
197 
198  // No-one gets to override this class.
199  template <typename T>
200  class Source final : public InputSource {
201  public:
203 
204  template <typename U = Parameters>
205  explicit Source(std::enable_if_t<std::is_same_v<U, fhicl::ParameterSet>,
206  fhicl::ParameterSet> const& p,
208 
209  template <typename U = Parameters>
210  explicit Source(
211  std::enable_if_t<!std::is_same_v<U, fhicl::ParameterSet>, U> const& p,
213 
214  Source(Source<T> const&) = delete;
215  Source(Source<T>&&) = delete;
216 
217  Source<T>& operator=(Source<T> const&) = delete;
218  Source<T>& operator=(Source<T>&&) = delete;
219 
220  private:
221  input::ItemType nextItemType() override;
222  std::unique_ptr<FileBlock> readFile() override;
223  void closeFile() override;
224 
226 
227  std::unique_ptr<RunPrincipal> readRun() override;
228  std::unique_ptr<SubRunPrincipal> readSubRun(
229  cet::exempt_ptr<RunPrincipal const> rp) override;
230 
231  std::unique_ptr<EventPrincipal> readEvent(
232  cet::exempt_ptr<SubRunPrincipal const> srp) override;
233 
234  std::unique_ptr<RangeSetHandler> runRangeSetHandler() override;
235  std::unique_ptr<RangeSetHandler> subRunRangeSetHandler() override;
236 
237  // Called in the constructor, to finish the process of product
238  // registration.
239  void finishProductRegistration_(InputSourceDescription& d);
240 
241  // Make detail_ try to read more stuff from its file. Cache any new
242  // run/subrun/event. Throw an exception if we detect an error in the
243  // data stream, or logic of the detail_ class. Move to the
244  // appropriate new state.
245  bool readNext_();
246 
247  // Check to see whether we have a new file to attempt to read,
248  // moving to either the IsStop or IsFile state.
249  void checkForNextFile_();
250 
251  // Call readNext_() and throw if we have not moved to the IsRun state.
252  void readNextAndRequireRun_();
253 
254  // Call readNext_() and throw if we have moved to the IsEvent state.
255  void readNextAndRefuseEvent_();
256 
257  // Test the newly read data for validity, given our current state.
258  void throwIfInsane_(bool result,
259  RunPrincipal* newR,
260  SubRunPrincipal* newSR,
261  EventPrincipal* newE) const;
262 
263  // Throw an Exception(errors::DataCorruption), with the given
264  // message text.
265  [[noreturn]] static void throwDataCorruption_(const char* msg);
266 
270 
271  // So it can be used by detail.
276  std::string currentFileName_{};
277 
278  std::unique_ptr<RunPrincipal> newRP_{};
279  std::unique_ptr<SubRunPrincipal> newSRP_{};
280  std::unique_ptr<EventPrincipal> newE_{};
281 
282  // Cached Run and SubRun Principals used for users creating new
283  // SubRun and Event Principals. These are non owning!
284  cet::exempt_ptr<RunPrincipal> cachedRP_{nullptr};
285  cet::exempt_ptr<SubRunPrincipal> cachedSRP_{nullptr};
286 
287  bool pendingSubRun_{false};
288  bool pendingEvent_{false};
289  bool subRunIsNew_{false};
290  SubRunNumber_t remainingSubRuns_{1};
291  bool haveSRLimit_{false};
292  EventNumber_t remainingEvents_{1};
293  bool haveEventLimit_{false};
294  };
295 
296  template <typename T>
297  template <typename U>
298  Source<T>::Source(std::enable_if_t<std::is_same_v<U, fhicl::ParameterSet>,
299  fhicl::ParameterSet> const& p,
302  , outputCallbacks_{d.productRegistry}
303  , sourceHelper_{d.moduleDescription}
304  , detail_{p, h_, sourceHelper_}
305  , fh_{p.template get<std::vector<std::string>>("fileNames", {})}
306  {
307  int64_t const maxSubRuns_par = p.template get<int64_t>("maxSubRuns", -1);
308  if (maxSubRuns_par > -1) {
309  remainingSubRuns_ = maxSubRuns_par;
310  haveSRLimit_ = true;
311  }
312  int64_t const maxEvents_par = p.template get<int64_t>("maxEvents", -1);
313  if (maxEvents_par > -1) {
314  remainingEvents_ = maxEvents_par;
315  haveEventLimit_ = true;
316  }
318  }
319 
320  template <typename T>
321  template <typename U>
323  std::enable_if_t<!std::is_same_v<U, fhicl::ParameterSet>, U> const& p,
326  , outputCallbacks_{d.productRegistry}
327  , sourceHelper_{d.moduleDescription}
328  , detail_{p().userConfig, h_, sourceHelper_}
329  , fh_{p().sourceConfig().fileNames()}
330  {
331  if (int64_t const maxSubRuns_par = p().sourceConfig().maxSubRuns();
332  maxSubRuns_par > -1) {
333  remainingSubRuns_ = maxSubRuns_par;
334  haveSRLimit_ = true;
335  }
336  if (int64_t const maxEvents_par = p().sourceConfig().maxEvents();
337  maxEvents_par > -1) {
338  remainingEvents_ = maxEvents_par;
339  haveEventLimit_ = true;
340  }
342  }
343 
344  template <typename T>
345  void
347  {
348  throw Exception(errors::DataCorruption) << msg;
349  }
350 
351  template <typename T>
352  void
353  Source<T>::throwIfInsane_(bool const result,
354  RunPrincipal* newR,
355  SubRunPrincipal* newSR,
356  EventPrincipal* newE) const
357  {
358  std::ostringstream errMsg;
359  if (result) {
360  if (!newR && !newSR && !newE) {
362  << "readNext returned true but created no new data\n";
363  }
364  if (!cachedRP_ && !newR) {
366  << "readNext returned true but no RunPrincipal has been set, and no "
367  "cached RunPrincipal exists.\n"
368  "This can happen if a new input file has been opened and the "
369  "RunPrincipal has not been appropriately assigned.";
370  }
371  if (!cachedSRP_ && !newSR) {
373  << "readNext returned true but no SubRunPrincipal has been set, and "
374  "no cached SubRunPrincipal exists.\n"
375  "This can happen if a new input file has been opened and the "
376  "SubRunPrincipal has not been appropriately assigned.";
377  }
378  if (cachedRP_ && newR && cachedRP_.get() == newR) {
379  errMsg << "readNext returned a new Run which is the old Run for "
380  << cachedRP_->runID()
381  << ".\nIf you don't have a new run, don't return one!\n";
382  }
383  if (cachedSRP_ && newSR && cachedSRP_.get() == newSR) {
384  errMsg << "readNext returned a new SubRun which is the old SubRun for "
385  << cachedSRP_->subRunID()
386  << ".\nIf you don't have a new subRun, don't return one!\n";
387  }
388  // Either or both of the above cases could be true and we need
389  // to make both of them safe before we throw:
390  if (!errMsg.str().empty())
391  throw Exception(errors::LogicError) << errMsg.str();
392  if (cachedRP_ && cachedSRP_) {
393  if (!newR && newSR && newSR->subRunID() == cachedSRP_->subRunID())
394  throwDataCorruption_("readNext returned a 'new' SubRun "
395  "that was the same as the previous "
396  "SubRun\n");
397  if (newR && newR->runID() == cachedRP_->runID())
398  throwDataCorruption_("readNext returned a 'new' Run "
399  "that was the same as the previous "
400  "Run\n");
401  if (newR && !newSR && newE)
402  throwDataCorruption_("readNext returned a new Run and "
403  "Event without a SubRun\n");
404  if (newR && newSR && newSR->subRunID() == cachedSRP_->subRunID())
405  throwDataCorruption_("readNext returned a new Run with "
406  "a SubRun from the wrong Run\n");
407  }
408  RunID rID;
409  SubRunID srID;
410  EventID eID;
411  if (newR) {
412  rID = newR->runID();
413  if (!rID.isValid()) {
415  "readNext returned a Run with an invalid RunID.\n");
416  }
417  } else if (cachedRP_) {
418  rID = cachedRP_->runID();
419  }
420  if (newSR) {
421  srID = newSR->subRunID();
422  if (rID != srID.runID()) {
423  errMsg << "readNext returned a SubRun " << srID
424  << " which is a mismatch to " << rID << '\n';
425  throwDataCorruption_(errMsg.str().c_str());
426  }
427  if (!srID.isValid()) {
429  "readNext returned a SubRun with an invalid SubRunID.\n");
430  }
431  } else if (cachedSRP_) {
432  srID = cachedSRP_->subRunID();
433  }
434  if (newE) {
435  eID = newE->eventID();
436  if (srID != eID.subRunID()) {
437  errMsg << "readNext returned an Event " << eID
438  << " which is a mismatch to " << srID << '\n';
439  throwDataCorruption_(errMsg.str().c_str());
440  }
441  if (!eID.isValid()) {
443  "readNext returned an Event with an invalid EventID.\n");
444  }
445  }
446  } else {
447  if (newR || newSR || newE)
449  << "readNext returned false but created new data\n";
450  }
451  }
452 
453  template <typename T>
454  bool
456  {
457  std::unique_ptr<RunPrincipal> newR{nullptr};
458  std::unique_ptr<SubRunPrincipal> newSR{nullptr};
459  std::unique_ptr<EventPrincipal> newE{nullptr};
460  bool result{false};
461  {
462  RunPrincipal* nR{nullptr};
463  SubRunPrincipal* nSR{nullptr};
464  EventPrincipal* nE{nullptr};
465  result = detail_.readNext(cachedRP_.get(), cachedSRP_.get(), nR, nSR, nE);
466  newR.reset(nR);
467  newSR.reset(nSR);
468  newE.reset(nE);
469  throwIfInsane_(result, newR.get(), newSR.get(), newE.get());
470  }
471  if (result) {
472  subRunIsNew_ =
473  newSR && ((!cachedSRP_) || newSR->subRunID() != cachedSRP_->subRunID());
474  pendingSubRun_ = newSR.get() != nullptr;
475  pendingEvent_ = newE.get() != nullptr;
476  if (newR) {
477  newRP_ = std::move(newR);
478  }
479  if (newSR) {
480  auto rp = newRP_ ? newRP_.get() : cachedRP_.get();
481  newSR->setRunPrincipal(rp);
482  newSRP_ = std::move(newSR);
483  }
484  if (newE) {
485  auto srp = newSRP_ ? newSRP_.get() : cachedSRP_.get();
486  newE->setSubRunPrincipal(srp);
487  newE_ = std::move(newE);
488  }
489  if (newRP_) {
491  } else if (newSRP_) {
493  } else if (newE_) {
495  }
496  }
497  return result;
498  }
499 
500  template <typename T>
501  void
503  {
504  state_ = input::IsStop; // Default -- may change below.
509  generatorHasMoreData;
510  if (generatorHasMoreData(detail_)) {
512  }
513  } else {
514  currentFileName_ = fh_.next();
515  if (!currentFileName_.empty()) {
517  }
518  }
519  }
520 
521  template <typename T>
524  {
525  if (remainingEvents_ == 0) {
527  }
528  switch (state_) {
529  case input::IsInvalid:
531  state_ = input::IsFile; // Once.
532  } else {
534  }
535  break;
536  case input::IsFile:
538  break;
539  case input::IsRun:
542  pendingSubRun_ = false;
543  } else if (pendingEvent_)
545  << "Input file '" << currentFileName_ << "' contains an Event "
546  << newE_->eventID() << " that belongs to no SubRun\n";
547  else {
549  }
550  break;
551  case input::IsSubRun:
552  if (pendingEvent_) {
554  pendingEvent_ = false;
555  } else {
557  }
558  break;
559  case input::IsEvent:
560  if (!readNext_()) {
562  }
563  break;
564  case input::IsStop:
565  break;
566  }
567  if ((state_ == input::IsRun || state_ == input::IsSubRun) &&
568  remainingSubRuns_ == 0) {
570  }
571  if (state_ == input::IsStop) {
572  // FIXME: upon the advent of a catalog system which can do something
573  // intelligent with the difference between whole-file success,
574  // partial-file success, partial-file failure and whole-file failure
575  // (such as file-open failure), we will need to communicate that
576  // difference here. The file disposition options as they are now
577  // (and the mapping to any concrete implementation we are are aware
578  // of currently) are not sufficient to the task, so we deliberately
579  // do not distinguish here between partial-file and whole-file
580  // success in particular.
581  fh_.finish();
582  }
583  return state_;
584  }
585 
586  template <typename T>
587  void
589  {
590  if (readNext_()) {
591  if (state_ != input::IsRun) {
592  if (cachedRP_) {
593  state_ = input::IsRun; // Regurgitate existing cached run.
594  } else {
596  << "Input file '" << currentFileName_ << "' has a"
597  << (state_ == input::IsSubRun ? " SubRun" : "n Event")
598  << " where a Run is expected\n";
599  }
600  }
601  } else {
603  }
604  }
605 
606  template <typename T>
607  void
609  {
610  if (readNext_()) {
611  if (state_ == input::IsEvent) {
613  << "Input file '" << currentFileName_
614  << "' has an Event where a Run or SubRun is expected\n";
615  }
616  } else {
618  }
619  }
620 
621  template <typename T>
622  std::unique_ptr<RangeSetHandler>
624  {
625  return std::make_unique<OpenRangeSetHandler>(cachedRP_->run());
626  }
627 
628  template <typename T>
629  std::unique_ptr<RangeSetHandler>
631  {
632  return std::make_unique<OpenRangeSetHandler>(cachedSRP_->run());
633  }
634 
635  template <typename T>
636  std::unique_ptr<FileBlock>
638  {
639  FileBlock* newF{nullptr};
640  detail_.readFile(currentFileName_, newF);
641  if (!newF) {
643  << "detail_::readFile() failed to return a valid FileBlock object\n";
644  }
645  return std::unique_ptr<FileBlock>(newF);
646  }
647 
648  template <typename T>
649  void
651  {
652  detail_.closeCurrentFile();
653  // Cached pointers are no longer valid since the PrincipalCache is
654  // cleared after file close.
655  cachedRP_ = nullptr;
656  cachedSRP_ = nullptr;
657  }
658 
659  template <typename T>
660  std::unique_ptr<RunPrincipal>
662  {
663  if (!newRP_)
665  << "Error in Source<T>\n"
666  << "readRun() called when no RunPrincipal exists\n"
667  << "Please report this to the art developers\n";
668  cachedRP_ = newRP_.get();
669  return std::move(newRP_);
670  }
671 
672  template <typename T>
673  std::unique_ptr<SubRunPrincipal>
674  Source<T>::readSubRun(cet::exempt_ptr<RunPrincipal const>)
675  {
676  if (!newSRP_)
678  << "Error in Source<T>\n"
679  << "readSubRun() called when no SubRunPrincipal exists\n"
680  << "Please report this to the art developers\n";
681  if (subRunIsNew_) {
682  if (haveSRLimit_) {
684  }
685  subRunIsNew_ = false;
686  }
687  cachedSRP_ = newSRP_.get();
688  return std::move(newSRP_);
689  }
690 
691  template <typename T>
692  std::unique_ptr<EventPrincipal>
693  Source<T>::readEvent(cet::exempt_ptr<SubRunPrincipal const>)
694  {
695  if (haveEventLimit_) {
697  }
698  return std::move(newE_);
699  }
700 
701  template <typename T>
702  void
704  {
705  // These _xERROR_ strings should never appear in branch names; they
706  // are here as tracers to help identify any failures in coding.
707  ProductDescriptions descriptions;
709  descriptions,
711  "_NAMEERROR_",
712  "_LABELERROR_",
715  true /*isEmulated*/});
716  presentProducts_ = ProductTables{descriptions};
717  sourceHelper_.setPresentProducts(cet::make_exempt_ptr(&presentProducts_));
719  }
720 
721 } // namespace art
722 
723 #endif /* art_Framework_IO_Sources_Source_h */
724 
725 // Local Variables:
726 // mode: c++
727 // End:
bool isValid() const
Definition: EventID.h:122
static fhicl::Name plugin_type()
SubRunID const & subRunID() const
Definition: EventID.h:104
void checkForNextFile_()
Definition: Source.h:502
std::unique_ptr< EventPrincipal > readEvent(cet::exempt_ptr< SubRunPrincipal const > srp) override
Definition: Source.h:693
bool readNext_()
Definition: Source.h:455
bool pendingSubRun_
Definition: Source.h:287
virtual std::unique_ptr< EventPrincipal > readEvent(cet::exempt_ptr< SubRunPrincipal const > srp)=0
bool subRunIsNew_
Definition: Source.h:289
EventNumber_t remainingEvents_
Definition: Source.h:292
static void throwDataCorruption_(const char *msg)
Definition: Source.h:346
STL namespace.
std::vector< BranchDescription > ProductDescriptions
std::unique_ptr< RangeSetHandler > runRangeSetHandler() override
Definition: Source.h:623
bool isValid() const
Definition: SubRunID.h:97
std::unique_ptr< RangeSetHandler > subRunRangeSetHandler() override
Definition: Source.h:630
void readNextAndRequireRun_()
Definition: Source.h:588
void closeFile() override
Definition: Source.h:650
input::ItemType state_
Definition: Source.h:274
RunID const & runID() const
Definition: SubRunID.h:79
cet::exempt_ptr< SubRunPrincipal > cachedSRP_
Definition: Source.h:285
void registerProducts(ProductDescriptions &productsToRegister, ModuleDescription const &md)
std::unique_ptr< SubRunPrincipal > readSubRun(cet::exempt_ptr< RunPrincipal const > rp) override
Definition: Source.h:674
bool pendingEvent_
Definition: Source.h:288
std::unique_ptr< SubRunPrincipal > newSRP_
Definition: Source.h:279
input::ItemType nextItemType() override
Definition: Source.h:523
SourceHelper sourceHelper_
Definition: Source.h:272
EventID const & eventID() const
cet::exempt_ptr< RunPrincipal > cachedRP_
Definition: Source.h:284
ProductTables presentProducts_
Definition: Source.h:269
IDNumber_t< Level::SubRun > SubRunNumber_t
Definition: IDNumber.h:119
Float_t d
Definition: plot.C:235
Source(std::enable_if_t< std::is_same_v< U, fhicl::ParameterSet >, fhicl::ParameterSet > const &p, InputSourceDescription &d)
Definition: Source.h:298
void invoke(ProductTables const &)
std::unique_ptr< EventPrincipal > newE_
Definition: Source.h:280
void throwIfInsane_(bool result, RunPrincipal *newR, SubRunPrincipal *newSR, EventPrincipal *newE) const
Definition: Source.h:353
ProcessConfiguration const & processConfiguration() const
double value
Definition: spectrum.C:18
ParameterSetID id() const
static ProductTables invalid()
fhicl::TableFragment< T > fragment_
Definition: Source.h:132
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
void finishProductRegistration_(InputSourceDescription &d)
Definition: Source.h:703
std::unique_ptr< RunPrincipal > newRP_
Definition: Source.h:278
std::unique_ptr< FileBlock > readFile() override
Definition: Source.h:637
ProductRegistryHelper h_
Definition: Source.h:267
detail::FileNamesHandler< Source_wantFileServices< T >::value > fh_
Definition: Source.h:275
bool haveEventLimit_
Definition: Source.h:293
SubRunNumber_t remainingSubRuns_
Definition: Source.h:290
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:118
UpdateOutputCallbacks & outputCallbacks_
Definition: Source.h:268
bool isValid() const
Definition: RunID.h:70
ModuleDescription const & moduleDescription
Definition: MVAAlg.h:12
bool haveSRLimit_
Definition: Source.h:291
auto const & operator()() const
Definition: Source.h:126
void readNextAndRefuseEvent_()
Definition: Source.h:608
std::unique_ptr< RunPrincipal > readRun() override
Definition: Source.h:661
std::string currentFileName_
Definition: Source.h:276
typename detail::maybe_has_Parameters< T >::Parameters Parameters
Definition: Source.h:202
SubRunID subRunID() const
RunID runID() const
Definition: RunPrincipal.cc:54