artdaq  v2_03_02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
raw_event_queue_reader_t.cc
1 #include "artdaq/ArtModules/detail/RawEventQueueReader.hh"
2 
3 #include "art/Framework/Core/FileBlock.h"
4 //#include "art/Framework/Core/RootDictionaryManager.h"
5 #include "art/Framework/IO/Sources/SourceHelper.h"
6 #include "art/Framework/Principal/Event.h"
7 #include "art/Framework/Principal/EventPrincipal.h"
8 #include "art/Framework/Principal/Handle.h"
9 #include "art/Framework/Principal/RunPrincipal.h"
10 #include "art/Framework/Principal/SubRunPrincipal.h"
11 //#include "art/Persistency/Provenance/BranchIDListHelper.h"
12 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
13 #include "art/Persistency/Provenance/MasterProductRegistry.h"
14 #include "art/Persistency/Provenance/ProductMetaData.h"
15 #include "canvas/Persistency/Provenance/EventID.h"
16 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
17 #include "canvas/Persistency/Provenance/ModuleDescription.h"
18 #include "canvas/Persistency/Provenance/Parentage.h"
19 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
20 #include "canvas/Persistency/Provenance/RunID.h"
21 #include "canvas/Persistency/Provenance/SubRunID.h"
22 #include "canvas/Persistency/Provenance/Timestamp.h"
23 #include "canvas/Utilities/Exception.h"
24 #include "canvas/Utilities/GetPassID.h"
25 #include "art/Version/GetReleaseVersion.h"
26 #include "artdaq-core/Core/GlobalQueue.hh"
27 #include "artdaq-core/Data/Fragment.hh"
28 #include "fhiclcpp/make_ParameterSet.h"
29 
30 #define BOOST_TEST_MODULE ( raw_event_queue_reader_t )
31 #include <boost/test/auto_unit_test.hpp>
32 
33 #include <iostream>
34 #include <memory>
35 #include <string>
36 
41 {
42 public:
47 
51  typedef std::map<std::string, art::BranchKey> BKmap_t;
52 
54  std::map<std::string, std::unique_ptr<art::ProcessConfiguration>> processConfigurations_;
55 
65  art::ProcessConfiguration*
66  fake_single_module_process(std::string const& tag,
67  std::string const& processName,
68  fhicl::ParameterSet const& moduleParams,
69  std::string const& release = art::getReleaseVersion(),
70  std::string const& pass = art::getPassID());
71 
79  std::unique_ptr<art::BranchDescription>
80  fake_single_process_branch(std::string const& tag,
81  std::string const& processName,
82  std::string const& productInstanceName = std::string());
83 
87  void finalize();
88 
89  art::MasterProductRegistry productRegistry_;
90  //art::RootDictionaryManager rdm_;
91 };
92 
94  :
95  branchKeys_()
96  , processConfigurations_()
97  , productRegistry_()//,
98 // rdm_()
99 {
100  // We can only insert products registered in the MasterProductRegistry.
101  productRegistry_.addProduct(fake_single_process_branch("hlt", "HLT"));
102  productRegistry_.addProduct(fake_single_process_branch("prod", "PROD"));
103  productRegistry_.addProduct(fake_single_process_branch("test", "TEST"));
104  productRegistry_.addProduct(fake_single_process_branch("user", "USER"));
105  productRegistry_.addProduct(fake_single_process_branch("rick", "USER2", "rick"));
106 }
107 
108 void
110 {
111  productRegistry_.setFrozen();
112 #if ART_HEX_VERSION >= 0x20703
113  art::BranchIDListRegistry::updateFromProductRegistry(productRegistry_);
114 #else
115  art::BranchIDListHelper::updateRegistries(productRegistry_);
116 #endif
117  art::ProductMetaData::create_instance(productRegistry_);
118 }
119 
120 art::ProcessConfiguration*
122 fake_single_module_process(std::string const& tag,
123  std::string const& processName,
124  fhicl::ParameterSet const& moduleParams,
125  std::string const& release,
126  std::string const& pass)
127 {
128  fhicl::ParameterSet processParams;
129  processParams.put(processName, moduleParams);
130  processParams.put<std::string>("process_name",
131  processName);
132  auto emplace_pair =
133  processConfigurations_.emplace(tag,
134  std::make_unique<art::ProcessConfiguration>(processName, processParams.id(), release, pass));
135  return emplace_pair.first->second.get();
136 }
137 
138 std::unique_ptr<art::BranchDescription>
140 fake_single_process_branch(std::string const& tag,
141  std::string const& processName,
142  std::string const& productInstanceName)
143 {
144  std::string moduleLabel = processName + "dummyMod";
145  std::string moduleClass("DummyModule");
146  fhicl::ParameterSet modParams;
147  modParams.put<std::string>("module_type", moduleClass);
148  modParams.put<std::string>("module_label", moduleLabel);
149  art::ProcessConfiguration* process =
150  fake_single_module_process(tag, processName, modParams);
151  art::ModuleDescription mod(modParams.id(),
152  moduleClass,
153  moduleLabel,
154  *process);
155  art::TypeID dummyType(typeid(int));
156  art::BranchDescription* result =
157  new art::BranchDescription(
158 # if ART_HEX_VERSION >= 0x20703
159  art::InEvent,
160  art::TypeLabel(dummyType,
161  productInstanceName),
162 # else
163  art::TypeLabel(art::InEvent,
164  dummyType,
165  productInstanceName),
166 # endif
167  mod);
168 
169 
170  branchKeys_.insert(std::make_pair(tag, art::BranchKey(*result)));
171  return std::unique_ptr<art::BranchDescription>(result);
172 }
173 
178 {
183  {
184  static bool once(true);
185  if (once)
186  {
187  (void)reader(); // Force initialization.
188  art::ModuleDescription md(fhicl::ParameterSet().id(),
189  "_NAMEERROR_",
190  "_LABELERROR_",
191  *gf().processConfigurations_["daq"]);
192  // These _xERROR_ strings should never appear in branch names; they
193  // are here as tracers to help identify any failures in coding.
194  helper().registerProducts(gf().productRegistry_, md);
195  gf().finalize();
196  once = false;
197  }
198  }
199 
205  {
206  static MPRGlobalTestFixture mpr;
207  return mpr;
208  }
209 
214  art::ProductRegistryHelper& helper()
215  {
216  static art::ProductRegistryHelper s_helper;
217  return s_helper;
218  }
219 
224  art::SourceHelper& source_helper()
225  {
226  static std::unique_ptr<art::SourceHelper>
227  s_source_helper;
228  if (!s_source_helper)
229  {
230  fhicl::ParameterSet sourceParams;
231  std::string moduleType{ "DummySource" };
232  std::string moduleLabel{ "daq" };
233  sourceParams.put<std::string>("module_type", moduleType);
234  sourceParams.put<std::string>("module_label", moduleLabel);
235  auto pc_ptr = gf().fake_single_module_process(moduleLabel,
236  "TEST",
237  sourceParams);
238  art::ModuleDescription md(sourceParams.id(),
239  moduleType,
240  moduleLabel,
241  *pc_ptr);
242  s_source_helper = std::make_unique<art::SourceHelper>(md);
243  }
244  return *s_source_helper;
245  }
246 
252  {
253  fhicl::ParameterSet pset;
255  s_reader(pset,
256  helper(),
257  source_helper(),
258  gf().productRegistry_);
259  static bool reader_initialized = false;
260  if (!reader_initialized)
261  {
262  s_reader.fragment_type_map_[1] = "ABCDEF";
263  helper().reconstitutes<artdaq::Fragments, art::InEvent>("daq", "ABCDEF");
264  reader_initialized = true;
265  }
266  return s_reader;
267  }
268 };
269 
270 BOOST_FIXTURE_TEST_SUITE(raw_event_queue_reader_t, REQRTestFixture)
271 
272 namespace
273 {
282  std::unique_ptr<art::RunPrincipal>&& run,
283  std::unique_ptr<art::SubRunPrincipal>&& subrun,
284  art::EventID const& eventid)
285  {
286  BOOST_REQUIRE(run || subrun == nullptr); // Sanity check.
287  std::shared_ptr<artdaq::RawEvent> event(new artdaq::RawEvent(eventid.run(), eventid.subRun(), eventid.event()));
288  std::vector<artdaq::Fragment::value_type> fakeData{ 1, 2, 3, 4 };
289  artdaq::FragmentPtr
290  tmpFrag(artdaq::Fragment::dataFrag(eventid.event(),
291  0,
292  fakeData.begin(),
293  fakeData.end()));
294  tmpFrag->setUserType(1);
295  event->insertFragment(std::move(tmpFrag));
296  event->markComplete();
297  artdaq::getGlobalQueue().enqNowait(event);
298  art::EventPrincipal* newevent = nullptr;
299  art::SubRunPrincipal* newsubrun = nullptr;
300  art::RunPrincipal* newrun = nullptr;
301  bool rc = reader.readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
302  BOOST_REQUIRE(rc);
303  if (run.get() && run->run() == eventid.run())
304  {
305  BOOST_CHECK(newrun == nullptr);
306  }
307  else
308  {
309  BOOST_CHECK(newrun);
310  BOOST_CHECK(newrun->id() == eventid.runID());
311  }
312  if (!newrun && subrun.get() && subrun->subRun() == eventid.subRun())
313  {
314  BOOST_CHECK(newsubrun == nullptr);
315  }
316  else
317  {
318  BOOST_CHECK(newsubrun);
319  BOOST_CHECK(newsubrun->id() == eventid.subRunID());
320  }
321  BOOST_CHECK(newevent);
322  BOOST_CHECK(newevent->id() == eventid);
323  art::Event e(*newevent, art::ModuleDescription());
324  art::Handle<std::vector<artdaq::Fragment>> h;
325  e.getByLabel("daq", "ABCDEF", h);
326  BOOST_CHECK(h.isValid());
327  BOOST_CHECK(h->size() == 1);
328  BOOST_CHECK(std::equal(fakeData.begin(),
329  fakeData.end(),
330  h->front().dataBegin()));
331  delete(newrun);
332  delete(newsubrun);
333  delete(newevent);
334  }
335 }
336 
337 BOOST_AUTO_TEST_CASE(nonempty_event)
338 {
339  art::EventID eventid(2112, 1, 3);
340  art::Timestamp now;
341  basic_test(reader(),
342  std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
343  std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), eventid.subRun(), now)),
344  eventid);
345 }
346 
347 BOOST_AUTO_TEST_CASE(first_event)
348 {
349  art::EventID eventid(2112, 1, 3);
350  art::Timestamp now;
351  basic_test(reader(),
352  nullptr,
353  nullptr,
354  eventid);
355 }
356 
357 BOOST_AUTO_TEST_CASE(new_subrun)
358 {
359  art::EventID eventid(2112, 1, 3);
360  art::Timestamp now;
361  basic_test(reader(),
362  std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
363  std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), 0, now)),
364  eventid);
365 }
366 
367 BOOST_AUTO_TEST_CASE(new_run)
368 {
369  art::EventID eventid(2112, 1, 3);
370  art::Timestamp now;
371  basic_test(reader(),
372  std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run() - 1, now)),
373  std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run() - 1,
374  eventid.subRun(),
375  now)),
376  eventid);
377 }
378 
379 BOOST_AUTO_TEST_CASE(end_of_data)
380 {
381  // Tell 'reader' the name of the file we are to read. This is pretty
382  // much irrelevant for RawEventQueueReader, but we'll stick to the
383  // interface demanded by Source<T>...
384  std::string const fakeFileName("no such file exists");
385  art::FileBlock* pFile = nullptr;
386  reader().readFile(fakeFileName, pFile);
387  BOOST_CHECK(pFile);
388  BOOST_CHECK(pFile->fileFormatVersion() == art::FileFormatVersion(1, "RawEvent2011"));
389  BOOST_CHECK(pFile->tree() == nullptr);
390 
391  BOOST_CHECK(!pFile->fastClonable());
392  // Test the end-of-data handling. Reading an end-of-data should result in readNext() returning false,
393  // and should return null pointers for new-run, -subrun and -event.
394  // Prepare our 'previous run/subrun/event'..
395  art::RunID runid(2112);
396  art::SubRunID subrunid(2112, 1);
397  art::EventID eventid(2112, 1, 3);
398  art::Timestamp now;
399  std::unique_ptr<art::RunPrincipal> run(source_helper().makeRunPrincipal(runid.run(), now));
400  std::unique_ptr<art::SubRunPrincipal> subrun(source_helper().makeSubRunPrincipal(runid.run(), subrunid.subRun(), now));
401  std::unique_ptr<art::EventPrincipal> event(source_helper().makeEventPrincipal(runid.run(),
402  subrunid.subRun(),
403  eventid.event(),
404  now));
405  artdaq::getGlobalQueue().enqNowait(std::shared_ptr<artdaq::RawEvent>(nullptr)); // insert end-of-data marker
406  art::EventPrincipal* newevent = nullptr;
407  art::SubRunPrincipal* newsubrun = nullptr;
408  art::RunPrincipal* newrun = nullptr;
409  bool rc = reader().readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
410  BOOST_CHECK(!rc);
411  BOOST_CHECK(newrun == nullptr);
412  BOOST_CHECK(newsubrun == nullptr);
413  BOOST_CHECK(newevent == nullptr);
414 }
415 
416 BOOST_AUTO_TEST_SUITE_END()
bool readNext(art::RunPrincipal *const &inR, art::SubRunPrincipal *const &inSR, art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
Dequeue a RawEvent and declare its Fragment contents to art, creating Run, SubRun, and EventPrincipal objects as necessary.
std::map< std::string, std::unique_ptr< art::ProcessConfiguration > > processConfigurations_
Configurations.
art::ProductRegistryHelper & helper()
Get an art::ProductRegistryHelper, creating a static instance if necessary.
void finalize()
Finalizes the ProductRegistry.
The RawEventQueueReader is a class which implements the methods needed by art::Source.
art::MasterProductRegistry productRegistry_
MasterProductRegistry instance.
void basic_test(artdaq::detail::RawEventQueueReader &reader, std::unique_ptr< art::RunPrincipal > &&run, std::unique_ptr< art::SubRunPrincipal > &&subrun, art::EventID const &eventid)
Run a basic checkout of the RawEventQueueReader.
art::ProcessConfiguration * fake_single_module_process(std::string const &tag, std::string const &processName, fhicl::ParameterSet const &moduleParams, std::string const &release=art::getReleaseVersion(), std::string const &pass=art::getPassID())
Create the ProcessConfiguration for a single module art process.
std::unique_ptr< art::BranchDescription > fake_single_process_branch(std::string const &tag, std::string const &processName, std::string const &productInstanceName=std::string())
Create a BranchDescription for a process.
MasterProductRegistry Test Fixture.
RawEventQueueReader Test Fixture.
REQRTestFixture()
REQRTestFixture Constructor.
std::map< std::string, art::BranchKey > BKmap_t
BKmap_t associates a string with a art::BranchKey.
MPRGlobalTestFixture()
MPRGlobalTestFixture Constructor.
art::SourceHelper & source_helper()
Get an art::SourceHelper object, creating a static instance if necessary.
std::map< Fragment::type_t, std::string > fragment_type_map_
The Fragment type names that this RawEventQueueReader knows about.
artdaq::detail::RawEventQueueReader & reader()
Get an artdaq::detail::RawEventQueueReader object, creating a static instance if necessary.
MPRGlobalTestFixture & gf()
Get a MPRGlobalTestFixture, creating a static instance if necessary.
BKmap_t branchKeys_
Keys in this test fixture.