1 #ifndef ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQINPUTHELPER_HH_
2 #define ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQINPUTHELPER_HH_
4 #include "art/Framework/Core/FileBlock.h"
5 #include "art/Framework/Core/InputSourceMacros.h"
6 #include "art/Framework/Core/ProductRegistryHelper.h"
7 #include "art/Framework/IO/Sources/Source.h"
8 #include "art/Framework/IO/Sources/SourceHelper.h"
9 #include "art/Framework/IO/Sources/SourceTraits.h"
10 #include "art/Framework/IO/Sources/put_product_in_principal.h"
11 #include "art/Framework/Principal/EventPrincipal.h"
12 #include "art/Framework/Principal/RunPrincipal.h"
13 #include "art/Framework/Principal/SubRunPrincipal.h"
14 #include "art/Framework/Services/Registry/ServiceHandle.h"
16 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
17 #include "art_root_io/setup.h"
19 #include "canvas/Persistency/Common/EDProduct.h"
20 #include "canvas/Persistency/Common/Wrapper.h"
21 #include "canvas/Persistency/Provenance/BranchDescription.h"
22 #include "canvas/Persistency/Provenance/BranchKey.h"
23 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
24 #if ART_HEX_VERSION < 0x31100
25 #include "canvas/Persistency/Provenance/History.h"
27 #include "canvas/Persistency/Provenance/Compatibility/History.h"
29 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
30 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
31 #include "canvas/Persistency/Provenance/ProcessHistory.h"
32 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
33 #include "canvas/Persistency/Provenance/ProductList.h"
34 #include "canvas/Persistency/Provenance/ProductProvenance.h"
35 #include "canvas/Persistency/Provenance/ProductTables.h"
36 #include "canvas/Utilities/DebugMacros.h"
38 #include "artdaq-utilities/Plugins/MakeParameterSet.hh"
39 #include "fhiclcpp/ParameterSet.h"
40 #include "fhiclcpp/ParameterSetID.h"
41 #include "fhiclcpp/ParameterSetRegistry.h"
43 #include <TBufferFile.h>
46 #include <TStreamerInfo.h>
48 #include "artdaq-core/Data/ContainerFragment.hh"
49 #include "artdaq-core/Data/Fragment.hh"
50 #include "artdaq-core/Data/detail/ParentageMap.hh"
51 #include "artdaq-core/Utilities/ExceptionHandler.hh"
52 #include "artdaq-core/Utilities/TimeUtils.hh"
53 #include "artdaq/ArtModules/ArtdaqFragmentNamingService.h"
54 #include "artdaq/ArtModules/ArtdaqSharedMemoryService.h"
55 #include "artdaq/ArtModules/InputUtilities.hh"
56 #include "artdaq/DAQdata/Globals.hh"
57 #include "artdaq/DAQdata/NetMonHeader.hh"
69 #include <unordered_map>
118 ArtdaqInputHelper(
const fhicl::ParameterSet& ps, art::ProductRegistryHelper& helper, art::SourceHelper
const& pm);
129 void readFile(
const std::string&, art::FileBlock*& fb);
146 bool readNext(art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR, art::RunPrincipal*& outR,
147 art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE);
153 void readAndConstructPrincipal(std::unique_ptr<TBufferFile>&, ULong_t, art::RunPrincipal*
const,
154 art::SubRunPrincipal*
const, art::RunPrincipal*&, art::SubRunPrincipal*&,
155 art::EventPrincipal*&);
157 bool constructPrincipal(artdaq::Fragment::type_t, art::RunPrincipal*
const,
158 art::SubRunPrincipal*
const, art::RunPrincipal*&, art::SubRunPrincipal*&,
159 art::EventPrincipal*&);
162 void readDataProducts(std::list<std::unique_ptr<TBufferFile>>&, T*&);
164 void putInPrincipal(RunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
165 std::unique_ptr<const ProductProvenance>&&);
167 void putInPrincipal(SubRunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
168 std::unique_ptr<const ProductProvenance>&&);
170 void putInPrincipal(EventPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
171 std::unique_ptr<const ProductProvenance>&&);
173 void readFragments(std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>>
const& eventMap, art::EventPrincipal*& outE);
175 bool shutdownMsgReceived_;
176 bool outputFileCloseNeeded_;
177 art::SourceHelper
const& pm_;
178 U communicationWrapper_;
179 ProductList* productList_;
180 std::unique_ptr<art::History> history_to_use_;
181 bool fragmentsOnlyMode_;
182 std::string pretend_module_name;
184 std::chrono::steady_clock::time_point last_read_time;
189 art::SourceHelper
const& pm)
190 : shutdownMsgReceived_(false)
191 , outputFileCloseNeeded_(false)
193 , communicationWrapper_(ps)
195 , fragmentsOnlyMode_(false)
196 , pretend_module_name(ps.get<std::string>(
"raw_data_label",
"daq"))
198 , last_read_time(std::chrono::steady_clock::now())
202 art::ServiceHandle<ArtdaqSharedMemoryServiceInterface> shm;
205 volatile bool loop =
true;
218 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::ArtdaqInputHelper("
219 <<
"const fhicl::ParameterSet& ps, "
220 <<
"art::ProductRegistryHelper& helper, "
221 <<
"const art::SourceHelper& pm)";
223 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"Going to receive init message";
224 artdaq::FragmentPtrs initFrags = communicationWrapper_.receiveInitMessage();
225 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"Init message received";
227 if (!initFrags.empty() && initFrags.front().get()->type() == artdaq::Fragment::EndOfDataFragmentType)
229 TLOG_ERROR(
"ArtdaqInputHelper") <<
"Received EndOfData as first broadcast! This process neveer received any data!";
230 shutdownMsgReceived_ =
true;
231 outputFileCloseNeeded_ =
true;
235 if (initFrags.empty() || initFrags.back().get()->dataSize() == 0)
237 TLOG(TLVL_DEBUG + 32,
"ArtdaqInputHelper") <<
"No init message received or zero-size init message: Fragments-only mode activated! This is an EventBuilder!";
238 fragmentsOnlyMode_ =
true;
242 std::list<std::unique_ptr<TBufferFile>> msgs;
243 for (
auto& initFrag : initFrags)
246 msgs.emplace_back(
new TBufferFile(TBuffer::kRead, header->data_length, initFrag->dataBegin(), kFALSE,
nullptr));
249 std::set<art::ProcessHistoryID> history_ids;
251 for (
auto& msg : msgs)
255 msg->ReadULong(dummy);
258 auto list =
dynamic_cast<TList*
>(msg->ReadObject(TList::Class()));
262 TObjLink* lnk = list->FirstLink();
266 info =
dynamic_cast<TStreamerInfo*
>(lnk->GetObject());
267 TObject* element = info->GetElements()->UncheckedAt(0);
268 Bool_t isstl = element && strcmp(
"This", element->GetName()) == 0;
272 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: importing TStreamerInfo: " << info->GetName() <<
", version = " << info->GetClassVersion();
277 lnk = list->FirstLink();
280 info =
dynamic_cast<TStreamerInfo*
>(lnk->GetObject());
281 TObject* element = info->GetElements()->UncheckedAt(0);
282 Bool_t isstl = element && strcmp(
"This", element->GetName()) == 0;
286 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: importing TStreamerInfo: " << info->GetName() <<
", version = " << info->GetClassVersion();
296 msg->ReadULong(ps_cnt);
297 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: parameter set count: " << ps_cnt;
298 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: reading parameter sets ...";
299 for (ULong_t I = 0; I < ps_cnt; ++I)
301 std::string pset_str =
"";
302 msg->ReadStdString(pset_str);
304 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: parameter set: " << pset_str;
306 fhicl::ParameterSet pset;
307 pset = artdaq::make_pset(pset_str);
310 fhicl::ParameterSetRegistry::put(pset);
312 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: finished reading parameter sets.";
317 auto thisProductList = ReadObjectAny<art::ProductList>(
318 msg,
"std::map<art::BranchKey,art::BranchDescription>",
"ArtdaqInputHelper::ArtdaqInputHelper");
319 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Input Product list sz=" << thisProductList->size();
321 bool productListInitialized = productList_ !=
nullptr;
322 if (!productListInitialized) productList_ = thisProductList;
323 for (
auto I = thisProductList->begin(), E = thisProductList->end(); I != E; ++I)
326 TLOG(50,
"ArtdaqInputHelper") <<
"Branch key: class: '" << I->first.friendlyClassName_ <<
"' modlbl: '"
327 << I->first.moduleLabel_ <<
"' instnm: '" << I->first.productInstanceName_ <<
"' procnm: '"
328 << I->first.processName_ <<
"', branch description name: " << I->second.wrappedName()
329 <<
", TClass = " <<
static_cast<void*
>(TClass::GetClass(I->second.wrappedName().c_str()));
331 if (productListInitialized)
333 productList_->emplace(*I);
337 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Reading ProcessHistory";
338 auto phm = ReadObjectAny<art::ProcessHistoryMap>(
339 msg,
"std::map<const art::Hash<2>,art::ProcessHistory>",
"ArtdaqInputHelper::ArtdaqInputHelper");
342 for (
auto& proc_hist : *phm)
344 history_ids.insert(proc_hist.second.id());
347 ProcessHistoryRegistry::put(*phm);
348 printProcessMap(ProcessHistoryRegistry::get(),
"ArtdaqInputHelper's ProcessHistoryRegistry");
353 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Reading ParentageMap";
354 auto parentageMap = ReadObjectAny<ParentageMap>(msg,
"art::ParentageMap",
"ArtdaqInputHelper::ArtdaqInputHelper");
355 ParentageRegistry::put(*parentageMap);
359 art::ProcessHistory fake_process_history;
360 for (
auto& hist : history_ids)
364 TLOG(TLVL_WARNING,
"ArtdaqInputHelper") <<
"Encountered invalid history ID!";
368 ProcessHistory thisProcessHistory;
369 if (ProcessHistoryRegistry::get(hist, thisProcessHistory))
371 for (
auto& conf : thisProcessHistory)
373 if (
auto e = fake_process_history.end();
374 std::find(fake_process_history.begin(), e, conf) == e) {
375 fake_process_history.push_back(conf);
380 art::ProcessHistoryMap fake_process_history_map;
381 fake_process_history_map[fake_process_history.id()] = fake_process_history;
382 ProcessHistoryRegistry::put(fake_process_history_map);
383 printProcessMap(ProcessHistoryRegistry::get(),
"ArtdaqInputHelper's ProcessHistoryRegistry w/fake history");
385 history_to_use_.reset(
new History());
386 history_to_use_->setProcessHistoryID(fake_process_history.id());
388 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper")
389 <<
"ArtdaqInputHelper: Product list sz=" << productList_->size();
393 helper.productList(std::unique_ptr<art::ProductList>(productList_));
394 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: got product list";
397 helper.reconstitutes<artdaq::detail::RawEventHeader, art::InEvent>(pretend_module_name,
"RawEventHeader");
399 if (ps.get<
bool>(
"register_fragment_types",
true))
401 TLOG(TLVL_DEBUG + 32,
"ArtdaqInputHelper") <<
"Registering known Fragment labels from ArtdaqFragmentNamingServiceInterface";
403 art::ServiceHandle<ArtdaqFragmentNamingServiceInterface> translator;
404 helper.reconstitutes<artdaq::Fragments, art::InEvent>(pretend_module_name, translator->GetUnidentifiedInstanceName());
406 helper.reconstitutes<artdaq::Fragments, art::InRun>(pretend_module_name, translator->GetUnidentifiedInstanceName());
407 helper.reconstitutes<artdaq::Fragments, art::InSubRun>(pretend_module_name, translator->GetUnidentifiedInstanceName());
409 std::set<std::string> instance_names = translator->GetAllProductInstanceNames();
410 for (
const auto& set_iter : instance_names)
412 helper.reconstitutes<artdaq::Fragments, art::InEvent>(pretend_module_name, set_iter);
418 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::ArtdaqInputHelper("
419 <<
"const fhicl::ParameterSet& ps, "
420 <<
"art::ProductRegistryHelper& helper, "
421 <<
"const art::SourceHelper& pm)";
432 TLOG(TLVL_DEBUG + 34,
"ArtdaqInputHelper") <<
"Begin/End: ArtdaqInputHelper::closeCurrentFile()";
438 TLOG(TLVL_DEBUG + 35,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::"
439 "readFile(const std::string& name, art::FileBlock*& fb)";
440 fb =
new art::FileBlock(art::FileFormatVersion(1,
"ArtdaqInputHelper2013"),
"");
441 TLOG(TLVL_DEBUG + 35,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::"
442 "readFile(const std::string& name, art::FileBlock*& fb)";
448 TLOG(TLVL_DEBUG + 36,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::hasMoreData()";
449 if (shutdownMsgReceived_)
451 TLOG(TLVL_DEBUG + 36,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::hasMoreData(): "
452 "returning false on shutdownMsgReceived_.";
453 TLOG(TLVL_DEBUG + 36,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::hasMoreData()";
456 TLOG(TLVL_DEBUG + 32,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::hasMoreData(): "
457 "returning true on not shutdownMsgReceived_.";
458 TLOG(TLVL_DEBUG + 36,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::hasMoreData()";
464 art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR,
465 art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR,
466 art::EventPrincipal*& outE)
471 std::unique_ptr<art::RunAuxiliary> run_aux;
472 std::unique_ptr<art::SubRunAuxiliary> subrun_aux;
473 std::unique_ptr<art::EventAuxiliary> event_aux;
480 if (msg_type_code == 2)
483 TLOG(TLVL_DEBUG + 37,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
484 <<
"processing EndRun message ...";
486 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
489 TLOG(TLVL_DEBUG + 37,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
490 <<
"making flush RunPrincipal ...";
491 outR = pm_.makeRunPrincipal(RunID::flushRun(), run_aux->beginTime());
493 TLOG(TLVL_DEBUG + 37,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
494 <<
"making flush SubRunPrincipal ...";
495 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(), run_aux->beginTime());
497 TLOG(TLVL_DEBUG + 37,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
498 <<
"making flush EventPrincipal ...";
499 outE = pm_.makeEventPrincipal(EventID::flushEvent(), run_aux->endTime(),
true, EventAuxiliary::Any);
501 TLOG(TLVL_DEBUG + 37,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
502 <<
"finished processing EndRun message.";
504 else if (msg_type_code == 3)
507 TLOG(TLVL_DEBUG + 38,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
508 <<
"processing EndSubRun message ...";
511 ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
514 TLOG(TLVL_DEBUG + 38,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
515 <<
"making flush RunPrincipal ...";
516 outR = pm_.makeRunPrincipal(RunID::flushRun(), subrun_aux->beginTime());
533 #if ART_HEX_VERSION < 0x31100
535 art::Timestamp currentTime = time(
nullptr);
538 inR->endTime(currentTime);
542 inSR->endTime(currentTime);
546 TLOG(TLVL_DEBUG + 38,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
547 <<
"making flush SubRunPrincipal ...";
548 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(), subrun_aux->beginTime());
550 TLOG(TLVL_DEBUG + 38,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
551 <<
"making flush EventPrincipal ...";
552 outE = pm_.makeEventPrincipal(EventID::flushEvent(), subrun_aux->endTime(),
true, EventAuxiliary::Any);
554 TLOG(TLVL_DEBUG + 38,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
555 <<
"finished processing EndSubRun message.";
557 else if (msg_type_code == 4)
560 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
561 <<
"processing Event message ...";
563 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
567 ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
571 ReadObjectAny<art::EventAuxiliary>(msg,
"art::EventAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
573 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
574 <<
"inR: " <<
static_cast<void*
>(inR) <<
" run/expected "
575 << (inR ? std::to_string(inR->run()) :
"invalid") <<
"/" << event_aux->run();
576 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
577 <<
"inSR: " <<
static_cast<void*
>(inSR) <<
" run/expected "
578 << (inSR ? std::to_string(inSR->run()) :
"invalid") <<
"/" << event_aux->run()
579 <<
", subrun/expected " << (inSR ? std::to_string(inSR->subRun()) :
"invalid") <<
"/"
580 << event_aux->subRun();
581 if ((inR ==
nullptr) || !inR->runID().isValid() || (inR->run() != event_aux->run()))
585 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: making RunPrincipal ...";
586 outR = pm_.makeRunPrincipal(*run_aux);
588 art::SubRunID subrun_check(event_aux->run(), event_aux->subRun());
589 if (inSR ==
nullptr || subrun_check != inSR->subRunID())
593 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
594 <<
"making SubRunPrincipal ...";
595 outSR = pm_.makeSubRunPrincipal(*subrun_aux);
597 TLOG(TLVL_DEBUG + 34,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: making EventPrincipal ...";
598 #if ART_HEX_VERSION < 0x31100
599 auto historyPtr = std::unique_ptr<art::History>(
new History(*(history_to_use_.get())));
600 if (!art::ProcessHistoryRegistry::get().count(history_to_use_->processHistoryID()))
602 TLOG_WARNING(
"ArtdaqInputHelper") <<
"Stored history is not in ProcessHistoryRegistry, this event may have issues!";
604 outE = pm_.makeEventPrincipal(*event_aux, std::move(historyPtr));
606 if (!art::ProcessHistoryRegistry::get().count(history_to_use_->processHistoryID()))
608 TLOG_WARNING(
"ArtdaqInputHelper") <<
"Stored history is not in ProcessHistoryRegistry, this event may have issues!";
610 event_aux->setProcessHistoryID(history_to_use_->processHistoryID());
611 outE = pm_.makeEventPrincipal(*event_aux);
613 TLOG(TLVL_DEBUG + 39,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
614 <<
"finished processing Event message.";
619 bool art::ArtdaqInputHelper<U>::constructPrincipal(artdaq::Fragment::type_t firstFragmentType, art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR, art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE)
626 if (firstFragmentType == artdaq::Fragment::EndOfDataFragmentType)
628 TLOG(TLVL_DEBUG + 32,
"ArtdaqInputHelper") <<
"Received shutdown message, returning false";
629 shutdownMsgReceived_ =
true;
633 auto evtHeader = communicationWrapper_.getEventHeader();
636 TLOG_ERROR(
"ArtdaqInputHelper") <<
"No RawEventHeader received, cannot construct principals!";
637 shutdownMsgReceived_ =
true;
644 art::Timestamp currentTime = 0;
646 art::TimeValue_t lo_res_time = time(0);
647 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"lo_res_time = " << lo_res_time;
648 currentTime = ((lo_res_time & 0xffffffff) << 32);
650 timespec hi_res_time;
651 int retcode = clock_gettime(CLOCK_REALTIME, &hi_res_time);
652 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"hi_res_time tv_sec = " << hi_res_time.tv_sec
653 <<
" tv_nsec = " << hi_res_time.tv_nsec <<
" (retcode = " << retcode <<
")";
656 currentTime = ((hi_res_time.tv_sec & 0xffffffff) << 32) | (hi_res_time.tv_nsec & 0xffffffff);
660 TLOG_ERROR(
"ArtdaqInputHelper")
661 <<
"Unable to fetch a high-resolution time with clock_gettime for art::Event Timestamp. "
662 <<
"The art::Event Timestamp will be zero for event " << evtHeader->event_id;
666 if (inR ==
nullptr || inR->run() != evtHeader->run_id)
668 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Making run principal with run_id " << evtHeader->run_id;
669 outR = pm_.makeRunPrincipal(evtHeader->run_id, currentTime);
672 if (firstFragmentType == artdaq::Fragment::EndOfRunFragmentType)
674 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"EndOfRunFragment received, returning Flush event";
675 art::EventID
const evid(art::EventID::flushEvent());
676 outR = pm_.makeRunPrincipal(evid.runID(), currentTime);
677 outSR = pm_.makeSubRunPrincipal(evid.subRunID(), currentTime);
678 outE = pm_.makeEventPrincipal(evid, currentTime);
681 else if (firstFragmentType == artdaq::Fragment::EndOfSubrunFragmentType)
683 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"EndOfSubrunFragment received, creating new Subrun Principal";
685 if (inR ==
nullptr || inR->run() != evtHeader->run_id)
687 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
688 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
689 art::EventID
const evid(art::EventID::flushEvent(outSR->subRunID()));
690 outE = pm_.makeEventPrincipal(evid, currentTime);
698 if (inSR !=
nullptr && !inSR->subRunID().isFlush() && inSR->subRun() == evtHeader->subrun_id)
700 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Flushing old run id " << inR->runID();
701 art::EventID
const evid(art::EventID::flushEvent(inR->runID()));
702 outSR = pm_.makeSubRunPrincipal(evid.subRunID(), currentTime);
703 outE = pm_.makeEventPrincipal(evid, currentTime);
710 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
711 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
712 art::EventID
const evid(art::EventID::flushEvent(outSR->subRunID()));
713 outE = pm_.makeEventPrincipal(evid, currentTime);
724 art::SubRunID subrun_check(evtHeader->run_id, evtHeader->subrun_id);
725 if (inSR ==
nullptr || subrun_check != inSR->subRunID())
727 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
728 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
730 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Making event principal with event_id " << evtHeader->event_id;
731 outE = pm_.makeEventPrincipal(evtHeader->run_id, evtHeader->subrun_id, evtHeader->event_id, currentTime);
739 for (
auto& msg : msgs)
743 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: reading data product count ...";
744 msg->ReadULong(prd_cnt);
745 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: product count: " << prd_cnt;
750 for (ULong_t I = 0; I < prd_cnt; ++I)
752 std::unique_ptr<BranchKey> bk;
754 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: Reading branch key.";
755 bk.reset(ReadObjectAny<BranchKey>(msg,
"art::BranchKey",
"ArtdaqInputHelper::readDataProducts"));
759 TLOG(TLVL_DEBUG + 41,
"ArtdaqInputHelper") <<
"readDataProducts: got product class: '" << bk->friendlyClassName_ <<
"' modlbl: '"
760 << bk->moduleLabel_ <<
"' instnm: '" << bk->productInstanceName_ <<
"' procnm: '"
763 ProductList::const_iterator iter;
765 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: looking up product ...";
766 iter = productList_->find(*bk);
767 if (iter == productList_->end())
769 throw art::Exception(art::errors::ProductNotFound)
770 <<
"No product is registered for\n"
771 <<
" process name: '" << bk->processName_ <<
"'\n"
772 <<
" module label: '" << bk->moduleLabel_ <<
"'\n"
773 <<
" product friendly class name: '" << bk->friendlyClassName_ <<
"'\n"
774 <<
" product instance name: '" << bk->productInstanceName_ <<
"'\n";
779 const BranchDescription& bd = iter->second;
780 std::unique_ptr<EDProduct> prd;
782 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: Reading product with wrapped name: " << bd.wrappedName()
783 <<
", TClass = " <<
static_cast<void*
>(TClass::GetClass(bd.wrappedName().c_str()));
790 void* p = msg->ReadObjectAny(TClass::GetClass(bd.wrappedName().c_str()));
791 auto pp =
reinterpret_cast<EDProduct*
>(p);
793 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: After ReadObjectAny(prd): p=" << p <<
", EDProduct::isPresent: " << pp->isPresent();
797 std::unique_ptr<const ProductProvenance> prdprov;
799 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: Reading product provenance.";
800 prdprov.reset(ReadObjectAny<ProductProvenance>(msg,
"art::ProductProvenance",
"ArtdaqInputHelper::readDataProducts"));
804 TLOG(TLVL_DEBUG + 40,
"ArtdaqInputHelper") <<
"readDataProducts: inserting product: class: '" << bd.friendlyClassName()
805 <<
"' modlbl: '" << bd.moduleLabel() <<
"' instnm: '" << bd.productInstanceName()
806 <<
"' procnm: '" << bd.processName() <<
"' id: '" << bd.productID() <<
"'";
807 putInPrincipal(outPrincipal, std::move(prd), bd, std::move(prdprov));
815 const BranchDescription& bd,
816 std::unique_ptr<const ProductProvenance>&& prdprov)
818 rp->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::forRun(rp->runID())));
823 const BranchDescription& bd,
824 std::unique_ptr<const ProductProvenance>&& prdprov)
826 srp->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::forSubRun(srp->subRunID())));
831 const BranchDescription& bd,
832 std::unique_ptr<const ProductProvenance>&& prdprov)
834 TLOG(TLVL_DEBUG + 42,
"ArtdaqInputHelper") <<
"EventPrincipal size before put: " << ep->size();
836 ep->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::invalid()));
838 TLOG(TLVL_DEBUG + 42,
"ArtdaqInputHelper") <<
"EventPrincipal size after put: " << ep->size();
845 double fragmentLatency = 0;
846 double fragmentLatencyMax = 0.0;
847 size_t fragmentCount = 0;
849 art::ServiceHandle<ArtdaqFragmentNamingServiceInterface> translator;
852 for (
auto& fragmentTypePair : eventMap)
854 auto type_code = fragmentTypePair.first;
855 if (type_code == artdaq::Fragment::DataFragmentType || type_code == artdaq::Fragment::EndOfDataFragmentType || type_code == artdaq::Fragment::InitFragmentType || type_code == artdaq::Fragment::EndOfRunFragmentType || type_code == artdaq::Fragment::EndOfSubrunFragmentType || type_code == artdaq::Fragment::ShutdownFragmentType)
857 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"Skipping system Fragment with type " <<
static_cast<int>(type_code) <<
" ( " << translator->GetInstanceNameForType(type_code) <<
" )";
860 TLOG(TLVL_DEBUG + 33,
"ArtdaqInputHelper") <<
"type is " <<
static_cast<int>(type_code) <<
", number of fragments is " << fragmentTypePair.second->size();
862 std::unordered_map<std::string, std::unique_ptr<artdaq::Fragments>> derived_fragments;
863 for (
auto& frag : *fragmentTypePair.second)
865 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"Processing Fragment with ID " << frag.fragmentID();
866 bytesRead += frag.sizeBytes();
867 auto latency_s = frag.getLatency(
true);
868 double latency = latency_s.tv_sec + (latency_s.tv_nsec / 1000000000.0);
870 fragmentLatency += latency;
872 if (latency > fragmentLatencyMax) fragmentLatencyMax = latency;
874 std::pair<bool, std::string> instance_name_result =
875 translator->GetInstanceNameForFragment(frag);
876 std::string label = instance_name_result.second;
877 if (!instance_name_result.first)
879 TLOG_WARNING(
"ArtdaqInputHelper")
880 <<
"UnknownFragmentType: The product instance name mapping for fragment type \"" <<
static_cast<int>(type_code)
881 <<
"\" is not known. Fragments of this "
882 <<
"type will be stored in the event with an instance name of \"" << label <<
"\".";
884 if (!derived_fragments.count(label))
886 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"Creating output Fragment storage for label " << label;
887 derived_fragments[label] = std::make_unique<artdaq::Fragments>();
889 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"Adding Fragment " << frag.fragmentID() <<
" to storage with label " << label <<
" (sz=" << derived_fragments[label]->size() + 1 <<
")";
890 derived_fragments[label]->emplace_back(std::move(frag));
892 for (
auto& type : derived_fragments)
894 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"Adding " << type.second->size() <<
" Fragments with label " << type.first <<
" to event.";
895 put_product_in_principal(std::move(type.second), *outE, pretend_module_name, type.first);
900 metricMan->sendMetric(
"bytesRead", bytesRead,
"B", 3, artdaq::MetricMode::LastPoint);
902 metricMan->sendMetric(
"ArtdaqInputHelper Latency", fragmentLatency / fragmentCount,
"s", 4, artdaq::MetricMode::Average);
903 metricMan->sendMetric(
"ArtdaqInputHelper Maximum Latency", fragmentLatencyMax,
"s", 4, artdaq::MetricMode::Maximum);
909 art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE)
911 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::readNext";
914 if (outputFileCloseNeeded_)
916 outputFileCloseNeeded_ =
false;
919 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
920 <<
"returning false on outputFileCloseNeeded_";
921 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
924 auto read_start_time = std::chrono::steady_clock::now();
926 std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> eventMap = communicationWrapper_.receiveMessages();
927 auto got_event_time = std::chrono::steady_clock::now();
929 if (eventMap.empty())
931 TLOG(TLVL_ERROR,
"ArtdaqInputHelper") <<
"No Fragments received! Aborting...";
932 shutdownMsgReceived_ =
true;
933 TLOG(TLVL_DEBUG + 45,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
937 if (!fragmentsOnlyMode_ && !eventMap.count(artdaq::Fragment::DataFragmentType))
939 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext got a message without a DataFragment";
940 shutdownMsgReceived_ =
true;
941 TLOG(TLVL_DEBUG + 45,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
945 if (fragmentsOnlyMode_)
947 if (eventMap.count(artdaq::Fragment::DataFragmentType))
949 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext unexpectedly got a message with a DataFragment. This art Event will NOT be reconstructed!";
952 auto firstFragmentType = eventMap.begin()->first;
953 TLOG(TLVL_DEBUG + 32,
"ArtdaqInputHelper") <<
"First Fragment type is " <<
static_cast<int>(firstFragmentType);
954 if (constructPrincipal(firstFragmentType, inR, inSR, outR, outSR, outE))
956 readFragments(eventMap, outE);
966 std::list<std::unique_ptr<TBufferFile>> msgs;
967 for (
auto& dataFrag : *(eventMap[artdaq::Fragment::DataFragmentType]))
970 msgs.emplace_back(
new TBufferFile(TBuffer::kRead, header->data_length, dataFrag.dataBegin(), kFALSE,
nullptr));
976 ULong_t msg_type_code = 0;
977 ULong_t msg_type_code_tmp = 0;
978 for (
auto& msg : msgs)
980 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
981 <<
"getting message type code ...";
982 msg->ReadULong(msg_type_code_tmp);
983 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
984 <<
"message type: " << msg_type_code_tmp;
986 if (msg_type_code == 0)
987 msg_type_code = msg_type_code_tmp;
988 else if (msg_type_code != msg_type_code_tmp)
990 TLOG(TLVL_ERROR,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: Received conflicting message type codes! Aborting...";
992 shutdownMsgReceived_ =
true;
993 TLOG(TLVL_DEBUG + 45,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
997 if (msg_type_code == 5)
1000 shutdownMsgReceived_ =
true;
1001 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
1002 <<
"returning false on Shutdown message.";
1003 TLOG(TLVL_DEBUG + 44,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
1007 for (
auto& msg : msgs)
1009 readAndConstructPrincipal(msg, msg_type_code, inR, inSR, outR, outSR, outE);
1014 if (msg_type_code == 2)
1018 readDataProducts(msgs, outR);
1020 TLOG(TLVL_DEBUG + 45,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
1021 <<
"returning false on EndRun message.";
1022 TLOG(TLVL_DEBUG + 45,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
1025 else if (msg_type_code == 3)
1036 if (inR !=
nullptr && inSR !=
nullptr && outR !=
nullptr && outSR !=
nullptr)
1038 if (inR->runID().isFlush() && inSR->subRunID().isFlush() && outR->runID().isFlush() &&
1039 outSR->subRunID().isFlush())
1043 outputFileCloseNeeded_ =
true;
1048 readDataProducts(msgs, outSR);
1051 outputFileCloseNeeded_ =
true;
1052 TLOG(TLVL_DEBUG + 46,
"ArtdaqInputHelper") <<
"readNext: returning true on EndSubRun message.";
1055 else if (msg_type_code == 4)
1058 readDataProducts(msgs, outE);
1060 if (eventMap.size() > 1)
1062 readFragments(eventMap, outE);
1065 TLOG(TLVL_DEBUG + 47,
"ArtdaqInputHelper") <<
"readNext: returning true on Event message.";
1070 if (outE !=
nullptr)
1072 auto artHdrPtr = std::make_unique<artdaq::detail::RawEventHeader>();
1073 auto daqHdrPtr = communicationWrapper_.getEventHeader();
1075 if (daqHdrPtr !=
nullptr)
1077 memcpy(artHdrPtr.get(), daqHdrPtr.get(),
sizeof(artdaq::detail::RawEventHeader));
1078 put_product_in_principal(std::move(artHdrPtr), *outE, pretend_module_name,
"RawEventHeader");
1082 auto read_finish_time = std::chrono::steady_clock::now();
1083 TLOG(TLVL_DEBUG + 43,
"ArtdaqInputHelper") <<
"readNext: bytesRead=" << bytesRead
1084 <<
" metricMan=" <<
static_cast<void*
>(metricMan.get());
1087 metricMan->sendMetric(
"Avg Processing Time", artdaq::TimeUtils::GetElapsedTime(last_read_time, read_start_time),
1088 "s", 2, artdaq::MetricMode::Average);
1089 metricMan->sendMetric(
"Avg Input Wait Time", artdaq::TimeUtils::GetElapsedTime(read_start_time, got_event_time),
1090 "s", 3, artdaq::MetricMode::Average);
1091 metricMan->sendMetric(
"Avg Read Time", artdaq::TimeUtils::GetElapsedTime(got_event_time, read_finish_time),
"s",
1092 3, artdaq::MetricMode::Average);
1095 TLOG(TLVL_DEBUG + 48,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext ret=" << std::boolalpha << ret;
1096 last_read_time = std::chrono::steady_clock::now();
1100 #endif // ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQINPUTHELPER_HH_
void printProcessHistoryID(const std::string &label, const T &object)
Print the processHistoryID from the object.
void printProcessMap(const T &mappable, const std::string &description)
Print data from a map-like class.