artdaq  v2_02_03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
RawEventQueueReader.cc
1 
2 #include "artdaq/DAQdata/Globals.hh"
3 #include "artdaq/ArtModules/detail/RawEventQueueReader.hh"
4 
5 #include "art/Framework/IO/Sources/put_product_in_principal.h"
6 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
7 #include "canvas/Utilities/Exception.h"
8 #include "artdaq-core/Data/Fragment.hh"
9 #include <sys/time.h>
10 
11 using std::string;
12 
14  art::ProductRegistryHelper& help,
15  art::SourceHelper const& pm) :
16  pmaker(pm)
17  , incoming_events(getGlobalQueue())
18  , waiting_time(ps.get<double>("waiting_time", 86400.0))
19  , resume_after_timeout(ps.get<bool>("resume_after_timeout", true))
20  , pretend_module_name(ps.get<std::string>("raw_data_label","daq"))
21  , unidentified_instance_name("unidentified")
22  , shutdownMsgReceived(false)
23  , outputFileCloseNeeded(false)
24  , fragment_type_map_(Fragment::MakeSystemTypeMap())
25  , readNext_calls_(0)
26 {
27  help.reconstitutes<Fragments, art::InEvent>(pretend_module_name,
29  for (auto it = fragment_type_map_.begin(); it != fragment_type_map_.end(); ++it)
30  {
31  help.reconstitutes<Fragments, art::InEvent>(pretend_module_name, it->second);
32  }
33 }
34 
36 
38  art::FileBlock*& fb)
39 {
40  fb = new art::FileBlock(art::FileFormatVersion(1, "RawEvent2011"), "nothing");
41 }
42 
43 bool artdaq::detail::RawEventQueueReader::readNext(art::RunPrincipal* const & inR,
44  art::SubRunPrincipal* const & inSR,
45  art::RunPrincipal*& outR,
46  art::SubRunPrincipal*& outSR,
47  art::EventPrincipal*& outE)
48 {
49  /*if (outputFileCloseNeeded) {
50  outputFileCloseNeeded = false;
51  return false;
52  }*/
53  if (readNext_calls_++ == 0)
54  {
55  incoming_events.setReaderIsReady();
56  TRACE(50, "RawEventQueueReader::readNext after incoming_events.setReaderIsReady()");
57  }
58  // Establish default 'results'
59  outR = 0;
60  outSR = 0;
61  outE = 0;
62  RawEvent_ptr popped_event;
63  // Try to get an event from the queue. We'll continuously loop, either until:
64  // 1) we have read a RawEvent off the queue, or
65  // 2) we have timed out, AND we are told the when we timeout we
66  // should stop.
67  // In any case, if we time out, we emit an informational message.
68  bool keep_looping = true;
69  bool got_event = false;
70  while (keep_looping)
71  {
72  keep_looping = false;
73  got_event = incoming_events.deqTimedWait(popped_event, waiting_time);
74  if (!got_event)
75  {
76  TLOG_INFO("RawEventQueueReader")
77  << "InputFailure: Reading timed out in RawEventQueueReader::readNext()" << TLOG_ENDL;
78  keep_looping = resume_after_timeout;
79  }
80  }
81  // We return false, indicating we're done reading, if:
82  // 1) we did not obtain an event, because we timed out and were
83  // configured NOT to keep trying after a timeout, or
84  // 2) the event we read was the end-of-data marker: a null
85  // pointer
86  if (!got_event || !popped_event)
87  {
88  TLOG_DEBUG("RawEventQueueReader") << "Received shutdown message, returning false" << TLOG_ENDL;
89  shutdownMsgReceived = true;
90  return false;
91  }
92 
93  // Check the number of fragments in the RawEvent. If we have a single
94  // fragment and that fragment is marked as EndRun or EndSubrun we'll create
95  // the special principals for that.
96  art::Timestamp currentTime = time(0);
97 
98  // make new run if inR is 0 or if the run has changed
99  if (inR == 0 || inR->run() != popped_event->runID())
100  {
101  outR = pmaker.makeRunPrincipal(popped_event->runID(),
102  currentTime);
103  }
104 
105  if (popped_event->numFragments() == 1)
106  {
107  if (popped_event->releaseProduct(Fragment::EndOfRunFragmentType)->size() == 1)
108  {
109  art::EventID const evid(art::EventID::flushEvent());
110  outR = pmaker.makeRunPrincipal(evid.runID(), currentTime);
111  outSR = pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
112  outE = pmaker.makeEventPrincipal(evid, currentTime);
113  return true;
114  }
115  else if (popped_event->releaseProduct(Fragment::EndOfSubrunFragmentType)->size() == 1)
116  {
117  // Check if inR == 0 or is a new run
118  if (inR == 0 || inR->run() != popped_event->runID())
119  {
120  outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
121  popped_event->subrunID(),
122  currentTime);
123 #ifdef ARTDAQ_ART_EVENTID_HAS_EXPLICIT_RUNID /* Old, error-prone interface. */
124  art::EventID const evid(art::EventID::flushEvent(outR->id(), outSR->id()));
125 #else
126  art::EventID const evid(art::EventID::flushEvent(outSR->id()));
127 #endif
128  outE = pmaker.makeEventPrincipal(evid, currentTime);
129  }
130  else
131  {
132  // If the previous subrun was neither 0 nor flush and was identical with the current
133  // subrun, then it must have been associated with a data event. In that case, we need
134  // to generate a flush event with a valid run but flush subrun and event number in order
135  // to end the subrun.
136  if (inSR != 0 && !inSR->id().isFlush() && inSR->subRun() == popped_event->subrunID())
137  {
138  art::EventID const evid(art::EventID::flushEvent(inR->id()));
139  outSR = pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
140  outE = pmaker.makeEventPrincipal(evid, currentTime);
141  // If this is either a new or another empty subrun, then generate a flush event with
142  // valid run and subrun numbers but flush event number
143  //} else if(inSR==0 || inSR->id().isFlush()){
144  }
145  else
146  {
147  outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
148  popped_event->subrunID(),
149  currentTime);
150 #ifdef ARTDAQ_ART_EVENTID_HAS_EXPLICIT_RUNID /* Old, error-prone interface. */
151  art::EventID const evid(art::EventID::flushEvent(inR->id(), outSR->id()));
152 #else
153  art::EventID const evid(art::EventID::flushEvent(outSR->id()));
154 #endif
155  outE = pmaker.makeEventPrincipal(evid, currentTime);
156  // Possible error condition
157  //} else {
158  }
159  outR = 0;
160  }
161  //outputFileCloseNeeded = true;
162  return true;
163  }
164  }
165 
166  // make new subrun if inSR is 0 or if the subrun has changed
167  art::SubRunID subrun_check(popped_event->runID(), popped_event->subrunID());
168  if (inSR == 0 || subrun_check != inSR->id())
169  {
170  outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
171  popped_event->subrunID(),
172  currentTime);
173  }
174  outE = pmaker.makeEventPrincipal(popped_event->runID(),
175  popped_event->subrunID(),
176  popped_event->sequenceID(),
177  currentTime);
178  // get the list of fragment types that exist in the event
179  std::vector<Fragment::type_t> type_list;
180  popped_event->fragmentTypes(type_list);
181  // insert the Fragments of each type into the EventPrincipal
182  std::map<Fragment::type_t, std::string>::const_iterator iter_end =
183  fragment_type_map_.end();
184  for (size_t idx = 0; idx < type_list.size(); ++idx)
185  {
186  std::map<Fragment::type_t, std::string>::const_iterator iter =
187  fragment_type_map_.find(type_list[idx]);
188  if (iter != iter_end)
189  {
190  put_product_in_principal(popped_event->releaseProduct(type_list[idx]),
191  *outE,
192  pretend_module_name,
193  iter->second);
194  }
195  else
196  {
197  put_product_in_principal(popped_event->releaseProduct(type_list[idx]),
198  *outE,
199  pretend_module_name,
200  unidentified_instance_name);
201  TLOG_WARNING("RawEventQueueReader")
202  << "UnknownFragmentType: The product instance name mapping for fragment type \""
203  << ((int)type_list[idx]) << "\" is not known. Fragments of this "
204  << "type will be stored in the event with an instance name of \""
205  << unidentified_instance_name << "\"." << TLOG_ENDL;
206  }
207  }
208 
209  return true;
210 }
std::string pretend_module_name
The module name to store data under.
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.
RawEventQueueReader(RawEventQueueReader const &)=delete
Copy Constructor is deleted.
std::string unidentified_instance_name
The name to use for unknown Fragment types.
void readFile(std::string const &, art::FileBlock *&fb)
Emulate opening a file.
void closeCurrentFile()
Emulate closing a file. No-Op.
std::map< Fragment::type_t, std::string > fragment_type_map_
The Fragment type names that this RawEventQueueReader knows about.