EventProcessorTestSource_source.cc
Go to the documentation of this file.
1 // ==============================================================
2 // EventProcessorTestSource
3 //
4 // The purpose of this source is solely to drive the EventProcessor,
5 // which calls the input source's 'nextItemType()' override. Input
6 // files for this source are of a simple form (e.g.):
7 //
8 // r:1
9 // s:2
10 // e:1
11 // e:2
12 //
13 // where a Run item type with an ID number of 1 is started, a SubRun
14 // item type with an ID number of 2 is started, and Event item types
15 // with ID numbers of 1 and 2 are then processed. Special characters
16 // are also allowed for testing rarer circumstances the framework must
17 // support:
18 //
19 // r:f // Provide 'flush' value to indicate run closure
20 // s:t // Throw an exception during readSubRun
21 //
22 // N.B. For the purposes of this input source, an input specification
23 // of 'r:t' corresponds to assigning a run number value of
24 // art::IDNumber<art::Level::Run>::flush_value() - 1, which is used to
25 // determine whether readRun should throw an exception.
26 // ==============================================================
27 
43 #include "fhiclcpp/ParameterSet.h"
44 
45 #include <fstream>
46 #include <string>
47 #include <vector>
48 
49 namespace {
50  std::uint32_t
51  flush_value(char const level)
52  {
53  switch (level) {
54  case 'r':
56  case 's':
58  case 'e':
60  default:
62  << "Action specifying flush or throw value does not correspond to "
63  "'r', 's', "
64  "or 'e'.\n";
65  }
66  }
67 
68  std::uint32_t
69  throw_value(char const level)
70  {
71  return flush_value(level) - 1;
72  }
73 
74  std::uint32_t
75  number(std::string const& action)
76  {
77  if (std::count(action.begin(), action.end(), ':') != 1u) {
79  << "The specified action for \"" << action << "\" must\n"
80  << "contain only one ':'.";
81  }
82  auto const level = action.substr(0, 1);
83  auto const symbol = action.substr(2);
84  if (symbol.empty()) {
86  << "The symbol for \"" << action << "\" is empty.\n"
87  << "Please provide a positive number, or the character 'f' or 't'.\n";
88  }
89 
90  // For flush/throw values -- r:f, s:f, or e:f
91  if (std::isalpha(symbol[0])) {
92  if (symbol.size() != 1ull) {
94  << "There must be only one character after the colon in \"" << action
95  << "\".\n"
96  << "Please either the character 'f' or 't'.\n";
97  }
98  switch (symbol[0]) {
99  case 'f':
100  return flush_value(level[0]);
101  case 't':
102  return throw_value(level[0]);
103  default:
105  << "The character specified for a symbol must be 'f' or 't'.\n";
106  }
107  }
108 
109  // For everything else
110  return std::stoul(action.substr(2)); // (e.g.) e:14 - start at "14"
111  }
112 
113  constexpr auto
114  nullTimestamp()
115  {
116  return art::Timestamp{};
117  }
118 
119 } // namespace
120 
121 namespace arttest {
122 
124  public:
128  , pc_{isd.moduleDescription.processConfiguration()}
129  , fileNames_{ps.get<std::vector<std::string>>("fileNames")}
130  {}
131 
132  std::unique_ptr<art::FileBlock>
133  readFile() override
134  {
135  inputFile_.open(currentName_);
136  return std::make_unique<art::FileBlock>(
137  art::FileFormatVersion{1, "EventProcessorTestSource_2017a"},
138  currentName_);
139  }
140 
141  void
142  closeFile() override
143  {
144  inputFile_.close();
145  }
146 
148  nextItemType() override
149  {
151  std::string action{};
152  if (std::getline(inputFile_, action)) {
153  if (action[0] == 'r') {
154  auto const r = number(action);
157  art::RunID{r};
159  } else if (action[0] == 's') {
160  auto const sr = number(action);
165  } else if (action[0] == 'e') {
166  auto const e = number(action);
170  // a special value for test purposes only
171  if (event_.event() != 7) {
173  }
174  } else {
176  << "Test pattern \"" << action << "\" not recognized.";
177  }
178  } else if (!fileNames_.empty()) {
179  currentName_ = fileNames_.front();
180  fileNames_.erase(cbegin(fileNames_));
181  return art::input::IsFile;
182  }
183  return rc;
184  }
185 
186  std::unique_ptr<art::RunPrincipal>
187  readRun() override
188  {
189  if (run_.run() == throw_value('r')) {
190  throw art::Exception{
192  "There was an exception while reading a run from the input file."};
193  }
194 
195  art::RunAuxiliary const aux{run_, nullTimestamp(), nullTimestamp()};
196  auto rp = std::make_unique<art::RunPrincipal>(aux, pc_, nullptr);
197  return rp;
198  }
199 
200  std::unique_ptr<art::SubRunPrincipal>
202  {
203  if (subRun_.subRun() == throw_value('s')) {
204  throw art::Exception{
206  "There was an exception while reading a subrun from the input file."};
207  }
208 
209  art::SubRunAuxiliary const aux{subRun_, nullTimestamp(), nullTimestamp()};
210  auto srp = std::make_unique<art::SubRunPrincipal>(aux, pc_, nullptr);
211  srp->setRunPrincipal(rp);
212  return srp;
213  }
214 
215  std::unique_ptr<art::EventPrincipal>
217  {
218  if (event_.event() == throw_value('e')) {
219  throw art::Exception{
221  "There was an exception while reading an event from the input file."};
222  }
223 
224  art::EventAuxiliary const aux{event_, nullTimestamp(), true};
225  auto ep = std::make_unique<art::EventPrincipal>(aux, pc_, nullptr);
226  ep->setSubRunPrincipal(srp);
227  return ep;
228  }
229 
230  std::unique_ptr<art::RangeSetHandler>
232  {
233  return std::make_unique<art::OpenRangeSetHandler>(run_.run());
234  }
235 
236  std::unique_ptr<art::RangeSetHandler>
238  {
239  return std::make_unique<art::OpenRangeSetHandler>(subRun_.run());
240  }
241 
242  private:
244  std::ifstream inputFile_{};
246  std::vector<std::string> fileNames_{};
250  };
251 
252 } // namespace arttest
253 
static constexpr EventID flushEvent() noexcept
Definition: EventID.h:221
InputSource(ModuleDescription const &)
Definition: InputSource.cc:8
std::string string
Definition: nybbler.cc:12
std::unique_ptr< art::RunPrincipal > readRun() override
RunNumber_t run() const
Definition: RunID.h:64
std::unique_ptr< art::SubRunPrincipal > readSubRun(cet::exempt_ptr< art::RunPrincipal const > rp) override
std::unique_ptr< art::RangeSetHandler > subRunRangeSetHandler() override
std::unique_ptr< art::RangeSetHandler > runRangeSetHandler() override
const double e
RunNumber_t run() const
Definition: SubRunID.h:85
static constexpr RunID flushRun() noexcept
Definition: RunID.h:122
std::unique_ptr< art::EventPrincipal > readEvent(cet::exempt_ptr< art::SubRunPrincipal const > srp) override
EventProcessorTestSource(fhicl::ParameterSet const &ps, art::InputSourceDescription &isd)
static constexpr double ps
Definition: Units.h:99
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static constexpr SubRunID flushSubRun() noexcept
Definition: SubRunID.h:171
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:82
ModuleDescription const & moduleDescription
std::unique_ptr< art::FileBlock > readFile() override
EventNumber_t event() const
Definition: EventID.h:116
SubRunNumber_t subRun() const
Definition: SubRunID.h:91
static constexpr double sr
Definition: Units.h:166
#define DEFINE_ART_INPUT_SOURCE(klass)