1 #include "art/Framework/Core/ModuleMacros.h"
2 #include "art/Framework/Core/OutputModule.h"
3 #include "art/Framework/Principal/EventPrincipal.h"
4 #include "art/Framework/Principal/OutputHandle.h"
5 #include "art/Framework/Principal/RunPrincipal.h"
6 #include "art/Framework/Principal/SubRunPrincipal.h"
7 #include "art/Framework/Services/Registry/ServiceHandle.h"
8 #if ART_HEX_VERSION >= 0x20703
11 # include "art/Persistency/Provenance/BranchIDListHelper.h"
13 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
14 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
15 #include "art/Persistency/Provenance/ProductMetaData.h"
17 #include "canvas/Persistency/Provenance/BranchDescription.h"
18 #include "canvas/Persistency/Provenance/BranchIDList.h"
19 #include "canvas/Persistency/Provenance/BranchKey.h"
20 #include "canvas/Persistency/Provenance/History.h"
21 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
22 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
23 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
24 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
25 #include "canvas/Persistency/Provenance/ProductList.h"
26 #include "canvas/Persistency/Provenance/ProductProvenance.h"
27 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
28 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
29 #include "canvas/Utilities/DebugMacros.h"
30 #include "canvas/Utilities/Exception.h"
31 #include "cetlib/column_width.h"
32 #include "cetlib/lpad.h"
33 #include "cetlib/rpad.h"
35 #include "fhiclcpp/ParameterSet.h"
36 #include "fhiclcpp/ParameterSetID.h"
37 #include "fhiclcpp/ParameterSetRegistry.h"
39 #include "artdaq/ArtModules/NetMonTransportService.h"
40 #include "artdaq/ArtModules/detail/ParentageMap.hh"
41 #include "artdaq/DAQdata/Globals.hh"
42 #include "artdaq/DAQdata/NetMonHeader.hh"
55 #define TRACE_NAME "RootMPIOutput"
88 virtual void openFile(FileBlock
const&);
90 virtual void closeFile();
92 virtual void respondToCloseInputFile(FileBlock
const&);
94 virtual void respondToCloseOutputFiles(FileBlock
const&);
96 virtual void endJob();
98 virtual void write(EventPrincipal CONST_WRITE&);
100 virtual void writeRun(RunPrincipal CONST_WRITE&);
102 virtual void writeSubRun(SubRunPrincipal CONST_WRITE&);
104 void writeDataProducts(TBufferFile&,
const Principal&,
105 std::vector<BranchKey*>&);
114 , initMsgSent_(false)
116 TLOG_DEBUG(
"RootMPIOutput") <<
"Begin: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
117 ServiceHandle<NetMonTransportService> transport;
118 transport->connect();
119 TLOG_DEBUG(
"RootMPIOutput") <<
"End: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
125 TLOG_DEBUG(
"RootMPIOutput") <<
"Begin: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
126 ServiceHandle<NetMonTransportService> transport;
127 transport->disconnect();
128 TLOG_DEBUG(
"RootMPIOutput") <<
"End: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
133 openFile(FileBlock
const&)
135 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::openFile(const FileBlock&)");
142 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::closeFile()");
147 respondToCloseInputFile(FileBlock
const&)
149 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::"
150 "respondToCloseOutputFiles(FileBlock const&)");
155 respondToCloseOutputFiles(FileBlock
const&)
157 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::"
158 "respondToCloseOutputFiles(FileBlock const&)");
163 send_shutdown_message()
175 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::endJob()");
176 send_shutdown_message();
177 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::endJob()");
186 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput static send_init_message()");
196 static TClass* product_list_class = TClass::GetClass(
197 "std::map<art::BranchKey,art::BranchDescription>");
198 if (product_list_class ==
nullptr)
200 throw art::Exception(art::errors::DictionaryNotFound) <<
201 "RootMPIOutput static send_init_message(): "
202 "Could not get TClass for "
203 "map<art::BranchKey,art::BranchDescription>!";
209 static TClass* process_history_map_class = TClass::GetClass(
210 "std::map<const art::Hash<2>,art::ProcessHistory>");
211 if (process_history_map_class ==
nullptr)
213 throw art::Exception(art::errors::DictionaryNotFound) <<
214 "RootMPIOutput static send_init_message(): "
215 "Could not get class for "
216 "std::map<const art::Hash<2>,art::ProcessHistory>!";
221 static TClass* parentage_map_class = TClass::GetClass(
"art::ParentageMap");
222 if (parentage_map_class ==
nullptr)
224 throw art::Exception(art::errors::DictionaryNotFound) <<
225 "RootMPIOutput static send_init_message(): "
226 "Could not get class for ParentageMap.";
231 TBufferFile msg(TBuffer::kWrite);
236 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
237 "Streaming message type code ...");
239 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
240 "Finished streaming message type code.");
245 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
246 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): parameter set count: " + std::to_string(ps_cnt));
247 msg.WriteULong(ps_cnt);
248 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Streaming parameter sets ...");
250 #
if ART_HEX_VERSION >= 0x20703
251 auto I = std::begin(fhicl::ParameterSetRegistry::get()),
252 E = std::end(fhicl::ParameterSetRegistry::get());
254 auto I = fhicl::ParameterSetRegistry::begin(),
255 E = fhicl::ParameterSetRegistry::end();
259 std::string pset_str = I->second.to_string();
261 msg.WriteStdString(pset_str);
263 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming parameter sets.");
268 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Streaming MasterProductRegistry ...");
269 art::ProductList productList(
270 art::ProductMetaData::instance().productList());
271 msg.WriteObjectAny(&productList, product_list_class);
272 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming MasterProductRegistry.");
277 if (art::debugit() >= 2)
282 # if ART_HEX_VERSION >= 0x20703
283 art::BranchIDLists
const * bilr =
284 &art::BranchIDListRegistry::instance().data();
286 art::BranchIDLists* bilr =
287 &art::BranchIDListRegistry::instance()->data();
289 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
290 "Content of BranchIDLists\n";
291 int max_bli = bilr->size();
292 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
293 "max_bli: " << max_bli <<
'\n';
294 for (
int i = 0; i < max_bli; ++i)
296 int max_prdidx = (*bilr)[i].size();
297 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
298 "max_prdidx: " << max_prdidx <<
'\n';
299 for (
int j = 0; j < max_prdidx; ++j)
301 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
304 <<
" bid: 0x" << std::hex
305 <<
static_cast<unsigned long>((*bilr)[i][j])
311 # if ART_HEX_VERSION >= 0x20703
312 art::ProcessHistoryMap phr;
313 for (
auto const& pr : art::ProcessHistoryRegistry::get()) {
320 if (art::debugit() >= 1)
322 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
323 "Dumping ProcessHistoryRegistry ...");
326 # if ART_HEX_VERSION < 0x20703
327 art::ProcessHistoryMap
const& phr = art::ProcessHistoryRegistry::get();
329 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
330 "phr: size: " + std::to_string(phr.size()));
331 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
333 std::ostringstream OS;
335 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
336 "phr: id: '" + OS.str() +
"'");
342 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
343 "Streaming ProcessHistoryRegistry ...");
346 # if ART_HEX_VERSION >= 0x20703
347 const art::ProcessHistoryMap& phm = phr;
349 const art::ProcessHistoryMap& phm = art::ProcessHistoryRegistry::get();
351 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
352 "phm: size: " + std::to_string(phm.size()));
353 msg.WriteObjectAny(&phm, process_history_map_class);
354 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
355 "Finished streaming ProcessHistoryRegistry.");
360 TRACE(5,
"RootMPIOutput: static send_init_message(): "
361 "Streaming ParentageRegistry ...");
362 # if ART_HEX_VERSION >= 0x20703
363 art::ParentageMap parentageMap{};
364 for (
auto const& pr : art::ParentageRegistry::get()) {
365 parentageMap.emplace(pr.first, pr.second);
368 const art::ParentageMap& parentageMap = art::ParentageRegistry::get();
371 msg.WriteObjectAny(&parentageMap, parentage_map_class);
373 TRACE(5,
"RootMPIOutput: static send_init_message(): Finished streaming ParentageRegistry.");
379 art::ServiceHandle<NetMonTransportService> transport;
380 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
381 "Sending the init message to "
382 + std::to_string(transport->dataReceiverCount()) +
383 " data receivers ...");
384 for (
size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
386 transport->sendMessage(idx, artdaq::Fragment::InitFragmentType, msg);
388 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
389 "Init message(s) sent.");
391 TRACE(5,
"RootMPIOutput: End: RootMPIOutput static send_init_message()");
398 writeDataProducts(TBufferFile& msg,
const Principal& principal,
399 std::vector<BranchKey*>& bkv)
401 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::writeDataProducts(...)");
406 static TClass* branch_key_class = TClass::GetClass(
"art::BranchKey");
407 if (branch_key_class ==
nullptr)
409 throw art::Exception(art::errors::DictionaryNotFound) <<
410 "RootMPIOutput::writeDataProducts(...): "
411 "Could not get TClass for art::BranchKey!";
413 static TClass* prdprov_class = TClass::GetClass(
"art::ProductProvenance");
414 if (prdprov_class ==
nullptr)
416 throw art::Exception(art::errors::DictionaryNotFound) <<
417 "RootMPIOutput::writeDataProducts(...): "
418 "Could not get TClass for art::ProductProvenance!";
423 unsigned long prd_cnt = 0;
425 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
427 if (I->second->productUnavailable() || !selected(I->second->productDescription()))
436 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
437 "Streaming product count: " + std::to_string(prd_cnt));
438 msg.WriteULong(prd_cnt);
439 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
440 "Finished streaming product count.");
452 bkv.reserve(prd_cnt);
454 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
456 if (I->second->productUnavailable() || !selected(I->second->productDescription()))
460 const BranchDescription& bd(I->second->productDescription());
461 bkv.push_back(
new BranchKey(bd));
462 if (art::debugit() >= 2)
464 FDEBUG(2) <<
"RootMPIOutput::writeDataProducts(...): "
465 "Dumping branch key of class: '"
466 << bkv.back()->friendlyClassName_
468 << bkv.back()->moduleLabel_
470 << bkv.back()->productInstanceName_
472 << bkv.back()->processName_
475 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
476 "Streaming branch key of class: '"
477 + bd.producedClassName()
481 + bd.productInstanceName()
485 msg.WriteObjectAny(bkv.back(), branch_key_class);
486 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
487 "Streaming product of class: '"
488 + bd.producedClassName()
492 + bd.productInstanceName()
496 OutputHandle oh = principal.getForOutput(bd.branchID(),
true);
497 const EDProduct* prd = oh.wrapper();
498 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
499 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
500 "Streaming product provenance of class: '"
501 + bd.producedClassName()
505 + bd.productInstanceName()
509 const ProductProvenance* prdprov =
510 I->second->productProvenancePtr().get();
511 msg.WriteObjectAny(prdprov, prdprov_class);
513 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::writeDataProducts(...)");
518 write(CONST_WRITE EventPrincipal& ep)
523 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::"
524 "write(const EventPrincipal& ep)");
533 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
534 if (run_aux_class ==
nullptr)
536 throw art::Exception(art::errors::DictionaryNotFound) <<
537 "RootMPIOutput::write(const EventPrincipal& ep): "
538 "Could not get TClass for art::RunAuxiliary!";
540 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
541 if (subrun_aux_class ==
nullptr)
543 throw art::Exception(art::errors::DictionaryNotFound) <<
544 "RootMPIOutput::write(const EventPrincipal& ep): "
545 "Could not get TClass for art::SubRunAuxiliary!";
547 static TClass* event_aux_class = TClass::GetClass(
"art::EventAuxiliary");
548 if (event_aux_class ==
nullptr)
550 throw art::Exception(art::errors::DictionaryNotFound) <<
551 "RootMPIOutput::write(const EventPrincipal& ep): "
552 "Could not get TClass for art::EventAuxiliary!";
554 static TClass* history_class = TClass::GetClass(
"art::History");
555 if (history_class ==
nullptr)
557 throw art::Exception(art::errors::DictionaryNotFound) <<
558 "RootMPIOutput::write(const EventPrincipal& ep): "
559 "Could not get TClass for art::History!";
564 TBufferFile msg(TBuffer::kWrite);
569 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
570 "Streaming message type code ...");
572 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
573 "Finished streaming message type code.");
578 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
579 "Streaming RunAuxiliary ...");
580 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
582 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
583 "Finished streaming RunAuxiliary.");
588 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
589 "Streaming SubRunAuxiliary ...");
590 msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
592 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
593 "Finished streaming SubRunAuxiliary.");
599 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
600 "Streaming EventAuxiliary ...");
601 msg.WriteObjectAny(&ep.aux(), event_aux_class);
602 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
603 "Finished streaming EventAuxiliary.");
609 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
610 "Streaming History ...");
611 msg.WriteObjectAny(&ep.history(), history_class);
612 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
613 "Finished streaming History.");
618 std::vector<BranchKey*> bkv;
619 writeDataProducts(msg, ep, bkv);
624 ServiceHandle<NetMonTransportService> transport;
625 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
626 "Sending a message ...");
627 transport->sendMessage(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
628 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
634 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
639 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::write(const EventPrincipal& ep)");
644 writeRun(CONST_WRITE RunPrincipal& rp)
649 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::writeRun(const RunPrincipal& rp)");
661 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
662 assert(run_aux_class !=
nullptr &&
"writeRun: Could not get TClass for "
663 "art::RunAuxiliary!");
667 TBufferFile msg(TBuffer::kWrite);
673 TRACE(5,
"RootMPIOutput: writeRun: streaming message type code ...");
675 TRACE(5,
"RootMPIOutput: writeRun: finished streaming message type code.");
681 TRACE(5,
"RootMPIOutput: writeRun: streaming RunAuxiliary ...");
682 if (art::debugit() >= 1) {
683 TRACE(5,
"RootMPIOutput: writeRun: dumping ProcessHistoryRegistry ...");
686 art::ProcessHistoryMap
const& phr =
687 art::ProcessHistoryRegistry::get();
688 TRACE(5,
"RootMPIOutput: writeRun: phr: size: " << phr.size() <<
'\n';
689 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I) {
690 std::ostringstream OS;
692 TRACE(5,
"RootMPIOutput: writeRun: phr: id: '" << OS.str() <<
"'");
694 TRACE(5,
"RootMPIOutput: writeRun: phr: data.size(): "
695 << I->second.data().size() <<
'\n';
696 if (I->second.data().size()) {
697 I->second.data().back().id().print(OS);
698 TRACE(5,
"RootMPIOutput: writeRun: phr: data.back().id(): '"
702 if (!rp.aux().processHistoryID().isValid()) {
703 TRACE(5,
"RootMPIOutput: writeRun: ProcessHistoryID: 'INVALID'");
706 std::ostringstream OS;
707 rp.aux().processHistoryID().print(OS);
708 TRACE(5,
"RootMPIOutput: writeRun: ProcessHistoryID: '"
711 const ProcessHistory& processHistory =
712 ProcessHistoryRegistry::get(rp.aux().processHistoryID());
713 if (processHistory.data().size()) {
715 processHistory.data().back().id().print(OS);
716 TRACE(5,
"RootMPIOutput: writeRun: ProcessConfigurationID: '"
719 TRACE(5,
"RootMPIOutput: writeRun: ProcessConfiguration: '"
720 << processHistory.data().back() <<
'\n';
724 msg.WriteObjectAny(&rp.aux(), run_aux_class);
725 TRACE(5,
"RootMPIOutput: writeRun: streamed RunAuxiliary.");
730 std::vector<BranchKey*> bkv;
731 writeDataProducts(msg, rp, bkv);
736 ServiceHandle<NetMonTransportService> transport;
737 TRACE(5,
"RootMPIOutput: writeRun: sending a message ...");
738 transport->sendMessage(0, artdaq::Fragment::EndOfRunFragmentType, msg);
739 TRACE(5,
"RootMPIOutput: writeRun: message sent.");
744 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I) {
749 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::writeRun(const RunPrincipal& rp)");
753 art::RootMPIOutput::writeSubRun(CONST_WRITE SubRunPrincipal& srp)
758 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::"
759 "writeSubRun(const SubRunPrincipal& srp)");
769 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
770 if (subrun_aux_class ==
nullptr)
772 throw art::Exception(art::errors::DictionaryNotFound) <<
773 "RootMPIOutput::writeSubRun: "
774 "Could not get TClass for art::SubRunAuxiliary!";
779 TBufferFile msg(TBuffer::kWrite);
785 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
786 "streaming message type code ...");
788 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
789 "finished streaming message type code.");
795 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
796 "streaming SubRunAuxiliary ...");
797 if (art::debugit() >= 1)
799 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
800 "dumping ProcessHistoryRegistry ...");
803 # if ART_HEX_VERSION >= 0x20703
804 for (
auto I = std::begin(art::ProcessHistoryRegistry::get())
805 , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I)
807 art::ProcessHistoryMap
const& phr =
808 art::ProcessHistoryRegistry::get();
809 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
810 "phr: size: " + std::to_string(phr.size()));
811 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
814 std::ostringstream OS;
816 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
817 "phr: id: '" + OS.str() +
"'");
819 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
820 "phr: data.size(): %zu",I->second.data().size() );
821 if (I->second.data().size())
823 I->second.data().back().id().print(OS);
824 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
825 "phr: data.back().id(): '"
829 if (!srp.aux().processHistoryID().isValid())
831 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
832 "ProcessHistoryID: 'INVALID'");
836 std::ostringstream OS;
837 srp.aux().processHistoryID().print(OS);
838 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: ProcessHistoryID: '"
841 # if ART_HEX_VERSION >= 0x20703
842 ProcessHistory processHistory;
843 ProcessHistoryRegistry::get(srp.aux().processHistoryID(),processHistory);
845 const ProcessHistory& processHistory =
846 ProcessHistoryRegistry::get(srp.aux().processHistoryID());
848 if (processHistory.data().size())
851 processHistory.data().back().id().print(OS);
852 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
853 "ProcessConfigurationID: '"
856 OS << processHistory.data().back();
857 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
858 "ProcessConfiguration: '"
863 msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
864 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: streamed SubRunAuxiliary.");
869 std::vector<BranchKey*> bkv;
870 writeDataProducts(msg, srp, bkv);
874 ServiceHandle<NetMonTransportService> transport;
875 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
876 "Sending the EndOfSubrun message to "
877 + std::to_string(transport->dataReceiverCount())
878 +
" data receivers ...");
879 for (
size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
881 transport->sendMessage(idx, artdaq::Fragment::EndOfSubrunFragmentType, msg);
883 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
884 "EndOfSubrun message(s) sent.");
888 transport->disconnect();
893 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
898 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::writeSubRun(const SubRunPrincipal& srp)");
RootMPIOutput(fhicl::ParameterSet const &ps)
RootMPIOutput Constructor.
~RootMPIOutput()
RootMPIOutput Destructor.
An art::OutputModule which sends events using DataSenderManager. This module is designed for transpor...