1 #include "artdaq/ArtModules/RootNetOutput.hh"
3 #include "art/Framework/Core/ModuleMacros.h"
4 #include "art/Framework/Services/Registry/ServiceHandle.h"
5 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
6 #include "art/Persistency/Provenance/ProductMetaData.h"
8 #include "canvas/Persistency/Provenance/BranchDescription.h"
9 #include "canvas/Persistency/Provenance/BranchKey.h"
10 #include "canvas/Persistency/Provenance/History.h"
11 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
12 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
13 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
14 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
15 #include "canvas/Persistency/Provenance/ProductList.h"
16 #include "canvas/Persistency/Provenance/ProductProvenance.h"
17 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
18 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
19 #include "canvas/Utilities/DebugMacros.h"
20 #include "canvas/Utilities/Exception.h"
21 #include "cetlib/column_width.h"
22 #include "cetlib/lpad.h"
23 #include "cetlib/rpad.h"
26 #include "fhiclcpp/ParameterSet.h"
27 #include "fhiclcpp/ParameterSetID.h"
28 #include "fhiclcpp/ParameterSetRegistry.h"
30 #define TRACE_NAME (app_name + "_RootNetOutput").c_str()
32 #define TLVL_OPENFILE 5
33 #define TLVL_CLOSEFILE 6
34 #define TLVL_RESPONDTOCLOSEINPUTFILE 7
35 #define TLVL_RESPONDTOCLOSEOUTPUTFILE 8
37 #define TLVL_SENDINIT 10
38 #define TLVL_SENDINIT_VERBOSE1 32
39 #define TLVL_SENDINIT_VERBOSE2 33
40 #define TLVL_WRITEDATAPRODUCTS 11
41 #define TLVL_WRITEDATAPRODUCTS_VERBOSE 34
43 #define TLVL_WRITERUN 13
44 #define TLVL_WRITESUBRUN 14
45 #define TLVL_WRITESUBRUN_VERBOSE 35
48 #include "artdaq/DAQdata/Globals.hh"
49 #include "artdaq/ArtModules/NetMonTransportService.h"
50 #include "artdaq-core/Data/detail/ParentageMap.hh"
51 #include "artdaq/DAQdata/NetMonHeader.hh"
63 #include <TBufferFile.h>
70 TLOG(TLVL_DEBUG) <<
"Begin: RootNetOutput::RootNetOutput(ParameterSet const& ps)";
71 ServiceHandle<NetMonTransportService> transport;
73 TLOG(TLVL_DEBUG) <<
"End: RootNetOutput::RootNetOutput(ParameterSet const& ps)";
79 TLOG(TLVL_DEBUG) <<
"Begin: RootNetOutput::~RootNetOutput()";
80 ServiceHandle<NetMonTransportService> transport;
81 transport->disconnect();
82 TLOG(TLVL_DEBUG) <<
"End: RootNetOutput::~RootNetOutput()";
87 openFile(FileBlock
const&)
89 TLOG(TLVL_OPENFILE) <<
"Begin/End: RootNetOutput::openFile(const FileBlock&)";
96 TLOG(TLVL_CLOSEFILE) <<
"Begin/End: RootNetOutput::closeFile()";
101 respondToCloseInputFile(FileBlock
const&)
103 TLOG(TLVL_RESPONDTOCLOSEINPUTFILE) <<
"Begin/End: RootNetOutput::"
104 "respondToCloseOutputFiles(FileBlock const&)";
109 respondToCloseOutputFiles(FileBlock
const&)
111 TLOG(TLVL_RESPONDTOCLOSEOUTPUTFILE) <<
"Begin/End: RootNetOutput::"
112 "respondToCloseOutputFiles(FileBlock const&)";
117 send_shutdown_message()
129 TLOG(TLVL_ENDJOB) <<
"Begin: RootNetOutput::endJob()";
130 send_shutdown_message();
131 TLOG(TLVL_ENDJOB) <<
"End: RootNetOutput::endJob()";
140 TLOG(TLVL_SENDINIT) <<
"Begin: RootNetOutput static send_init_message()";
150 static TClass* product_list_class = TClass::GetClass(
151 "std::map<art::BranchKey,art::BranchDescription>");
152 if (product_list_class ==
nullptr)
154 throw art::Exception(art::errors::DictionaryNotFound) <<
155 "RootNetOutput static send_init_message(): "
156 "Could not get TClass for "
157 "map<art::BranchKey,art::BranchDescription>!";
163 static TClass* process_history_map_class = TClass::GetClass(
164 "std::map<const art::Hash<2>,art::ProcessHistory>");
165 if (process_history_map_class ==
nullptr)
167 throw art::Exception(art::errors::DictionaryNotFound) <<
168 "RootNetOutput static send_init_message(): "
169 "Could not get class for "
170 "std::map<const art::Hash<2>,art::ProcessHistory>!";
175 static TClass* parentage_map_class = TClass::GetClass(
"art::ParentageMap");
176 if (parentage_map_class ==
nullptr)
178 throw art::Exception(art::errors::DictionaryNotFound) <<
179 "RootNetOutput static send_init_message(): "
180 "Could not get class for ParentageMap.";
182 TLOG(TLVL_SENDINIT) <<
"parentage_map_class: " << (
void*)parentage_map_class;
187 TBufferFile msg(TBuffer::kWrite);
192 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Streaming message type code ...";
194 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Finished streaming message type code.";
199 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
200 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): parameter set count: " + std::to_string(ps_cnt);
201 msg.WriteULong(ps_cnt);
202 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Streaming parameter sets ...";
204 auto I = std::begin(fhicl::ParameterSetRegistry::get()),
205 E = std::end(fhicl::ParameterSetRegistry::get());
208 std::string pset_str = I->second.to_string();
210 msg.WriteStdString(pset_str);
212 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Finished streaming parameter sets.";
217 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Streaming MasterProductRegistry ...";
218 art::ProductList productList(
219 art::ProductMetaData::instance().productList());
220 msg.WriteObjectAny(&productList, product_list_class);
221 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Finished streaming MasterProductRegistry.";
223 art::ProcessHistoryMap phr;
224 for (
auto const& pr : art::ProcessHistoryRegistry::get())
231 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"RootNetOutput static send_init_message(): Dumping ProcessHistoryRegistry ...";
234 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"RootNetOutput static send_init_message(): phr: size: " << phr.size();
235 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
237 std::ostringstream OS;
239 TLOG(TLVL_SENDINIT_VERBOSE2) <<
"RootNetOutput static send_init_message(): phr: id: '" << OS.str() <<
"'";
244 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Streaming ProcessHistoryRegistry ...";
247 const art::ProcessHistoryMap& phm = phr;
248 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): phm: size: " << phm.size();
249 msg.WriteObjectAny(&phm, process_history_map_class);
250 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Finished streaming ProcessHistoryRegistry.";
255 TLOG(TLVL_SENDINIT) <<
"static send_init_message(): Streaming ParentageRegistry ..."
256 << (
void*)parentage_map_class;
257 art::ParentageMap parentageMap{};
258 for (
auto const& pr : art::ParentageRegistry::get())
260 parentageMap.emplace(pr.first, pr.second);
263 msg.WriteObjectAny(&parentageMap, parentage_map_class);
265 TLOG(TLVL_SENDINIT) <<
"static send_init_message(): Finished streaming ParentageRegistry.";
271 art::ServiceHandle<NetMonTransportService> transport;
272 if (!transport.get())
274 TLOG(TLVL_ERROR) <<
"Could not get handle to NetMonTransportService!";
277 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Sending the init message to " << transport->dataReceiverCount() <<
" data receivers ...";
278 for (
size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
280 transport->sendMessage(idx, artdaq::Fragment::InitFragmentType, msg);
282 TLOG(TLVL_SENDINIT) <<
"RootNetOutput static send_init_message(): Init message(s) sent.";
284 TLOG(TLVL_SENDINIT) <<
"End: RootNetOutput static send_init_message()";
291 writeDataProducts(TBufferFile& msg,
const Principal& principal,
292 std::vector<BranchKey*>& bkv)
294 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"Begin: RootNetOutput::writeDataProducts(...)";
299 static TClass* branch_key_class = TClass::GetClass(
"art::BranchKey");
300 if (branch_key_class ==
nullptr)
302 throw art::Exception(art::errors::DictionaryNotFound) <<
303 "RootNetOutput::writeDataProducts(...): "
304 "Could not get TClass for art::BranchKey!";
306 static TClass* prdprov_class = TClass::GetClass(
"art::ProductProvenance");
307 if (prdprov_class ==
nullptr)
309 throw art::Exception(art::errors::DictionaryNotFound) <<
310 "RootNetOutput::writeDataProducts(...): "
311 "Could not get TClass for art::ProductProvenance!";
317 unsigned long prd_cnt = 0;
319 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
321 auto const& productDescription = I->second->productDescription();
322 auto const& refs = keptProducts()[productDescription.branchType()];
324 for (
auto const& ref : refs)
326 if (*ref == productDescription)
332 if (I->second->productUnavailable() || !found)
341 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"RootNetOutput::writeDataProducts(...): Streaming product count: " + std::to_string(prd_cnt);
342 msg.WriteULong(prd_cnt);
343 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"RootNetOutput::writeDataProducts(...): Finished streaming product count.";
355 bkv.reserve(prd_cnt);
357 for (
auto I = principal.begin(), E = principal.end(); I != E; ++I)
359 auto const& productDescription = I->second->productDescription();
360 auto const& refs = keptProducts()[productDescription.branchType()];
362 for (
auto const& ref : refs)
364 if (*ref == productDescription)
370 if (I->second->productUnavailable() || !found)
374 const BranchDescription& bd(I->second->productDescription());
375 bkv.push_back(
new BranchKey(bd));
376 TLOG(TLVL_WRITEDATAPRODUCTS_VERBOSE) <<
"RootNetOutput::writeDataProducts(...): Dumping branch key of class: '"
377 << bkv.back()->friendlyClassName_
379 << bkv.back()->moduleLabel_
381 << bkv.back()->productInstanceName_
383 << bkv.back()->processName_
385 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"RootNetOutput::writeDataProducts(...): "
386 "Streaming branch key of class: '"
387 << bd.producedClassName()
391 << bd.productInstanceName()
395 msg.WriteObjectAny(bkv.back(), branch_key_class);
396 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"RootNetOutput::writeDataProducts(...): "
397 "Streaming product of class: '"
398 << bd.producedClassName()
402 << bd.productInstanceName()
407 OutputHandle oh = principal.getForOutput(bd.productID(),
true);
408 const EDProduct* prd = oh.wrapper();
409 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"Class for branch " << bd.wrappedName() <<
" is " << (
void*)TClass::GetClass(bd.wrappedName().c_str());
410 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
411 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"RootNetOutput::writeDataProducts(...): "
412 "Streaming product provenance of class: '"
413 << bd.producedClassName()
417 << bd.productInstanceName()
421 const ProductProvenance* prdprov = I->second->productProvenancePtr().get();
422 msg.WriteObjectAny(prdprov, prdprov_class);
424 TLOG(TLVL_WRITEDATAPRODUCTS) <<
"End: RootNetOutput::writeDataProducts(...)";
429 write(EventPrincipal& ep)
434 TLOG(TLVL_WRITE) <<
"Begin: RootNetOutput::write(const EventPrincipal& ep)";
443 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
444 if (run_aux_class ==
nullptr)
446 throw art::Exception(art::errors::DictionaryNotFound) <<
447 "RootNetOutput::write(const EventPrincipal& ep): "
448 "Could not get TClass for art::RunAuxiliary!";
450 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
451 if (subrun_aux_class ==
nullptr)
453 throw art::Exception(art::errors::DictionaryNotFound) <<
454 "RootNetOutput::write(const EventPrincipal& ep): "
455 "Could not get TClass for art::SubRunAuxiliary!";
457 static TClass* event_aux_class = TClass::GetClass(
"art::EventAuxiliary");
458 if (event_aux_class ==
nullptr)
460 throw art::Exception(art::errors::DictionaryNotFound) <<
461 "RootNetOutput::write(const EventPrincipal& ep): "
462 "Could not get TClass for art::EventAuxiliary!";
464 static TClass* history_class = TClass::GetClass(
"art::History");
465 if (history_class ==
nullptr)
467 throw art::Exception(art::errors::DictionaryNotFound) <<
468 "RootNetOutput::write(const EventPrincipal& ep): "
469 "Could not get TClass for art::History!";
474 TBufferFile msg(TBuffer::kWrite);
479 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Streaming message type code ...";
481 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Finished streaming message type code.";
486 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Streaming RunAuxiliary ...";
487 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
489 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Finished streaming RunAuxiliary.";
494 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Streaming SubRunAuxiliary ...";
495 msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
497 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Finished streaming SubRunAuxiliary.";
503 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Streaming EventAuxiliary ...";
504 msg.WriteObjectAny(&ep.aux(), event_aux_class);
505 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Finished streaming EventAuxiliary.";
511 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Streaming History ...";
512 msg.WriteObjectAny(&ep.history(), history_class);
513 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Finished streaming History.";
518 std::vector<BranchKey*> bkv;
519 writeDataProducts(msg, ep, bkv);
524 ServiceHandle<NetMonTransportService> transport;
525 if (!transport.get())
527 TLOG(TLVL_ERROR) <<
"Could not get handle to NetMonTransportService!";
530 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Sending a message ...";
531 transport->sendMessage(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
532 TLOG(TLVL_WRITE) <<
"RootNetOutput::write(const EventPrincipal& ep): Message sent.";
537 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
542 TLOG(TLVL_WRITE) <<
"End: RootNetOutput::write(const EventPrincipal& ep)";
547 writeRun(RunPrincipal& rp)
552 TLOG(TLVL_WRITERUN) <<
"Begin: RootNetOutput::writeRun(const RunPrincipal& rp)";
564 static TClass* run_aux_class = TClass::GetClass(
"art::RunAuxiliary");
565 assert(run_aux_class !=
nullptr &&
"writeRun: Could not get TClass for art::RunAuxiliary!");
569 TBufferFile msg(TBuffer::kWrite);
575 TLOG(TLVL_WRITERUN) <<
"writeRun: streaming message type code ...";
577 TLOG(TLVL_WRITERUN) <<
"writeRun: finished streaming message type code.";
583 TLOG(TLVL_WRITERUN) <<
"writeRun: streaming RunAuxiliary ...";
584 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: dumping ProcessHistoryRegistry ...";
587 art::ProcessHistoryMap
const& phr =
588 art::ProcessHistoryRegistry::get();
589 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: phr: size: " << phr.size();
590 for (
auto I = phr.begin(), E = phr.end(); I != E; ++I)
592 std::ostringstream OS;
594 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: phr: id: '" << OS.str() <<
"'";
596 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: phr: data.size(): " << I->second.data().size();
597 if (I->second.data().size())
599 I->second.data().back().id().print(OS);
600 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: phr: data.back().id(): '" << OS.str() <<
"'";
603 if (!rp.aux().processHistoryID().isValid())
605 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: ProcessHistoryID: 'INVALID'";
609 std::ostringstream OS;
610 rp.aux().processHistoryID().print(OS);
611 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: ProcessHistoryID: '" << OS.str() <<
"'";
613 const ProcessHistory& processHistory =
614 ProcessHistoryRegistry::get(rp.aux().processHistoryID());
615 if (processHistory.data().size())
618 processHistory.data().back().id().print(OS);
619 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: ProcessConfigurationID: '" << OS.str() <<
"'";
621 TLOG(TLVL_WRITERUN_VERBOSE) <<
"writeRun: ProcessConfiguration: '" << processHistory.data().back();
624 msg.WriteObjectAny(&rp.aux(), run_aux_class);
625 TLOG(TLVL_WRITERUN) <<
"writeRun: streamed RunAuxiliary.";
630 std::vector<BranchKey*> bkv;
631 writeDataProducts(msg, rp, bkv);
636 ServiceHandle<NetMonTransportService> transport;
637 if (!transport.get())
639 TLOG(TLVL_ERROR) <<
"Could not get handle to NetMonTransportService!";
642 TLOG(TLVL_WRITERUN) <<
"writeRun: sending a message ...";
643 transport->sendMessage(0, artdaq::Fragment::EndOfRunFragmentType, msg);
644 TLOG(TLVL_WRITERUN) <<
"writeRun: message sent.";
649 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
655 TLOG(TLVL_WRITERUN) <<
"End: RootNetOutput::writeRun(const RunPrincipal& rp)";
659 art::RootNetOutput::writeSubRun(SubRunPrincipal& srp)
664 TLOG(TLVL_WRITESUBRUN) <<
"Begin: RootNetOutput::writeSubRun(const SubRunPrincipal& srp)";
674 static TClass* subrun_aux_class = TClass::GetClass(
"art::SubRunAuxiliary");
675 if (subrun_aux_class ==
nullptr)
677 throw art::Exception(art::errors::DictionaryNotFound) <<
678 "RootNetOutput::writeSubRun: "
679 "Could not get TClass for art::SubRunAuxiliary!";
684 TBufferFile msg(TBuffer::kWrite);
690 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: streaming message type code ...";
692 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: finished streaming message type code.";
698 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: streaming SubRunAuxiliary ...";
700 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: dumping ProcessHistoryRegistry ...";
703 for (
auto I = std::begin(art::ProcessHistoryRegistry::get())
704 , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I)
706 std::ostringstream OS;
708 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: phr: id: '" << OS.str() <<
"'";
710 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: phr: data.size(): " << I->second.data().size();
711 if (I->second.data().size())
713 I->second.data().back().id().print(OS);
714 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: phr: data.back().id(): '" << OS.str() <<
"'";
717 if (!srp.aux().processHistoryID().isValid())
719 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: ProcessHistoryID: 'INVALID'";
723 std::ostringstream OS;
724 srp.aux().processHistoryID().print(OS);
725 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: ProcessHistoryID: '" << OS.str() <<
"'";
727 ProcessHistory processHistory;
728 ProcessHistoryRegistry::get(srp.aux().processHistoryID(), processHistory);
729 if (processHistory.data().size())
732 processHistory.data().back().id().print(OS);
733 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: ProcessConfigurationID: '" << OS.str() <<
"'";
735 OS << processHistory.data().back();
736 TLOG(TLVL_WRITESUBRUN_VERBOSE) <<
"RootNetOutput::writeSubRun: ProcessConfiguration: '" << OS.str();
739 msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
740 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: streamed SubRunAuxiliary.";
745 std::vector<BranchKey*> bkv;
746 writeDataProducts(msg, srp, bkv);
750 ServiceHandle<NetMonTransportService> transport;
751 if (!transport.get())
753 TLOG(TLVL_ERROR) <<
"Could not get handle to NetMonTransportService!";
756 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: Sending the EndOfSubrun message";
757 transport->sendMessage(0, artdaq::Fragment::EndOfSubrunFragmentType, msg);
758 TLOG(TLVL_WRITESUBRUN) <<
"RootNetOutput::writeSubRun: EndOfSubrun message sent.";
767 for (
auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
772 TLOG(TLVL_WRITESUBRUN) <<
"End: RootNetOutput::writeSubRun(const SubRunPrincipal& srp)";
~RootNetOutput()
RootNetOutput Destructor.
An art::OutputModule which sends events using DataSenderManager. This module is designed for transpor...
RootNetOutput(fhicl::ParameterSet const &ps)
RootNetOutput Constructor.