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 #include "art/Persistency/Provenance/BranchIDListHelper.h"
9 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
10 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
11 #include "art/Persistency/Provenance/ProductMetaData.h"
13 #include "canvas/Persistency/Provenance/BranchDescription.h"
14 #include "canvas/Persistency/Provenance/BranchIDList.h"
15 #include "canvas/Persistency/Provenance/BranchKey.h"
16 #include "canvas/Persistency/Provenance/History.h"
17 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
18 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
19 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
20 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
21 #include "canvas/Persistency/Provenance/ProductList.h"
22 #include "canvas/Persistency/Provenance/ProductProvenance.h"
23 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
24 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
25 #include "canvas/Utilities/DebugMacros.h"
26 #include "canvas/Utilities/Exception.h"
27 #include "cetlib/column_width.h"
28 #include "cetlib/lpad.h"
29 #include "cetlib/rpad.h"
31 #include "fhiclcpp/ParameterSet.h"
32 #include "fhiclcpp/ParameterSetID.h"
33 #include "fhiclcpp/ParameterSetRegistry.h"
35 #include "artdaq/DAQdata/Globals.hh"
36 #include "artdaq/ArtModules/NetMonTransportService.h"
37 #include "artdaq/DAQdata/NetMonHeader.hh"
50 #define TRACE_NAME "RootMPIOutput"
82 virtual void openFile(FileBlock
const&);
84 virtual void closeFile();
86 virtual void respondToCloseInputFile(FileBlock
const&);
88 virtual void respondToCloseOutputFiles(FileBlock
const&);
90 virtual void endJob();
92 virtual void write(EventPrincipal CONST_WRITE&);
94 virtual void writeRun(RunPrincipal CONST_WRITE&);
96 virtual void writeSubRun(SubRunPrincipal CONST_WRITE&);
98 void writeDataProducts(TBufferFile&,
const Principal&,
99 std::vector<BranchKey*>&);
108 , initMsgSent_(false)
110 TLOG_DEBUG(
"RootMPIOutput") <<
"Begin: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
111 ServiceHandle<NetMonTransportService> transport;
112 transport->connect();
113 TLOG_DEBUG(
"RootMPIOutput") <<
"End: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
119 TLOG_DEBUG(
"RootMPIOutput") <<
"Begin: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
120 ServiceHandle<NetMonTransportService> transport;
121 transport->disconnect();
122 TLOG_DEBUG(
"RootMPIOutput") <<
"End: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
127 openFile(FileBlock
const&)
129 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::openFile(const FileBlock&)");
136 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::closeFile()");
141 respondToCloseInputFile(FileBlock
const&)
143 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::"
144 "respondToCloseOutputFiles(FileBlock const&)");
149 respondToCloseOutputFiles(FileBlock
const&)
151 TRACE(5,
"RootMPIOutput: Begin/End: RootMPIOutput::"
152 "respondToCloseOutputFiles(FileBlock const&)");
157 send_shutdown_message()
164 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput static send_shutdown_message()");
168 TBufferFile msg(TBuffer::kWrite);
174 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_shutdown_message: "
175 "streaming shutdown message type code ...");
177 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_shutdown_message: "
178 "finished streaming shutdown message type code.");
185 art::ServiceHandle<NetMonTransportService> transport;
186 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_shutdown_message: "
187 "sending the shutdown message ...");
188 transport->sendMessage(0, artdaq::Fragment::ShutdownFragmentType, msg);
189 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_shutdown_message: sent the shutdown message.");
191 TRACE(5,
"RootMPIOutput: End: RootMPIOutput static send_shutdown_message()");
199 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::endJob()");
200 send_shutdown_message();
201 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::endJob()");
210 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput static send_init_message()");
220 static TClass* product_list_class = TClass::GetClass(
221 "std::map<art::BranchKey,art::BranchDescription>");
222 if (product_list_class ==
nullptr)
224 throw art::Exception(art::errors::DictionaryNotFound) <<
225 "RootMPIOutput static send_init_message(): "
226 "Could not get TClass for "
227 "map<art::BranchKey,art::BranchDescription>!";
233 static TClass* process_history_map_class = TClass::GetClass(
234 "std::map<const art::Hash<2>,art::ProcessHistory>");
235 if (process_history_map_class ==
nullptr)
237 throw art::Exception(art::errors::DictionaryNotFound) <<
238 "RootMPIOutput static send_init_message(): "
239 "Could not get class for "
240 "std::map<const art::Hash<2>,art::ProcessHistory>!";
245 static TClass* parentage_map_class = TClass::GetClass(
246 "std::map<const art::Hash<5>,art::Parentage>");
247 if (parentage_map_class ==
nullptr)
249 throw art::Exception(art::errors::DictionaryNotFound) <<
250 "RootMPIOutput static send_init_message(): "
251 "Could not get class for "
252 "std::map<const art::Hash<5>,art::Parentage>!";
257 TBufferFile msg(TBuffer::kWrite);
263 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
264 "Streaming message type code ...");
266 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
267 "Finished streaming message type code.");
273 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
274 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): parameter set count: " + std::to_string(ps_cnt));
275 msg.WriteULong(ps_cnt);
276 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Streaming parameter sets ...");
277 for (
auto I = fhicl::ParameterSetRegistry::begin(),
278 E = fhicl::ParameterSetRegistry::end(); I != E; ++I)
280 std::string pset_str = I->second.to_string();
282 msg.WriteStdString(pset_str);
284 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming parameter sets.");
290 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Streaming MasterProductRegistry ...");
291 art::ProductList productList(
292 art::ProductMetaData::instance().productList());
293 msg.WriteObjectAny(&productList, product_list_class);
294 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming MasterProductRegistry.");
299 if (art::debugit() >= 2)
304 art::BranchIDLists* bilr =
305 &art::BranchIDListRegistry::instance()->data();
306 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
307 "Content of BranchIDLists\n";
308 int max_bli = bilr->size();
309 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
310 "max_bli: " << max_bli <<
'\n';
311 for (
int i = 0; i < max_bli; ++i)
313 int max_prdidx = (*bilr)[i].size();
314 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
315 "max_prdidx: " << max_prdidx <<
'\n';
316 for (
int j = 0; j < max_prdidx; ++j)
318 FDEBUG(2) <<
"RootMPIOutput static send_init_message(): "
321 <<
" bid: 0x" << std::hex
322 <<
static_cast<unsigned long>((*bilr)[i][j])
330 if (art::debugit() >= 1)
332 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
333 "Dumping ProcessHistoryRegistry ...");
336 art::ProcessHistoryMap
const& phr = art::ProcessHistoryRegistry::get();
337 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
338 "phr: size: " + std::to_string(phr.size()));
339 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
341 std::ostringstream OS;
343 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
344 "phr: id: '" + OS.str() +
"'");
351 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
352 "Streaming ProcessHistoryRegistry ...");
355 const art::ProcessHistoryMap& phm = art::ProcessHistoryRegistry::get();
356 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
357 "phm: size: " + std::to_string(phm.size()));
358 msg.WriteObjectAny(&phm, process_history_map_class);
359 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
360 "Finished streaming ProcessHistoryRegistry.");
366 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
367 "Streaming ParentageRegistry ...");
369 const art::ParentageMap& parentageMap = art::ParentageRegistry::get();
370 msg.WriteObjectAny(&parentageMap, parentage_map_class);
371 TRACE(5,
"RootMPIOutput: RootMPIOutput static send_init_message(): "
372 "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()))
437 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
438 "Streaming product count: " + std::to_string(prd_cnt));
439 msg.WriteULong(prd_cnt);
440 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
441 "Finished streaming product count.");
453 bkv.reserve(prd_cnt);
455 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
457 if (I->second->productUnavailable() || !selected(I->second->productDescription()))
461 const BranchDescription& bd(I->second->productDescription());
462 bkv.push_back(
new BranchKey(bd));
463 if (art::debugit() >= 2)
465 FDEBUG(2) <<
"RootMPIOutput::writeDataProducts(...): "
466 "Dumping branch key of class: '"
467 << bkv.back()->friendlyClassName_
469 << bkv.back()->moduleLabel_
471 << bkv.back()->productInstanceName_
473 << bkv.back()->processName_
477 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
478 "Streaming branch key of class: '"
479 + bd.producedClassName()
483 + bd.productInstanceName()
487 msg.WriteObjectAny(bkv.back(), branch_key_class);
490 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
491 "Streaming product of class: '"
492 + bd.producedClassName()
496 + bd.productInstanceName()
500 OutputHandle oh = principal.getForOutput(bd.branchID(),
true);
501 const EDProduct* prd = oh.wrapper();
502 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
505 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
506 "Streaming product provenance of class: '"
507 + bd.producedClassName()
511 + bd.productInstanceName()
515 const ProductProvenance* prdprov =
516 I->second->productProvenancePtr().get();
517 msg.WriteObjectAny(prdprov, prdprov_class);
520 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::writeDataProducts(...)");
525 write(CONST_WRITE EventPrincipal& ep)
530 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::"
531 "write(const EventPrincipal& ep)");
540 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
541 if (run_aux_class ==
nullptr)
543 throw art::Exception(art::errors::DictionaryNotFound) <<
544 "RootMPIOutput::write(const EventPrincipal& ep): "
545 "Could not get TClass for art::RunAuxiliary!";
547 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
548 if (subrun_aux_class ==
nullptr)
550 throw art::Exception(art::errors::DictionaryNotFound) <<
551 "RootMPIOutput::write(const EventPrincipal& ep): "
552 "Could not get TClass for art::SubRunAuxiliary!";
554 static TClass* event_aux_class = TClass::GetClass(
"art::EventAuxiliary");
555 if (event_aux_class ==
nullptr)
557 throw art::Exception(art::errors::DictionaryNotFound) <<
558 "RootMPIOutput::write(const EventPrincipal& ep): "
559 "Could not get TClass for art::EventAuxiliary!";
561 static TClass* history_class = TClass::GetClass(
"art::History");
562 if (history_class ==
nullptr)
564 throw art::Exception(art::errors::DictionaryNotFound) <<
565 "RootMPIOutput::write(const EventPrincipal& ep): "
566 "Could not get TClass for art::History!";
571 TBufferFile msg(TBuffer::kWrite);
577 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
578 "Streaming message type code ...");
580 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
581 "Finished streaming message type code.");
587 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
588 "Streaming RunAuxiliary ...");
589 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
591 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
592 "Finished streaming RunAuxiliary.");
598 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
599 "Streaming SubRunAuxiliary ...");
600 msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
602 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
603 "Finished streaming SubRunAuxiliary.");
609 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
610 "Streaming EventAuxiliary ...");
611 msg.WriteObjectAny(&ep.aux(), event_aux_class);
612 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
613 "Finished streaming EventAuxiliary.");
619 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
620 "Streaming History ...");
621 msg.WriteObjectAny(&ep.history(), history_class);
622 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
623 "Finished streaming History.");
628 std::vector<BranchKey*> bkv;
629 writeDataProducts(msg, ep, bkv);
634 ServiceHandle<NetMonTransportService> transport;
635 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
636 "Sending a message ...");
637 transport->sendMessage(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
638 TRACE(5,
"RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
644 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
649 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::write(const EventPrincipal& ep)");
654 writeRun(CONST_WRITE RunPrincipal& rp)
659 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::writeRun(const RunPrincipal& rp)");
671 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
672 assert(run_aux_class !=
nullptr &&
"writeRun: Could not get TClass for "
673 "art::RunAuxiliary!");
677 TBufferFile msg(TBuffer::kWrite);
683 TRACE(5,
"RootMPIOutput: writeRun: streaming message type code ...");
685 TRACE(5,
"RootMPIOutput: writeRun: finished streaming message type code.");
691 TRACE(5,
"RootMPIOutput: writeRun: streaming RunAuxiliary ...");
692 if (art::debugit() >= 1) {
693 TRACE(5,
"RootMPIOutput: writeRun: dumping ProcessHistoryRegistry ...");
696 art::ProcessHistoryMap
const& phr =
697 art::ProcessHistoryRegistry::get();
698 TRACE(5,
"RootMPIOutput: writeRun: phr: size: " << phr.size() <<
'\n';
699 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I) {
700 std::ostringstream OS;
702 TRACE(5,
"RootMPIOutput: writeRun: phr: id: '" << OS.str() <<
"'");
704 TRACE(5,
"RootMPIOutput: writeRun: phr: data.size(): "
705 << I->second.data().size() <<
'\n';
706 if (I->second.data().size()) {
707 I->second.data().back().id().print(OS);
708 TRACE(5,
"RootMPIOutput: writeRun: phr: data.back().id(): '"
712 if (!rp.aux().processHistoryID().isValid()) {
713 TRACE(5,
"RootMPIOutput: writeRun: ProcessHistoryID: 'INVALID'");
716 std::ostringstream OS;
717 rp.aux().processHistoryID().print(OS);
718 TRACE(5,
"RootMPIOutput: writeRun: ProcessHistoryID: '"
721 const ProcessHistory& processHistory =
722 ProcessHistoryRegistry::get(rp.aux().processHistoryID());
723 if (processHistory.data().size()) {
725 processHistory.data().back().id().print(OS);
726 TRACE(5,
"RootMPIOutput: writeRun: ProcessConfigurationID: '"
729 TRACE(5,
"RootMPIOutput: writeRun: ProcessConfiguration: '"
730 << processHistory.data().back() <<
'\n';
734 msg.WriteObjectAny(&rp.aux(), run_aux_class);
735 TRACE(5,
"RootMPIOutput: writeRun: streamed RunAuxiliary.");
740 std::vector<BranchKey*> bkv;
741 writeDataProducts(msg, rp, bkv);
746 ServiceHandle<NetMonTransportService> transport;
747 TRACE(5,
"RootMPIOutput: writeRun: sending a message ...");
748 transport->sendMessage(0, artdaq::Fragment::EndOfRunFragmentType, msg);
749 TRACE(5,
"RootMPIOutput: writeRun: message sent.");
754 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I) {
759 TRACE(5,
"RootMPIOutput: End: RootMPIOutput::writeRun(const RunPrincipal& rp)");
763 art::RootMPIOutput::writeSubRun(CONST_WRITE SubRunPrincipal& srp)
768 TRACE(5,
"RootMPIOutput: Begin: RootMPIOutput::"
769 "writeSubRun(const SubRunPrincipal& srp)");
779 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
780 if (subrun_aux_class ==
nullptr)
782 throw art::Exception(art::errors::DictionaryNotFound) <<
783 "RootMPIOutput::writeSubRun: "
784 "Could not get TClass for art::SubRunAuxiliary!";
789 TBufferFile msg(TBuffer::kWrite);
795 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
796 "streaming message type code ...");
798 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
799 "finished streaming message type code.");
805 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
806 "streaming SubRunAuxiliary ...");
807 if (art::debugit() >= 1)
809 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
810 "dumping ProcessHistoryRegistry ...");
813 art::ProcessHistoryMap
const& phr =
814 art::ProcessHistoryRegistry::get();
815 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
816 "phr: size: " + std::to_string(phr.size()));
817 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
819 std::ostringstream OS;
821 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
822 "phr: id: '" + OS.str() +
"'");
824 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
826 + std::to_string(I->second.data().size()));
827 if (I->second.data().size())
829 I->second.data().back().id().print(OS);
830 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
831 "phr: data.back().id(): '"
835 if (!srp.aux().processHistoryID().isValid())
837 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
838 "ProcessHistoryID: 'INVALID'");
842 std::ostringstream OS;
843 srp.aux().processHistoryID().print(OS);
844 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: ProcessHistoryID: '"
847 const ProcessHistory& processHistory =
848 ProcessHistoryRegistry::get(srp.aux().processHistoryID());
849 if (processHistory.data().size())
852 processHistory.data().back().id().print(OS);
853 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
854 "ProcessConfigurationID: '"
857 OS << processHistory.data().back();
858 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
859 "ProcessConfiguration: '"
864 msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
865 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: streamed SubRunAuxiliary.");
870 std::vector<BranchKey*> bkv;
871 writeDataProducts(msg, srp, bkv);
876 ServiceHandle<NetMonTransportService> transport;
877 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
878 "Sending the EndOfSubrun message to "
879 + std::to_string(transport->dataReceiverCount())
880 +
" data receivers ...");
881 for (
size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
883 transport->sendMessage(idx, artdaq::Fragment::EndOfSubrunFragmentType, msg);
885 TRACE(5,
"RootMPIOutput: RootMPIOutput::writeSubRun: "
886 "EndOfSubrun message(s) sent.");
890 transport->disconnect();
895 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
900 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...