1 #include "art/Framework/Core/Frameworkfwd.h"
3 #include "art/Framework/Core/FileBlock.h"
4 #include "art/Framework/Core/InputSourceMacros.h"
5 #include "art/Framework/Core/ProductRegistryHelper.h"
6 #include "art/Framework/IO/Sources/Source.h"
7 #include "art/Framework/IO/Sources/SourceHelper.h"
8 #include "art/Framework/IO/Sources/SourceTraits.h"
9 #include "art/Framework/IO/Sources/put_product_in_principal.h"
10 #include "art/Framework/Principal/EventPrincipal.h"
11 #include "art/Framework/Principal/RunPrincipal.h"
12 #include "art/Framework/Principal/SubRunPrincipal.h"
13 #include "art/Framework/Services/Registry/ServiceHandle.h"
15 #if ART_HEX_VERSION < 0x30000
16 #include "art/Persistency/Provenance/MasterProductRegistry.h"
17 #include "art/Persistency/Provenance/ProductMetaData.h"
19 #if ART_HEX_VERSION >= 0x30200
20 #include "art_root_io/setup.h"
22 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
24 #include "canvas/Persistency/Common/EDProduct.h"
25 #include "canvas/Persistency/Common/Wrapper.h"
26 #include "canvas/Persistency/Provenance/BranchDescription.h"
27 #include "canvas/Persistency/Provenance/BranchKey.h"
28 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
29 #include "canvas/Persistency/Provenance/History.h"
30 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
31 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
32 #include "canvas/Persistency/Provenance/ProcessHistory.h"
33 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
34 #include "canvas/Persistency/Provenance/ProductList.h"
35 #include "canvas/Persistency/Provenance/ProductProvenance.h"
36 #include "canvas/Persistency/Provenance/ProductTables.h"
37 #include "canvas/Utilities/DebugMacros.h"
39 #include "fhiclcpp/ParameterSet.h"
40 #include "fhiclcpp/ParameterSetID.h"
41 #include "fhiclcpp/ParameterSetRegistry.h"
42 #include "fhiclcpp/make_ParameterSet.h"
44 #include <TBufferFile.h>
47 #include <TStreamerInfo.h>
49 #include "artdaq-core/Data/ContainerFragment.hh"
50 #include "artdaq-core/Data/Fragment.hh"
51 #include "artdaq-core/Data/detail/ParentageMap.hh"
52 #include "artdaq-core/Utilities/ExceptionHandler.hh"
53 #include "artdaq-core/Utilities/TimeUtils.hh"
54 #include "artdaq/ArtModules/ArtdaqFragmentNamingService.h"
55 #include "artdaq/ArtModules/ArtdaqSharedMemoryService.h"
56 #include "artdaq/ArtModules/InputUtilities.hh"
57 #include "artdaq/DAQdata/Globals.hh"
58 #include "artdaq/DAQdata/NetMonHeader.hh"
70 #if ART_HEX_VERSION < 0x30000
74 #define HISTORY_PTR_T std::shared_ptr<art::History>
76 #define EVENT_ID eventID
77 #define SUBRUN_ID subRunID
79 #define HISTORY_PTR_T std::unique_ptr<art::History>
127 ArtdaqInputHelper(
const fhicl::ParameterSet& ps, art::ProductRegistryHelper& helper, art::SourceHelper
const& pm);
138 void readFile(
const std::string&, art::FileBlock*& fb);
155 bool readNext(art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR, art::RunPrincipal*& outR,
156 art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE);
159 void readAndConstructPrincipal(std::unique_ptr<TBufferFile>&,
unsigned long, art::RunPrincipal*
const,
160 art::SubRunPrincipal*
const, art::RunPrincipal*&, art::SubRunPrincipal*&,
161 art::EventPrincipal*&);
163 bool constructPrincipal(artdaq::Fragment::type_t, art::RunPrincipal*
const,
164 art::SubRunPrincipal*
const, art::RunPrincipal*&, art::SubRunPrincipal*&,
165 art::EventPrincipal*&);
168 void readDataProducts(std::list<std::unique_ptr<TBufferFile>>&, T*&);
170 void putInPrincipal(RunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
171 std::unique_ptr<const ProductProvenance>&&);
173 void putInPrincipal(SubRunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
174 std::unique_ptr<const ProductProvenance>&&);
176 void putInPrincipal(EventPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&,
177 std::unique_ptr<const ProductProvenance>&&);
179 void readFragments(std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>>
const& eventMap, art::EventPrincipal*& outE);
182 bool shutdownMsgReceived_;
183 bool outputFileCloseNeeded_;
184 art::SourceHelper
const& pm_;
185 U communicationWrapper_;
186 ProductList* productList_;
187 HISTORY_PTR_T history_to_use_;
188 bool fragmentsOnlyMode_;
189 std::string pretend_module_name;
191 std::chrono::steady_clock::time_point last_read_time;
196 art::SourceHelper
const& pm)
197 : shutdownMsgReceived_(false)
198 , outputFileCloseNeeded_(false)
200 , communicationWrapper_(ps)
202 , fragmentsOnlyMode_(false)
203 , pretend_module_name(ps.get<std::string>(
"raw_data_label",
"daq"))
205 , last_read_time(std::chrono::steady_clock::now())
207 #if ART_HEX_VERSION >= 0x30200
211 art::ServiceHandle<ArtdaqSharedMemoryServiceInterface> shm;
214 volatile bool loop =
true;
227 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::ArtdaqInputHelper("
228 <<
"const fhicl::ParameterSet& ps, "
229 <<
"art::ProductRegistryHelper& helper, "
230 <<
"const art::SourceHelper& pm)";
232 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"Going to receive init message";
233 artdaq::FragmentPtrs initFrags = communicationWrapper_.receiveInitMessage();
234 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"Init message received";
236 if (initFrags.size() == 0 || initFrags.back().get()->dataSize() == 0)
238 TLOG_DEBUG(
"ArtdaqInputHelper") <<
"No init message received or zero-size init message: Fragments-only mode activated! This is an EventBuilder!";
239 fragmentsOnlyMode_ =
true;
243 std::list<std::unique_ptr<TBufferFile>> msgs;
244 for (
auto& initFrag : initFrags)
247 msgs.emplace_back(
new TBufferFile(TBuffer::kRead, header->data_length, initFrag->dataBegin(), kFALSE, 0));
250 std::list<History*> processHistories;
252 for (
auto& msg : msgs)
255 unsigned long dummy = 0;
256 msg->ReadULong(dummy);
259 TList* list = (TList*)msg->ReadObject(TList::Class());
263 TObjLink* lnk = list->FirstLink();
267 info = (TStreamerInfo*)lnk->GetObject();
268 TObject* element = info->GetElements()->UncheckedAt(0);
269 Bool_t isstl = element && strcmp(
"This", element->GetName()) == 0;
273 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: importing TStreamerInfo: " << info->GetName() <<
", version = " << info->GetClassVersion();
278 lnk = list->FirstLink();
281 info = (TStreamerInfo*)lnk->GetObject();
282 TObject* element = info->GetElements()->UncheckedAt(0);
283 Bool_t isstl = element && strcmp(
"This", element->GetName()) == 0;
287 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: importing TStreamerInfo: " << info->GetName() <<
", version = " << info->GetClassVersion();
296 unsigned long ps_cnt = 0;
297 msg->ReadULong(ps_cnt);
298 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: parameter set count: " << ps_cnt;
299 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: reading parameter sets ...";
300 for (
unsigned long I = 0; I < ps_cnt; ++I)
302 std::string pset_str =
"";
303 msg->ReadStdString(pset_str);
305 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: parameter set: " << pset_str;
307 fhicl::ParameterSet pset;
308 fhicl::make_ParameterSet(pset_str, pset);
311 fhicl::ParameterSetRegistry::put(pset);
313 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: finished reading parameter sets.";
318 auto thisProductList = ReadObjectAny<art::ProductList>(
319 msg,
"std::map<art::BranchKey,art::BranchDescription>",
"ArtdaqInputHelper::ArtdaqInputHelper");
320 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Input Product list sz=" << thisProductList->size();
322 bool productListInitialized = productList_ !=
nullptr;
323 if (!productListInitialized) productList_ = thisProductList;
324 for (
auto I = thisProductList->begin(), E = thisProductList->end(); I != E; ++I)
327 TLOG_ARB(50,
"ArtdaqInputHelper") <<
"Branch key: class: '" << I->first.friendlyClassName_ <<
"' modlbl: '"
328 << I->first.moduleLabel_ <<
"' instnm: '" << I->first.productInstanceName_ <<
"' procnm: '"
329 << I->first.processName_ <<
"', branch description name: " << I->second.wrappedName()
330 <<
", TClass = " << (
void*)TClass::GetClass(I->second.wrappedName().c_str());
332 if (productListInitialized)
334 productList_->emplace(*I);
338 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Reading ProcessHistory";
339 art::ProcessHistoryMap* phm = ReadObjectAny<art::ProcessHistoryMap>(
340 msg,
"std::map<const art::Hash<2>,art::ProcessHistory>",
"ArtdaqInputHelper::ArtdaqInputHelper");
343 ProcessHistoryRegistry::put(*phm);
344 printProcessMap(ProcessHistoryRegistry::get(),
"ArtdaqInputHelper's ProcessHistoryRegistry");
349 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Reading ParentageMap";
350 ParentageMap* parentageMap = ReadObjectAny<ParentageMap>(msg,
"art::ParentageMap",
"ArtdaqInputHelper::ArtdaqInputHelper");
351 ParentageRegistry::put(*parentageMap);
356 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: Reading History";
357 processHistories.push_back(ReadObjectAny<History>(msg,
"art::History",
"ArtdaqInputHelper::ArtdaqInputHelper"));
361 art::ProcessHistory fake_process_history;
362 for (
auto& hist : processHistories)
364 auto id = hist->processHistoryID();
365 ProcessHistory thisProcessHistory;
366 if (ProcessHistoryRegistry::get(
id, thisProcessHistory))
368 for (
auto& conf : thisProcessHistory)
369 fake_process_history.push_back(conf);
372 art::ProcessHistoryMap fake_process_history_map;
373 fake_process_history_map[fake_process_history.id()] = fake_process_history;
374 ProcessHistoryRegistry::put(fake_process_history_map);
375 history_to_use_.reset(
new History());
376 history_to_use_->setProcessHistoryID(fake_process_history.id());
377 for (
auto& hist : processHistories)
379 for (
auto& es : hist->eventSelectionIDs())
381 history_to_use_->addEventSelectionEntry(es);
385 TLOG_ARB(5,
"ArtdaqInputHelper")
386 <<
"ArtdaqInputHelper: Product list sz=" << productList_->size();
389 #if ART_HEX_VERSION < 0x30000
390 helper.productList(productList_);
392 helper.productList(std::unique_ptr<art::ProductList>(productList_));
394 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper: got product list";
397 if (ps.get<
bool>(
"register_fragment_types",
true))
399 TLOG_DEBUG(
"ArtdaqInputHelper") <<
"Registering known Fragment labels from ArtdaqFragmentNamingServiceInterface";
400 art::ServiceHandle<ArtdaqFragmentNamingServiceInterface> translator;
401 helper.reconstitutes<artdaq::Fragments, art::InEvent>(pretend_module_name, translator->GetUnidentifiedInstanceName());
403 helper.reconstitutes<artdaq::Fragments, art::InRun>(pretend_module_name, translator->GetUnidentifiedInstanceName());
404 helper.reconstitutes<artdaq::Fragments, art::InSubRun>(pretend_module_name, translator->GetUnidentifiedInstanceName());
406 std::set<std::string> instance_names = translator->GetAllProductInstanceNames();
407 for (
const auto& set_iter : instance_names)
409 helper.reconstitutes<artdaq::Fragments, art::InEvent>(pretend_module_name, set_iter);
415 TLOG_ARB(5,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::ArtdaqInputHelper("
416 <<
"const fhicl::ParameterSet& ps, "
417 <<
"art::ProductRegistryHelper& helper, "
418 <<
"const art::SourceHelper& pm)";
428 TLOG_ARB(6,
"ArtdaqInputHelper") <<
"Begin/End: ArtdaqInputHelper::closeCurrentFile()";
434 TLOG_ARB(7,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::"
435 "readFile(const std::string& name, art::FileBlock*& fb)";
436 fb =
new art::FileBlock(art::FileFormatVersion(1,
"ArtdaqInputHelper2013"),
"nothing");
437 TLOG_ARB(7,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::"
438 "readFile(const std::string& name, art::FileBlock*& fb)";
444 TLOG_ARB(8,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::hasMoreData()";
445 if (shutdownMsgReceived_)
447 TLOG_ARB(8,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::hasMoreData(): "
448 "returning false on shutdownMsgReceived_.";
449 TLOG_ARB(8,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::hasMoreData()";
452 TLOG_ARB(8,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::hasMoreData(): "
453 "returning true on not shutdownMsgReceived_.";
454 TLOG_ARB(8,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::hasMoreData()";
460 art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR,
461 art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR,
462 art::EventPrincipal*& outE)
467 std::unique_ptr<art::RunAuxiliary> run_aux;
468 std::unique_ptr<art::SubRunAuxiliary> subrun_aux;
469 std::unique_ptr<art::EventAuxiliary> event_aux;
471 HISTORY_PTR_T history_from_event;
478 if (msg_type_code == 2)
481 TLOG_ARB(9,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
482 <<
"processing EndRun message ...";
484 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
487 TLOG_ARB(9,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
488 <<
"making flush RunPrincipal ...";
489 outR = pm_.makeRunPrincipal(RunID::flushRun(), run_aux->beginTime());
491 TLOG_ARB(9,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
492 <<
"making flush SubRunPrincipal ...";
493 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(), run_aux->beginTime());
495 TLOG_ARB(9,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
496 <<
"making flush EventPrincipal ...";
497 outE = pm_.makeEventPrincipal(EventID::flushEvent(), run_aux->endTime(),
true, EventAuxiliary::Any);
499 TLOG_ARB(9,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
500 <<
"finished processing EndRun message.";
502 else if (msg_type_code == 3)
505 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
506 <<
"processing EndSubRun message ...";
509 ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
512 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
513 <<
"making flush RunPrincipal ...";
514 outR = pm_.makeRunPrincipal(RunID::flushRun(), subrun_aux->beginTime());
531 art::Timestamp currentTime = time(0);
534 #if ART_HEX_VERSION < 0x30000
535 inR->setEndTime(currentTime);
537 inR->endTime(currentTime);
542 #if ART_HEX_VERSION < 0x30000
543 inSR->setEndTime(currentTime);
545 inSR->endTime(currentTime);
549 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
550 <<
"making flush SubRunPrincipal ...";
551 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(), subrun_aux->beginTime());
553 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
554 <<
"making flush EventPrincipal ...";
555 outE = pm_.makeEventPrincipal(EventID::flushEvent(), subrun_aux->endTime(),
true, EventAuxiliary::Any);
557 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
558 <<
"finished processing EndSubRun message.";
560 else if (msg_type_code == 4)
563 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
564 <<
"processing Event message ...";
566 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
570 ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
574 ReadObjectAny<art::EventAuxiliary>(msg,
"art::EventAuxiliary",
"ArtdaqInputHelper::readAndConstructPrincipal"));
576 history_from_event.reset(ReadObjectAny<art::History>(msg,
"art::History",
"ArtdaqInputHelper::readAndConstructPrincipal"));
580 if (!history_from_event->processHistoryID().isValid())
582 throw art::Exception(art::errors::Unknown)
583 <<
"readAndConstructPrincipal: processHistoryID of history in Event message is invalid!";
586 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
587 <<
"inR: " << (
void*)inR <<
" run/expected "
588 << (inR ? std::to_string(inR->run()) :
"invalid") <<
"/" << event_aux->run();
589 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
590 <<
"inSR: " << (
void*)inSR <<
" run/expected "
591 << (inSR ? std::to_string(inSR->run()) :
"invalid") <<
"/" << event_aux->run()
592 <<
", subrun/expected " << (inSR ? std::to_string(inSR->subRun()) :
"invalid") <<
"/"
593 << event_aux->subRun();
594 if ((inR ==
nullptr) || !inR->RUN_ID().isValid() || (inR->run() != event_aux->run()))
598 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: making RunPrincipal ...";
599 outR = pm_.makeRunPrincipal(*run_aux.get());
601 art::SubRunID subrun_check(event_aux->run(), event_aux->subRun());
602 if (inSR == 0 || subrun_check != inSR->SUBRUN_ID())
606 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
607 <<
"making SubRunPrincipal ...";
608 outSR = pm_.makeSubRunPrincipal(*subrun_aux.get());
610 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: making EventPrincipal ...";
611 auto historyPtr = HISTORY_PTR_T(
new History(*(history_to_use_.get())));
612 if (!art::ProcessHistoryRegistry::get().count(history_to_use_->processHistoryID()))
614 TLOG_WARNING(
"ArtdaqInputHelper") <<
"Stored history is not in ProcessHistoryRegistry, this event may have issues!";
616 outE = pm_.makeEventPrincipal(*event_aux.get(), std::move(historyPtr));
618 TLOG_ARB(11,
"ArtdaqInputHelper") <<
"readAndConstructPrincipal: "
619 <<
"finished processing Event message.";
624 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)
631 if (firstFragmentType == artdaq::Fragment::EndOfDataFragmentType)
633 TLOG_DEBUG(
"ArtdaqInputHelper") <<
"Received shutdown message, returning false";
634 shutdownMsgReceived_ =
true;
638 auto evtHeader = communicationWrapper_.getEventHeader();
641 TLOG_ERROR(
"ArtdaqInputHelper") <<
"No RawEventHeader received, cannot construct principals!";
642 shutdownMsgReceived_ =
true;
649 art::Timestamp currentTime = 0;
651 art::TimeValue_t lo_res_time = time(0);
652 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"lo_res_time = " << lo_res_time;
653 currentTime = ((lo_res_time & 0xffffffff) << 32);
655 timespec hi_res_time;
656 int retcode = clock_gettime(CLOCK_REALTIME, &hi_res_time);
657 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"hi_res_time tv_sec = " << hi_res_time.tv_sec
658 <<
" tv_nsec = " << hi_res_time.tv_nsec <<
" (retcode = " << retcode <<
")";
661 currentTime = ((hi_res_time.tv_sec & 0xffffffff) << 32) | (hi_res_time.tv_nsec & 0xffffffff);
665 TLOG_ERROR(
"ArtdaqInputHelper")
666 <<
"Unable to fetch a high-resolution time with clock_gettime for art::Event Timestamp. "
667 <<
"The art::Event Timestamp will be zero for event " << evtHeader->event_id;
671 if (inR == 0 || inR->run() != evtHeader->run_id)
673 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Making run principal with run_id " << evtHeader->run_id;
674 outR = pm_.makeRunPrincipal(evtHeader->run_id, currentTime);
677 if (firstFragmentType == artdaq::Fragment::EndOfRunFragmentType)
679 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"EndOfRunFragment received, returning Flush event";
680 art::EventID
const evid(art::EventID::flushEvent());
681 outR = pm_.makeRunPrincipal(evid.runID(), currentTime);
682 outSR = pm_.makeSubRunPrincipal(evid.subRunID(), currentTime);
683 outE = pm_.makeEventPrincipal(evid, currentTime);
686 else if (firstFragmentType == artdaq::Fragment::EndOfSubrunFragmentType)
688 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"EndOfSubrunFragment received, creating new Subrun Principal";
690 if (inR == 0 || inR->run() != evtHeader->run_id)
692 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
693 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
694 art::EventID
const evid(art::EventID::flushEvent(outSR->SUBRUN_ID()));
695 outE = pm_.makeEventPrincipal(evid, currentTime);
703 if (inSR != 0 && !inSR->SUBRUN_ID().isFlush() && inSR->subRun() == evtHeader->subrun_id)
705 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Flushing old run id " << inR->RUN_ID();
706 art::EventID
const evid(art::EventID::flushEvent(inR->RUN_ID()));
707 outSR = pm_.makeSubRunPrincipal(evid.subRunID(), currentTime);
708 outE = pm_.makeEventPrincipal(evid, currentTime);
715 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
716 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
717 art::EventID
const evid(art::EventID::flushEvent(outSR->SUBRUN_ID()));
718 outE = pm_.makeEventPrincipal(evid, currentTime);
729 art::SubRunID subrun_check(evtHeader->run_id, evtHeader->subrun_id);
730 if (inSR == 0 || subrun_check != inSR->SUBRUN_ID())
732 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Making subrun principal with subrun_id " << evtHeader->subrun_id;
733 outSR = pm_.makeSubRunPrincipal(evtHeader->run_id, evtHeader->subrun_id, currentTime);
735 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Making event principal with event_id " << evtHeader->event_id;
736 outE = pm_.makeEventPrincipal(evtHeader->run_id, evtHeader->subrun_id, evtHeader->event_id, currentTime);
744 for (
auto& msg : msgs)
746 unsigned long prd_cnt = 0;
748 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: reading data product count ...";
749 msg->ReadULong(prd_cnt);
750 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: product count: " << prd_cnt;
755 for (
unsigned long I = 0; I < prd_cnt; ++I)
757 std::unique_ptr<BranchKey> bk;
759 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: Reading branch key.";
760 bk.reset(ReadObjectAny<BranchKey>(msg,
"art::BranchKey",
"ArtdaqInputHelper::readDataProducts"));
764 TLOG_ARB(13,
"ArtdaqInputHelper") <<
"readDataProducts: got product class: '" << bk->friendlyClassName_ <<
"' modlbl: '"
765 << bk->moduleLabel_ <<
"' instnm: '" << bk->productInstanceName_ <<
"' procnm: '"
768 ProductList::const_iterator iter;
770 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: looking up product ...";
771 iter = productList_->find(*bk);
772 if (iter == productList_->end())
774 throw art::Exception(art::errors::ProductNotFound)
775 <<
"No product is registered for\n"
776 <<
" process name: '" << bk->processName_ <<
"'\n"
777 <<
" module label: '" << bk->moduleLabel_ <<
"'\n"
778 <<
" product friendly class name: '" << bk->friendlyClassName_ <<
"'\n"
779 <<
" product instance name: '" << bk->productInstanceName_ <<
"'\n";
784 const BranchDescription& bd = iter->second;
785 std::unique_ptr<EDProduct> prd;
787 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: Reading product with wrapped name: " << bd.wrappedName()
788 <<
", TClass = " << (
void*)TClass::GetClass(bd.wrappedName().c_str());
795 void* p = msg->ReadObjectAny(TClass::GetClass(bd.wrappedName().c_str()));
796 auto pp =
reinterpret_cast<EDProduct*
>(p);
798 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: After ReadObjectAny(prd): p=" << p <<
", EDProduct::isPresent: " << pp->isPresent();
802 std::unique_ptr<const ProductProvenance> prdprov;
804 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: Reading product provenance.";
805 prdprov.reset(ReadObjectAny<ProductProvenance>(msg,
"art::ProductProvenance",
"ArtdaqInputHelper::readDataProducts"));
809 TLOG_ARB(12,
"ArtdaqInputHelper") <<
"readDataProducts: inserting product: class: '" << bd.friendlyClassName()
810 <<
"' modlbl: '" << bd.moduleLabel() <<
"' instnm: '" << bd.productInstanceName()
811 <<
"' procnm: '" << bd.processName() <<
"' id: '" << bd.productID() <<
"'";
812 putInPrincipal(outPrincipal, std::move(prd), bd, std::move(prdprov));
820 const BranchDescription& bd,
821 std::unique_ptr<const ProductProvenance>&& prdprov)
823 #if ART_HEX_VERSION < 0x30000
824 rp->put(std::move(prd), bd, std::move(prdprov), RangeSet::forRun(rp->RUN_ID()));
826 rp->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::forRun(rp->RUN_ID())));
832 const BranchDescription& bd,
833 std::unique_ptr<const ProductProvenance>&& prdprov)
835 #if ART_HEX_VERSION < 0x30000
836 srp->put(std::move(prd), bd, std::move(prdprov), RangeSet::forSubRun(srp->SUBRUN_ID()));
838 srp->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::forSubRun(srp->SUBRUN_ID())));
844 const BranchDescription& bd,
845 std::unique_ptr<const ProductProvenance>&& prdprov)
847 TLOG_ARB(14,
"ArtdaqInputHelper") <<
"EventPrincipal size before put: " << ep->size();
848 #if ART_HEX_VERSION < 0x30000
849 ep->put(std::move(prd), bd, std::move(prdprov));
851 ep->put(bd, std::move(prdprov), std::move(prd), std::make_unique<RangeSet>(RangeSet::invalid()));
853 TLOG_ARB(14,
"ArtdaqInputHelper") <<
"EventPrincipal size after put: " << ep->size();
860 double fragmentLatency = 0;
861 double fragmentLatencyMax = 0.0;
862 size_t fragmentCount = 0;
864 art::ServiceHandle<ArtdaqFragmentNamingServiceInterface> translator;
867 for (
auto& fragmentTypePair : eventMap)
869 auto type_code = fragmentTypePair.first;
870 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)
872 TLOG_TRACE(
"ArtdaqInputHelper") <<
"Skipping system Fragment with type " << (int)type_code <<
" ( " << translator->GetInstanceNameForType(type_code) <<
" )";
875 TLOG_TRACE(
"ArtdaqInputHelper") <<
"type is " << (int)type_code <<
", number of fragments is " << fragmentTypePair.second->size();
877 std::unordered_map<std::string, std::unique_ptr<artdaq::Fragments>> derived_fragments;
878 for (
auto& frag : *fragmentTypePair.second)
880 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"Processing Fragment with ID " << frag.fragmentID();
881 bytesRead += frag.sizeBytes();
882 auto latency_s = frag.getLatency(
true);
883 double latency = latency_s.tv_sec + (latency_s.tv_nsec / 1000000000.0);
885 fragmentLatency += latency;
887 if (latency > fragmentLatencyMax) fragmentLatencyMax = latency;
889 std::pair<bool, std::string> instance_name_result =
890 translator->GetInstanceNameForFragment(frag);
891 std::string label = instance_name_result.second;
892 if (!instance_name_result.first)
894 TLOG_WARNING(
"ArtdaqInputHelper")
895 <<
"UnknownFragmentType: The product instance name mapping for fragment type \"" << ((int)type_code)
896 <<
"\" is not known. Fragments of this "
897 <<
"type will be stored in the event with an instance name of \"" << label <<
"\".";
899 if (!derived_fragments.count(label))
901 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"Creating output Fragment storage for label " << label;
902 derived_fragments[label] = std::make_unique<artdaq::Fragments>();
904 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"Adding Fragment " << frag.fragmentID() <<
" to storage with label " << label <<
" (sz=" << derived_fragments[label]->size() + 1 <<
")";
905 derived_fragments[label]->emplace_back(std::move(frag));
907 for (
auto& type : derived_fragments)
909 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"Adding " << type.second->size() <<
" Fragments with label " << type.first <<
" to event.";
910 put_product_in_principal(std::move(type.second), *outE, pretend_module_name, type.first);
915 metricMan->sendMetric(
"bytesRead", bytesRead,
"B", 3, artdaq::MetricMode::LastPoint);
917 metricMan->sendMetric(
"ArtdaqInputHelper Latency", fragmentLatency / fragmentCount,
"s", 4, artdaq::MetricMode::Average);
918 metricMan->sendMetric(
"ArtdaqInputHelper Maximum Latency", fragmentLatencyMax,
"s", 4, artdaq::MetricMode::Maximum);
924 art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE)
926 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"Begin: ArtdaqInputHelper::readNext";
929 if (outputFileCloseNeeded_)
931 outputFileCloseNeeded_ =
false;
934 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
935 <<
"returning false on outputFileCloseNeeded_";
936 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
939 auto read_start_time = std::chrono::steady_clock::now();
941 std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> eventMap = communicationWrapper_.receiveMessages();
942 auto got_event_time = std::chrono::steady_clock::now();
944 if (eventMap.size() == 0)
946 TLOG_ARB(TLVL_ERROR,
"ArtdaqInputHelper") <<
"No Fragments received! Aborting...";
947 shutdownMsgReceived_ =
true;
948 TLOG_ARB(17,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
952 if (!fragmentsOnlyMode_ && !eventMap.count(artdaq::Fragment::DataFragmentType))
954 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext got a message without a DataFragment";
955 shutdownMsgReceived_ =
true;
956 TLOG_ARB(17,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
960 if (fragmentsOnlyMode_)
962 if (eventMap.count(artdaq::Fragment::DataFragmentType))
964 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext unexpectedly got a message with a DataFragment. This art Event will NOT be reconstructed!";
967 auto firstFragmentType = eventMap.begin()->first;
968 TLOG_DEBUG(
"ArtdaqInputHelper") <<
"First Fragment type is " << (int)firstFragmentType;
969 if (constructPrincipal(firstFragmentType, inR, inSR, outR, outSR, outE))
971 readFragments(eventMap, outE);
981 std::list<std::unique_ptr<TBufferFile>> msgs;
982 for (
auto& dataFrag : *(eventMap[artdaq::Fragment::DataFragmentType]))
985 msgs.emplace_back(
new TBufferFile(TBuffer::kRead, header->data_length, dataFrag.dataBegin(), kFALSE, 0));
991 unsigned long msg_type_code = 0;
992 unsigned long msg_type_code_tmp = 0;
993 for (
auto& msg : msgs)
995 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
996 <<
"getting message type code ...";
997 msg->ReadULong(msg_type_code_tmp);
998 TLOG_ARB(15,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
999 <<
"message type: " << msg_type_code_tmp;
1001 if (msg_type_code == 0)
1002 msg_type_code = msg_type_code_tmp;
1003 else if (msg_type_code != msg_type_code_tmp)
1005 TLOG_ARB(TLVL_ERROR,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: Received conflicting message type codes! Aborting...";
1007 shutdownMsgReceived_ =
true;
1008 TLOG_ARB(17,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
1012 if (msg_type_code == 5)
1015 shutdownMsgReceived_ =
true;
1016 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
1017 <<
"returning false on Shutdown message.";
1018 TLOG_ARB(16,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
1022 for (
auto& msg : msgs)
1024 readAndConstructPrincipal(msg, msg_type_code, inR, inSR, outR, outSR, outE);
1029 if (msg_type_code == 2)
1033 readDataProducts(msgs, outR);
1035 TLOG_ARB(17,
"ArtdaqInputHelper") <<
"ArtdaqInputHelper::readNext: "
1036 <<
"returning false on EndRun message.";
1037 TLOG_ARB(17,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext";
1040 else if (msg_type_code == 3)
1051 if (inR != 0 && inSR != 0 && outR != 0 && outSR != 0)
1053 if (inR->RUN_ID().isFlush() && inSR->SUBRUN_ID().isFlush() && outR->RUN_ID().isFlush() &&
1054 outSR->SUBRUN_ID().isFlush())
1058 outputFileCloseNeeded_ =
true;
1063 readDataProducts(msgs, outSR);
1066 outputFileCloseNeeded_ =
true;
1067 TLOG_ARB(18,
"ArtdaqInputHelper") <<
"readNext: returning true on EndSubRun message.";
1070 else if (msg_type_code == 4)
1073 readDataProducts(msgs, outE);
1075 if (eventMap.size() > 1)
1077 readFragments(eventMap, outE);
1080 TLOG_ARB(19,
"ArtdaqInputHelper") <<
"readNext: returning true on Event message.";
1085 auto read_finish_time = std::chrono::steady_clock::now();
1086 TLOG_ARB(10,
"ArtdaqInputHelper") <<
"readNext: bytesRead=" << bytesRead
1087 <<
" metricMan=" << (
void*)metricMan.get();
1090 metricMan->sendMetric(
"Avg Processing Time", artdaq::TimeUtils::GetElapsedTime(last_read_time, read_start_time),
1091 "s", 2, artdaq::MetricMode::Average);
1092 metricMan->sendMetric(
"Avg Input Wait Time", artdaq::TimeUtils::GetElapsedTime(read_start_time, got_event_time),
1093 "s", 3, artdaq::MetricMode::Average);
1094 metricMan->sendMetric(
"Avg Read Time", artdaq::TimeUtils::GetElapsedTime(got_event_time, read_finish_time),
"s",
1095 3, artdaq::MetricMode::Average);
1098 TLOG_ARB(20,
"ArtdaqInputHelper") <<
"End: ArtdaqInputHelper::readNext ret=" << std::boolalpha << ret;
1099 last_read_time = std::chrono::steady_clock::now();
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.