1 #ifndef artdaq_ArtModules_detail_SharedMemoryReader_hh
2 #define artdaq_ArtModules_detail_SharedMemoryReader_hh
4 #include "artdaq/DAQdata/Globals.hh"
5 #include "art/Framework/Core/Frameworkfwd.h"
7 #include "art/Framework/Core/FileBlock.h"
8 #include "art/Framework/Core/ProductRegistryHelper.h"
9 #include "art/Framework/IO/Sources/SourceHelper.h"
10 #include "art/Framework/Principal/EventPrincipal.h"
11 #include "art/Framework/Principal/RunPrincipal.h"
12 #include "art/Framework/Principal/SubRunPrincipal.h"
13 #include "artdaq-core/Core/SharedMemoryManager.hh"
14 #include "artdaq-core/Utilities/TimeUtils.hh"
15 #include "fhiclcpp/ParameterSet.h"
16 #include "artdaq-core/Data/Fragment.hh"
17 #include "artdaq-core/Data/ContainerFragment.hh"
18 #include "artdaq-core/Core/SharedMemoryEventReceiver.hh"
19 #include "art/Framework/IO/Sources/put_product_in_principal.h"
20 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
26 #include "artdaq-core/Data/RawEvent.hh"
35 template<std::map<artdaq::Fragment::type_t, std::
string> getDefaultTypes() = artdaq::Fragment::MakeSystemTypeMap >
76 art::ProductRegistryHelper& help,
77 art::SourceHelper
const& pm)
95 incoming_events.reset(
new SharedMemoryEventReceiver(ps.get<uint32_t>(
"shared_memory_key", 0xBEE70000 + getppid()), ps.get<uint32_t>(
"broadcast_shared_memory_key", 0xCEE70000 + getppid())));
101 help.reconstitutes<Fragments, art::InEvent>(
pretend_module_name,
"Container" + it->second);
103 auto extraTypes = ps.get<std::vector<std::pair<Fragment::type_t, std::string>>>(
"fragment_type_map", std::vector<std::pair<Fragment::type_t, std::string>>());
104 for (
auto it = extraTypes.begin(); it != extraTypes.end(); ++it)
108 help.reconstitutes<Fragments, art::InEvent>(
pretend_module_name,
"Container" + it->second);
110 TLOG_INFO(
"SharedMemoryReader") <<
"SharedMemoryReader initialized with ParameterSet: " << ps.to_string() ;
126 art::ProductRegistryHelper& help,
127 art::SourceHelper
const& pm,
145 void readFile(std::string
const&, art::FileBlock*& fb)
147 TLOG_ARB(5,
"SharedMemoryReader") <<
"readFile enter/start";
148 fb =
new art::FileBlock(art::FileFormatVersion(1,
"RawEvent2011"),
"nothing");
168 art::SubRunPrincipal*
const & inSR,
169 art::RunPrincipal*& outR,
170 art::SubRunPrincipal*& outSR,
171 art::EventPrincipal*& outE)
173 TLOG_DEBUG(
"SharedMemoryReader") <<
"readNext BEGIN" ;
191 bool keep_looping =
true;
192 bool got_event =
false;
194 if (sleepTimeUsec > 100000) sleepTimeUsec = 100000;
197 keep_looping =
false;
198 auto start_time = std::chrono::steady_clock::now();
199 while (!got_event && TimeUtils::GetElapsedTime(start_time) <
waiting_time)
204 usleep(sleepTimeUsec);
210 TLOG_INFO(
"SharedMemoryReader")
211 <<
"InputFailure: Reading timed out in SharedMemoryReader::readNext()" ;
218 TLOG_INFO(
"SharedMemoryReader") <<
"Did not receive an event from Shared Memory, returning false" ;
222 TLOG_DEBUG(
"SharedMemoryReader") <<
"Got Event!" ;
224 auto errflag =
false;
226 if (errflag)
goto start;
228 if (errflag)
goto start;
229 if (fragmentTypes.size() == 0)
231 TLOG_ERROR(
"SharedMemoryReader") <<
"Event has no Fragments! Aborting!" ;
235 auto firstFragmentType = *fragmentTypes.begin();
236 TLOG_DEBUG(
"SharedMemoryReader") <<
"First Fragment type is " << std::to_string(firstFragmentType) <<
" (" <<
fragment_type_map_[firstFragmentType] <<
")" ;
243 if (firstFragmentType == Fragment::EndOfDataFragmentType)
245 TLOG_DEBUG(
"SharedMemoryReader") <<
"Received shutdown message, returning false" ;
256 art::Timestamp currentTime = time(0);
259 if (inR == 0 || inR->run() != evtHeader->run_id)
261 outR =
pmaker.makeRunPrincipal(evtHeader->run_id,
265 if (firstFragmentType == Fragment::EndOfRunFragmentType)
267 art::EventID
const evid(art::EventID::flushEvent());
268 outR =
pmaker.makeRunPrincipal(evid.runID(), currentTime);
269 outSR =
pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
270 outE =
pmaker.makeEventPrincipal(evid, currentTime);
274 else if (firstFragmentType == Fragment::EndOfSubrunFragmentType)
277 if (inR == 0 || inR->run() != evtHeader->run_id)
279 outSR =
pmaker.makeSubRunPrincipal(evtHeader->run_id,
280 evtHeader->subrun_id,
282 art::EventID
const evid(art::EventID::flushEvent(outSR->id()));
283 outE =
pmaker.makeEventPrincipal(evid, currentTime);
291 if (inSR != 0 && !inSR->id().isFlush() && inSR->subRun() == evtHeader->subrun_id)
293 art::EventID
const evid(art::EventID::flushEvent(inR->id()));
294 outSR =
pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
295 outE =
pmaker.makeEventPrincipal(evid, currentTime);
302 outSR =
pmaker.makeSubRunPrincipal(evtHeader->run_id,
303 evtHeader->subrun_id,
305 art::EventID
const evid(art::EventID::flushEvent(outSR->id()));
306 outE =
pmaker.makeEventPrincipal(evid, currentTime);
318 art::SubRunID subrun_check(evtHeader->run_id, evtHeader->subrun_id);
319 if (inSR == 0 || subrun_check != inSR->id())
321 outSR =
pmaker.makeSubRunPrincipal(evtHeader->run_id,
322 evtHeader->subrun_id,
325 outE =
pmaker.makeEventPrincipal(evtHeader->run_id,
326 evtHeader->subrun_id,
327 evtHeader->sequence_id,
331 std::map<Fragment::type_t, std::string>::const_iterator iter_end =
333 for (
auto& type_code : fragmentTypes)
335 std::map<Fragment::type_t, std::string>::const_iterator iter =
337 auto product =
incoming_events->GetFragmentsByType(errflag, type_code);
338 if (errflag)
goto start;
339 for (
auto &frag : *product)
341 if (iter != iter_end)
343 if (type_code == artdaq::Fragment::ContainerFragmentType)
345 std::unordered_map<std::string, std::unique_ptr<Fragments>> derived_fragments;
346 derived_fragments[iter->second] = std::make_unique<Fragments>();
348 for (
size_t ii = 0; ii < product->size(); ++ii)
350 ContainerFragment cf(product->at(ii));
352 if (contained_type != iter_end)
354 auto label = iter->second + contained_type->second;
355 if (!derived_fragments.count(label))
357 derived_fragments[label] = std::make_unique<Fragments>();
359 derived_fragments[label]->emplace_back(std::move(product->at(ii)));
363 derived_fragments[iter->second]->emplace_back(std::move(product->at(ii)));
367 for (
auto& type : derived_fragments)
369 put_product_in_principal(std::move(type.second),
378 put_product_in_principal(std::move(product),
386 put_product_in_principal(std::move(product),
390 TLOG_WARNING(
"SharedMemoryReader")
391 <<
"UnknownFragmentType: The product instance name mapping for fragment type \""
392 << ((int)type_code) <<
"\" is not known. Fragments of this "
393 <<
"type will be stored in the event with an instance name of \""
398 TLOG_ARB(10,
"SharedMemoryReader") <<
"readNext: bytesRead=" << std::to_string(
bytesRead) <<
" qsize=" << std::to_string(qsize) <<
" cap=" << std::to_string(
incoming_events->size()) <<
" metricMan=" << (
void*)metricMan ;
401 metricMan->sendMetric(
"bytesRead",
bytesRead,
"B", 5, MetricMode::Accumulate,
"",
true);
402 metricMan->sendMetric(
"queue%Used", static_cast<unsigned long int>(qsize * 100 /
incoming_events->size()),
"%", 5, MetricMode::LastPoint,
"",
true);
The SharedMemoryReader is a class which implements the methods needed by art::Source.
unsigned readNext_calls_
The number of times readNext has been called.
SharedMemoryReader(fhicl::ParameterSet const &ps, art::ProductRegistryHelper &help, art::SourceHelper const &pm)
SharedMemoryReader Constructor.
SharedMemoryReader(fhicl::ParameterSet const &ps, art::ProductRegistryHelper &help, art::SourceHelper const &pm, art::MasterProductRegistry &)
SharedMemoryReader Constructor.
virtual ~SharedMemoryReader()=default
SharedMemoryReader destructor.
art::SourceHelper const & pmaker
An art::SourceHelper instance.
SharedMemoryReader & operator=(SharedMemoryReader const &)=delete
Copy Assignment operator is deleted.
double waiting_time
The amount of time to wait for an event from the queue.
bool resume_after_timeout
Whether to resume if the dequeue action times out.
std::string unidentified_instance_name
The name to use for unknown Fragment types.
bool outputFileCloseNeeded
If an explicit output file close message is needed.
std::unique_ptr< SharedMemoryEventReceiver > incoming_events
The events from the EventStore.
size_t bytesRead
running total of number of bytes received
void closeCurrentFile()
Emulate closing a file. No-Op.
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.
std::map< Fragment::type_t, std::string > fragment_type_map_
The Fragment type names that this SharedMemoryReader knows about.
bool hasMoreData() const
Whether more data is expected from the SharedMemoryReader.
void readFile(std::string const &, art::FileBlock *&fb)
Emulate opening a file.
SharedMemoryReader(SharedMemoryReader const &)=delete
Copy Constructor is deleted.
bool shutdownMsgReceived
Whether a shutdown message has been received.