1 #ifndef ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQOUTPUT_HH_
2 #define ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQOUTPUT_HH_
4 #include "art/Framework/Core/OutputModule.h"
5 #include "art/Framework/Principal/EventPrincipal.h"
6 #include "art/Framework/Principal/OutputHandle.h"
7 #include "art/Framework/Principal/RunPrincipal.h"
8 #include "art/Framework/Principal/SubRunPrincipal.h"
10 #include "art/Framework/Core/ModuleMacros.h"
11 #include "art/Framework/Services/Registry/ServiceHandle.h"
12 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
14 #include "art_root_io/setup.h"
16 #include "canvas/Persistency/Common/Wrapper.h"
17 #include "canvas/Persistency/Provenance/BranchDescription.h"
18 #include "canvas/Persistency/Provenance/BranchKey.h"
19 #include "canvas/Persistency/Provenance/History.h"
20 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
21 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
22 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
23 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
24 #include "canvas/Persistency/Provenance/ProductList.h"
25 #include "canvas/Persistency/Provenance/ProductProvenance.h"
26 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
27 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
28 #include "canvas/Utilities/DebugMacros.h"
29 #include "canvas/Utilities/Exception.h"
30 #if ART_HEX_VERSION < 0x30901
31 #include "canvas/Utilities/WrappedTypeID.h"
33 #include "cetlib/column_width.h"
34 #include "cetlib/lpad.h"
35 #include "cetlib/rpad.h"
36 #include "fhiclcpp/ParameterSet.h"
37 #include "fhiclcpp/ParameterSetID.h"
38 #include "fhiclcpp/ParameterSetRegistry.h"
40 #include "artdaq/DAQdata/Globals.hh"
41 #include "artdaq/DAQdata/NetMonHeader.hh"
43 #include "artdaq-core/Data/Fragment.hh"
44 #include "artdaq-core/Data/RawEvent.hh"
45 #include "artdaq-core/Data/detail/ParentageMap.hh"
47 #include <TBufferFile.h>
50 #include <TStreamerInfo.h>
62 #define TLVL_OPENFILE 16
63 #define TLVL_CLOSEFILE 17
64 #define TLVL_RESPONDTOCLOSEINPUTFILE 18
65 #define TLVL_RESPONDTOCLOSEOUTPUTFILE 19
66 #define TLVL_ENDJOB 20
67 #define TLVL_SENDINIT 10
68 #define TLVL_SENDINIT_VERBOSE1 32
69 #define TLVL_SENDINIT_VERBOSE2 33
70 #define TLVL_WRITEDATAPRODUCTS 11
71 #define TLVL_WRITEDATAPRODUCTS_VERBOSE 34
73 #define TLVL_WRITERUN 13
74 #define TLVL_WRITERUN_VERBOSE 37
75 #define TLVL_WRITESUBRUN 14
76 #define TLVL_WRITESUBRUN_VERBOSE 35
77 #define TLVL_EXTRACTPRODUCTS 15
78 #define TLVL_EXTRACTPRODUCTS_VERBOSE 36
84 static artdaq::FragmentPtr outputFrag =
nullptr;
85 inline char* Fragment_ReAllocChar(
char* dataPtr,
size_t size,
size_t )
87 if (outputFrag !=
nullptr && dataPtr == reinterpret_cast<char*>(outputFrag->dataBegin()))
89 outputFrag->resizeBytes(size);
91 return reinterpret_cast<char*
>(outputFrag->dataBegin());
107 : OutputModule(ps), productList_(), raw_data_label_(ps.get<std::string>(
"raw_data_label",
"daq"))
123 TLOG(TLVL_OPENFILE) <<
"Begin/End: ArtdaqOutput::openFile(const FileBlock&)";
129 virtual void closeFile() { TLOG(TLVL_CLOSEFILE) <<
"Begin/End: ArtdaqOutput::closeFile()"; }
136 TLOG(TLVL_RESPONDTOCLOSEINPUTFILE) <<
"Begin/End: ArtdaqOutput::"
137 "respondToCloseOutputFiles(FileBlock const&)";
145 TLOG(TLVL_RESPONDTOCLOSEOUTPUTFILE) <<
"Begin/End: ArtdaqOutput::"
146 "respondToCloseOutputFiles(FileBlock const&)";
154 TLOG(TLVL_ENDJOB) <<
"Begin/End: ArtdaqOutput::endJob()";
189 void event(EventPrincipal
const& ep)
final
197 virtual void event_(EventPrincipal
const&) {}
203 void write(EventPrincipal& ep)
final;
209 void writeRun(RunPrincipal& rp)
final;
223 void writeDataProducts(std::unique_ptr<TBufferFile>& msg,
const Principal& principal, std::vector<BranchKey*>& bkv);
241 virtual void SendMessage(artdaq::FragmentPtr& msg) = 0;
249 bool initMsgSent_{
false};
250 ProductList productList_;
251 size_t last_fragment_size_{10};
252 artdaq::Fragment::sequence_id_t last_sequence_id_{0};
253 artdaq::Fragment::timestamp_t last_timestamp_{0};
254 std::string raw_data_label_;
256 std::unique_ptr<TBufferFile> prepareMessage(artdaq::Fragment::sequence_id_t seqID, artdaq::Fragment::timestamp_t ts, artdaq::Fragment::type_t type)
259 outputFrag = std::make_unique<artdaq::Fragment>(last_fragment_size_, seqID, my_rank, type, hdr, ts);
260 auto msg = std::make_unique<TBufferFile>(TBuffer::kWrite, last_fragment_size_ *
sizeof(artdaq::RawDataType), outputFrag->dataBegin(), kFALSE, &Fragment_ReAllocChar);
263 if (seqID > last_sequence_id_) last_sequence_id_ = seqID;
264 if (ts > last_timestamp_) last_timestamp_ = ts;
269 void sendMessage(std::unique_ptr<TBufferFile>& msg)
272 hdr.
data_length =
static_cast<uint64_t
>(msg->Length());
273 outputFrag->updateMetadata(hdr);
275 last_fragment_size_ = std::ceil(msg->Length() /
static_cast<double>(
sizeof(artdaq::RawDataType)));
282 TLOG(TLVL_SENDINIT) <<
"Begin: ArtdaqOutput::send_init_message()";
292 static TClass* product_list_class = TClass::GetClass(
"std::map<art::BranchKey,art::BranchDescription>");
293 if (product_list_class ==
nullptr)
295 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::send_init_message(): "
296 "Could not get TClass for "
297 "map<art::BranchKey,art::BranchDescription>!";
303 static TClass* process_history_map_class = TClass::GetClass(
"std::map<const art::Hash<2>,art::ProcessHistory>");
304 if (process_history_map_class ==
nullptr)
306 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::send_init_message(): "
307 "Could not get class for "
308 "std::map<const art::Hash<2>,art::ProcessHistory>!";
312 static TClass* parentage_map_class = TClass::GetClass(
"art::ParentageMap");
313 if (parentage_map_class ==
nullptr)
315 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::send_init_message(): "
316 "Could not get class for ParentageMap.";
318 TLOG(TLVL_SENDINIT) <<
"parentage_map_class: " <<
static_cast<void*
>(parentage_map_class);
320 static TClass* history_class = TClass::GetClass(
"art::History");
321 if (history_class ==
nullptr)
323 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::send_init_message(): "
324 "Could not get TClass for art::History!";
330 auto msg = prepareMessage(0, 0, artdaq::Fragment::InitFragmentType);
334 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming message type code ...";
336 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Finished streaming message type code.";
343 std::vector<std::string> classNames{
"std::map<art::BranchKey,art::BranchDescription>",
"std::map<const art::Hash<2>,art::ProcessHistory>",
"art::ParentageMap",
344 "art::History",
"art::BranchKey",
"art::ProductProvenance",
"art::RunAuxiliary",
"art::SubRunAuxiliary",
"art::EventAuxiliary"};
345 for (
auto& className : classNames)
347 TClass* class_ptr = TClass::GetClass(className.c_str());
348 if (class_ptr ==
nullptr)
350 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::send_init_message: Could not get TClass for " << className <<
"!";
352 infos.Add(class_ptr->GetStreamerInfo());
354 msg->WriteObject(&infos);
359 ULong_t ps_cnt = fhicl::ParameterSetRegistry::size();
360 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): parameter set count: " << ps_cnt;
361 msg->WriteULong(ps_cnt);
362 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming parameter sets ...";
363 for (
auto I = std::begin(fhicl::ParameterSetRegistry::get()), E = std::end(fhicl::ParameterSetRegistry::get());
366 TLOG(TLVL_SENDINIT) <<
"Pset ID " << I->first <<
": " << I->second.to_string();
367 std::string pset_str = I->second.to_string();
369 msg->WriteStdString(pset_str);
371 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Finished streaming parameter sets.";
376 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming Product List sz=" << productList_.size() <<
"...";
377 msg->WriteObjectAny(&productList_, product_list_class);
378 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Finished streaming Product List.";
380 art::ProcessHistoryMap phr;
381 for (
auto const& pr : art::ProcessHistoryRegistry::get())
388 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"ArtdaqOutput::send_init_message(): Dumping ProcessHistoryRegistry ...";
391 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"ArtdaqOutput::send_init_message(): phr: size: " << phr.size();
392 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
394 std::ostringstream OS;
396 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"ArtdaqOutput::send_init_message(): phr: id: '" << OS.str() <<
"'";
401 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming ProcessHistoryRegistry ...";
404 const art::ProcessHistoryMap& phm = phr;
405 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): phm: size: " << phm.size();
406 msg->WriteObjectAny(&phm, process_history_map_class);
407 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Finished streaming ProcessHistoryRegistry.";
412 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming ParentageRegistry ..." <<
static_cast<void*
>(parentage_map_class);
413 art::ParentageMap parentageMap{};
414 for (
auto const& pr : art::ParentageRegistry::get())
416 parentageMap.emplace(pr.first, pr.second);
419 msg->WriteObjectAny(&parentageMap, parentage_map_class);
421 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Finished streaming ParentageRegistry.";
423 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Streaming History";
424 msg->WriteObjectAny(&history, history_class);
425 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Done streaming History";
427 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Sending init message";
429 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): Done sending init message";
431 TLOG(TLVL_SENDINIT) <<
"ArtdaqOutput::send_init_message(): END";
436 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"Begin: ArtdaqOutput::writeDataProducts(...)";
441 static TClass* branch_key_class = TClass::GetClass(
"art::BranchKey");
442 if (branch_key_class ==
nullptr)
444 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::writeDataProducts(...): "
445 "Could not get TClass for art::BranchKey!";
447 static TClass* prdprov_class = TClass::GetClass(
"art::ProductProvenance");
448 if (prdprov_class ==
nullptr)
450 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::writeDataProducts(...): "
451 "Could not get TClass for art::ProductProvenance!";
459 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
461 auto const& productDescription = I->second->productDescription();
462 auto const& refs = keptProducts()[productDescription.branchType()];
464 for (
auto const& ref : refs)
466 if (ref.second == productDescription)
472 if (!I->second->productAvailable() || !found)
481 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"ArtdaqOutput::writeDataProducts(...): Streaming product count: " +
482 std::to_string(prd_cnt);
483 msg->WriteULong(prd_cnt);
484 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"ArtdaqOutput::writeDataProducts(...): Finished streaming product count.";
496 bkv.reserve(prd_cnt);
498 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
500 auto const& productDescription = I->second->productDescription();
501 auto const& refs = keptProducts()[productDescription.branchType()];
503 for (
auto const& ref : refs)
505 if (ref.second == productDescription)
511 if (!I->second->productAvailable() || !found)
515 const BranchDescription& bd(I->second->productDescription());
516 bkv.push_back(
new BranchKey(bd));
517 TLOG(TLVL_WRITEDATAPRODUCTS_VERBOSE)
518 <<
"ArtdaqOutput::writeDataProducts(...): Dumping branch key of class: '"
519 << bkv.back()->friendlyClassName_ <<
"' modlbl: '" << bkv.back()->moduleLabel_ <<
"' instnm: '"
520 << bkv.back()->productInstanceName_ <<
"' procnm: '" << bkv.back()->processName_ <<
"'";
521 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"ArtdaqOutput::writeDataProducts(...): "
522 "Streaming branch key of class: '"
523 << bd.producedClassName() <<
"' modlbl: '" << bd.moduleLabel() <<
"' instnm: '"
524 << bd.productInstanceName() <<
"' procnm: '" << bd.processName() <<
"'";
525 msg->WriteObjectAny(bkv.back(), branch_key_class);
527 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"ArtdaqOutput::writeDataProducts(...): "
528 "Streaming product of class: '"
529 << bd.producedClassName() <<
"' modlbl: '" << bd.moduleLabel() <<
"' instnm: '"
530 << bd.productInstanceName() <<
"' procnm: '" << bd.processName() <<
"'";
532 OutputHandle oh = principal.getForOutput(bd.productID(),
true);
533 const EDProduct* prd = oh.wrapper();
534 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"Class for branch " << bd.wrappedName() <<
" is "
535 <<
static_cast<void*
>(TClass::GetClass(bd.wrappedName().c_str()));
536 msg->WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
537 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"ArtdaqOutput::writeDataProducts(...): "
538 "Streaming product provenance of class: '"
539 << bd.producedClassName() <<
"' modlbl: '" << bd.moduleLabel() <<
"' instnm: '"
540 << bd.productInstanceName() <<
"' procnm: '" << bd.processName() <<
"'";
542 const ProductProvenance* prdprov = I->second->productProvenance().get();
544 msg->WriteObjectAny(prdprov, prdprov_class);
546 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"End: ArtdaqOutput::writeDataProducts(...)";
554 TLOG(TLVL_WRITE) <<
"Begin: ArtdaqOutput::write(const EventPrincipal& ep)";
557 send_init_message(ep.history());
563 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
564 if (run_aux_class ==
nullptr)
566 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::write(const EventPrincipal& ep): "
567 "Could not get TClass for art::RunAuxiliary!";
569 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
570 if (subrun_aux_class ==
nullptr)
572 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::write(const EventPrincipal& ep): "
573 "Could not get TClass for art::SubRunAuxiliary!";
575 static TClass* event_aux_class = TClass::GetClass(
"art::EventAuxiliary");
576 if (event_aux_class ==
nullptr)
578 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::write(const EventPrincipal& ep): "
579 "Could not get TClass for art::EventAuxiliary!";
581 static TClass* history_class = TClass::GetClass(
"art::History");
582 if (history_class ==
nullptr)
584 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::write(const EventPrincipal& ep): "
585 "Could not get TClass for art::History!";
589 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Setting Output Fragment Header Fields";
590 auto seqID = (
static_cast<uint64_t
>(ep.eventID().subRun() - 1) << 32) + ep.eventID().event();
592 art::ProcessTag tag(
"", processName());
593 auto res = ep.getMany(art::ModuleContext::invalid(), art::WrappedTypeID::make<artdaq::detail::RawEventHeader>(), art::MatchAllSelector(), tag);
595 artdaq::Fragment::timestamp_t ts = 0;
597 for (
auto const& qr : res)
599 Handle<artdaq::detail::RawEventHeader> handle{qr};
600 if (handle.isValid())
602 if (handle->timestamp > ts) ts = handle->timestamp;
605 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Data Fragment Header Fields: SeqID: " << seqID <<
", timestamp: " << ts;
610 auto msg = prepareMessage(seqID, ts, artdaq::Fragment::DataFragmentType);
614 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Streaming message type code ...";
616 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Finished streaming message type code.";
621 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Streaming RunAuxiliary ...";
622 msg->WriteObjectAny(&ep.subRunPrincipal().runPrincipal().runAux(), run_aux_class);
623 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Finished streaming RunAuxiliary.";
628 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Streaming SubRunAuxiliary ...";
629 msg->WriteObjectAny(&ep.subRunPrincipal().subRunAux(), subrun_aux_class);
630 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Finished streaming SubRunAuxiliary.";
636 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Streaming EventAuxiliary ...";
637 msg->WriteObjectAny(&ep.eventAux(), event_aux_class);
638 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Finished streaming EventAuxiliary.";
644 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Streaming History ...";
645 msg->WriteObjectAny(&ep.history(), history_class);
646 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write(const EventPrincipal& ep): Finished streaming History.";
651 std::vector<BranchKey*> bkv;
652 writeDataProducts(msg, ep, bkv);
654 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write: Sending message";
656 TLOG(TLVL_WRITE) <<
"ArtdaqOutput::write: Done sending message";
661 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
666 TLOG(TLVL_WRITE) <<
"End: ArtdaqOutput::write(const EventPrincipal& ep)";
673 TLOG(TLVL_WRITERUN) <<
"Begin: ArtdaqOutput::writeRun(const RunPrincipal& rp)";
677 send_init_message(rp.history());
685 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
686 assert(run_aux_class !=
nullptr &&
"writeRun: Could not get TClass for art::RunAuxiliary!");
690 auto msg = prepareMessage(last_sequence_id_ + 1,rp.run() + 1, artdaq::Fragment::EndOfRunFragmentType);
695 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: streaming message type code ...";
697 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: finished streaming message type code.";
703 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: streaming RunAuxiliary ...";
704 msg->WriteObjectAny(&rp.runAux(), run_aux_class);
705 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: streamed RunAuxiliary.";
710 std::vector<BranchKey*> bkv;
711 writeDataProducts(msg, rp, bkv);
713 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: Sending message";
715 TLOG(TLVL_WRITERUN) <<
"ArtdaqOutput::writeRun: Done sending message";
717 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
723 TLOG(TLVL_WRITERUN) <<
"End: ArtdaqOutput::writeRun(RunPrincipal& rp)";
729 TLOG(TLVL_WRITESUBRUN) <<
"Begin: ArtdaqOutput::writeSubRun(const SubRunPrincipal& srp)";
732 send_init_message(srp.history());
739 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
740 if (subrun_aux_class ==
nullptr)
742 throw art::Exception(art::errors::DictionaryNotFound) <<
"ArtdaqOutput::writeSubRun: "
743 "Could not get TClass for art::SubRunAuxiliary!";
748 auto msg = prepareMessage(last_sequence_id_ + 1, srp.subRun() + 1, artdaq::Fragment::EndOfSubrunFragmentType);
753 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: streaming message type code ...";
755 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: finished streaming message type code.";
761 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: streaming SubRunAuxiliary ...";
763 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: dumping ProcessHistoryRegistry ...";
766 for (
auto I = std::begin(art::ProcessHistoryRegistry::get()), E = std::end(art::ProcessHistoryRegistry::get());
769 std::ostringstream OS;
771 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: phr: id: '" << OS.str() <<
"'";
773 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: phr: data.size(): " << I->second.data().size();
774 if (!I->second.data().empty())
776 I->second.data().back().id().print(OS);
777 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: phr: data.back().id(): '" << OS.str() <<
"'";
780 if (!srp.subRunAux().processHistoryID().isValid())
782 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: ProcessHistoryID: 'INVALID'";
786 std::ostringstream OS;
787 srp.subRunAux().processHistoryID().print(OS);
788 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: ProcessHistoryID: '" << OS.str() <<
"'";
790 ProcessHistory processHistory;
791 ProcessHistoryRegistry::get(srp.subRunAux().processHistoryID(), processHistory);
792 if (!processHistory.data().empty())
795 processHistory.data().back().id().print(OS);
796 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: ProcessConfigurationID: '" << OS.str() <<
"'";
798 OS << processHistory.data().back();
799 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"ArtdaqOutput::writeSubRun: ProcessConfiguration: '" << OS.str();
802 msg->WriteObjectAny(&srp.subRunAux(), subrun_aux_class);
803 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: streamed SubRunAuxiliary.";
808 std::vector<BranchKey*> bkv;
809 writeDataProducts(msg, srp, bkv);
811 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: Sending message";
813 TLOG(TLVL_WRITESUBRUN) <<
"ArtdaqOutput::writeSubRun: Done sending message";
818 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
823 TLOG(TLVL_WRITESUBRUN) <<
"End: ArtdaqOutput::writeSubRun(const SubRunPrincipal& srp)";
828 TLOG(TLVL_EXTRACTPRODUCTS) <<
"Begin: ArtdaqOutput::extractProducts_(Principal const& principal) sz=" << principal.size();
830 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
832 auto const& productDescription = I->second->productDescription();
833 auto const& branchKey = BranchKey(productDescription);
835 if (!productList_.count(branchKey))
837 TLOG(TLVL_EXTRACTPRODUCTS_VERBOSE) <<
"ArtdaqOutput::extractProducts_:"
838 <<
"Adding branch key to productList of class: '"
839 << branchKey.friendlyClassName_ <<
"' modlbl: '" << branchKey.moduleLabel_ <<
"' instnm: '"
840 << branchKey.productInstanceName_ <<
"' procnm: '" << branchKey.processName_ <<
"'"
841 <<
", description: " << productDescription.wrappedName();
843 productList_[branchKey] = productDescription;
847 TLOG(TLVL_EXTRACTPRODUCTS) <<
"End: ArtdaqOutput::extractProducts_(Principal const& principal) Product list sz=" << productList_.size();
850 #endif // ARTDAQ_ARTDAQ_ARTMODULES_ARTDAQOUTPUT_HH_
void writeRun(RunPrincipal &rp) final
Write a RunPrincipal to TBufferFile and send
virtual void event_(EventPrincipal const &)
Perform actions for each event. No-op, but derived classes may override
void send_init_message(History const &history)
Send an init message downstream. Use the given History for initializing downstream art processes...
void extractProducts_(Principal const &principal)
Extract the list of Products from the given Principal
This is the base class for artdaq OutputModules, providing the serialization interface for art Events...
virtual void beginSubRun_(SubRunPrincipal const &)
Perform Begin SubRun actions. No-op, but derived classes may override
virtual ~ArtdaqOutput()=default
Destructor
void event(EventPrincipal const &ep) final
Perform actions for each event. Derived classes should implement event_ instead.
virtual void openFile(FileBlock const &)
Perform actions necessary for opening files. No-op, but derived classes may override ...
virtual void endJob()
Perform End-of-Job actions. No-op, but derived classes may override
virtual void SendMessage(artdaq::FragmentPtr &msg)=0
Send the serialized art Event downstream. Artdaq output modules should define this function...
void beginRun(RunPrincipal const &rp) final
Perform Begin Run actions. Derived classes should implement beginRun_ instead.
void beginSubRun(SubRunPrincipal const &srp) final
Perform Begin SubRun actions. Derived classes should implement beginSubRun_ instead.
virtual void closeFile()
Perform actions necessary for closing files. No-op, but derived classes may override ...
ArtdaqOutput(fhicl::ParameterSet const &ps)
ArtdaqOutput Constructor
virtual void respondToCloseOutputFiles(FileBlock const &)
Perform actions necessary after closing the output file(s). No-op, but derived classes may override ...
void writeSubRun(SubRunPrincipal &srp) final
Write a SubRunPrincipal to TBufferFile and send
virtual void respondToCloseInputFile(FileBlock const &)
Perform actions nesessary after closing the input file. No-op, but derived classes may override ...
virtual void beginRun_(RunPrincipal const &)
Perform Begin Run actions. No-op, but derived classes may override
void write(EventPrincipal &ep) final
Write an EventPrincipal to TBufferFile and send
void writeDataProducts(std::unique_ptr< TBufferFile > &msg, const Principal &principal, std::vector< BranchKey * > &bkv)
Extract the data products from a Principal and write them to the TBufferFile