00001 #include "art/Framework/Core/ModuleMacros.h"
00002 #include "art/Framework/Core/OutputModule.h"
00003 #include "art/Framework/Principal/EventPrincipal.h"
00004 #include "art/Framework/Principal/OutputHandle.h"
00005 #include "art/Framework/Principal/RunPrincipal.h"
00006 #include "art/Framework/Principal/SubRunPrincipal.h"
00007 #include "art/Framework/Services/Registry/ServiceHandle.h"
00008 #if ART_HEX_VERSION >= 0x20703
00009 # include <iterator>
00010 #else
00011 # include "art/Persistency/Provenance/BranchIDListHelper.h"
00012 #endif
00013 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
00014 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
00015 #include "art/Persistency/Provenance/ProductMetaData.h"
00016
00017 #include "canvas/Persistency/Provenance/BranchDescription.h"
00018 #include "canvas/Persistency/Provenance/BranchIDList.h"
00019 #include "canvas/Persistency/Provenance/BranchKey.h"
00020 #include "canvas/Persistency/Provenance/History.h"
00021 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
00022 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
00023 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
00024 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
00025 #include "canvas/Persistency/Provenance/ProductList.h"
00026 #include "canvas/Persistency/Provenance/ProductProvenance.h"
00027 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
00028 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
00029 #include "canvas/Utilities/DebugMacros.h"
00030 #include "canvas/Utilities/Exception.h"
00031 #include "cetlib/column_width.h"
00032 #include "cetlib/lpad.h"
00033 #include "cetlib/rpad.h"
00034 #include <algorithm>
00035 #include "fhiclcpp/ParameterSet.h"
00036 #include "fhiclcpp/ParameterSetID.h"
00037 #include "fhiclcpp/ParameterSetRegistry.h"
00038
00039 #include "artdaq/ArtModules/NetMonTransportService.h"
00040 #include "artdaq/ArtModules/detail/ParentageMap.hh"
00041 #include "artdaq/DAQdata/Globals.hh"
00042 #include "artdaq/DAQdata/NetMonHeader.hh"
00043
00044 #include <iomanip>
00045 #include <iostream>
00046 #include <sstream>
00047 #include <string>
00048 #include <vector>
00049
00050 #include <unistd.h>
00051
00052 #include <TClass.h>
00053 #include <TMessage.h>
00054
00055 #define TRACE_NAME "RootMPIOutput"
00056
00057 # define CONST_WRITE
00058
00059 namespace art
00060 {
00061 class RootMPIOutput;
00062 }
00063
00064
00070 class art::RootMPIOutput : public OutputModule
00071 {
00072 public:
00080 explicit RootMPIOutput(fhicl::ParameterSet const& ps);
00081
00085 ~RootMPIOutput();
00086
00087 private:
00088 virtual void openFile(FileBlock const&);
00089
00090 virtual void closeFile();
00091
00092 virtual void respondToCloseInputFile(FileBlock const&);
00093
00094 virtual void respondToCloseOutputFiles(FileBlock const&);
00095
00096 virtual void endJob();
00097
00098 virtual void write(EventPrincipal CONST_WRITE&);
00099
00100 virtual void writeRun(RunPrincipal CONST_WRITE&);
00101
00102 virtual void writeSubRun(SubRunPrincipal CONST_WRITE&);
00103
00104 void writeDataProducts(TBufferFile&, const Principal&,
00105 std::vector<BranchKey*>&);
00106
00107 private:
00108 bool initMsgSent_;
00109 };
00110
00111 art::RootMPIOutput::
00112 RootMPIOutput(fhicl::ParameterSet const& ps)
00113 : OutputModule(ps)
00114 , initMsgSent_(false)
00115 {
00116 TLOG_DEBUG("RootMPIOutput") << "Begin: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
00117 ServiceHandle<NetMonTransportService> transport;
00118 transport->connect();
00119 TLOG_DEBUG("RootMPIOutput") << "End: RootMPIOutput::RootMPIOutput(ParameterSet const& ps)" << TLOG_ENDL;
00120 }
00121
00122 art::RootMPIOutput::
00123 ~RootMPIOutput()
00124 {
00125 TLOG_DEBUG("RootMPIOutput") << "Begin: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
00126 ServiceHandle<NetMonTransportService> transport;
00127 transport->disconnect();
00128 TLOG_DEBUG("RootMPIOutput") << "End: RootMPIOutput::~RootMPIOutput()" << TLOG_ENDL;
00129 }
00130
00131 void
00132 art::RootMPIOutput::
00133 openFile(FileBlock const&)
00134 {
00135 TRACE(5, "RootMPIOutput: Begin/End: RootMPIOutput::openFile(const FileBlock&)");
00136 }
00137
00138 void
00139 art::RootMPIOutput::
00140 closeFile()
00141 {
00142 TRACE(5, "RootMPIOutput: Begin/End: RootMPIOutput::closeFile()");
00143 }
00144
00145 void
00146 art::RootMPIOutput::
00147 respondToCloseInputFile(FileBlock const&)
00148 {
00149 TRACE(5, "RootMPIOutput: Begin/End: RootMPIOutput::"
00150 "respondToCloseOutputFiles(FileBlock const&)");
00151 }
00152
00153 void
00154 art::RootMPIOutput::
00155 respondToCloseOutputFiles(FileBlock const&)
00156 {
00157 TRACE(5, "RootMPIOutput: Begin/End: RootMPIOutput::"
00158 "respondToCloseOutputFiles(FileBlock const&)");
00159 }
00160
00161 static
00162 void
00163 send_shutdown_message()
00164 {
00165
00166
00167
00168
00169 }
00170
00171 void
00172 art::RootMPIOutput::
00173 endJob()
00174 {
00175 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput::endJob()");
00176 send_shutdown_message();
00177 TRACE(5, "RootMPIOutput: End: RootMPIOutput::endJob()");
00178 }
00179
00180
00181
00182 static
00183 void
00184 send_init_message()
00185 {
00186 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput static send_init_message()");
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 static TClass* product_list_class = TClass::GetClass(
00197 "std::map<art::BranchKey,art::BranchDescription>");
00198 if (product_list_class == nullptr)
00199 {
00200 throw art::Exception(art::errors::DictionaryNotFound) <<
00201 "RootMPIOutput static send_init_message(): "
00202 "Could not get TClass for "
00203 "map<art::BranchKey,art::BranchDescription>!";
00204 }
00205
00206
00207
00208
00209 static TClass* process_history_map_class = TClass::GetClass(
00210 "std::map<const art::Hash<2>,art::ProcessHistory>");
00211 if (process_history_map_class == nullptr)
00212 {
00213 throw art::Exception(art::errors::DictionaryNotFound) <<
00214 "RootMPIOutput static send_init_message(): "
00215 "Could not get class for "
00216 "std::map<const art::Hash<2>,art::ProcessHistory>!";
00217 }
00218
00219
00220
00221 static TClass* parentage_map_class = TClass::GetClass("art::ParentageMap");
00222 if (parentage_map_class == nullptr)
00223 {
00224 throw art::Exception(art::errors::DictionaryNotFound) <<
00225 "RootMPIOutput static send_init_message(): "
00226 "Could not get class for ParentageMap.";
00227 }
00228
00229
00230
00231 TBufferFile msg(TBuffer::kWrite);
00232 msg.SetWriteMode();
00233
00234
00235
00236 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00237 "Streaming message type code ...");
00238 msg.WriteULong(1);
00239 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00240 "Finished streaming message type code.");
00241
00242
00243
00244
00245 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
00246 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): parameter set count: " + std::to_string(ps_cnt));
00247 msg.WriteULong(ps_cnt);
00248 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): Streaming parameter sets ...");
00249 for (
00250 # if ART_HEX_VERSION >= 0x20703
00251 auto I = std::begin(fhicl::ParameterSetRegistry::get()),
00252 E = std::end(fhicl::ParameterSetRegistry::get());
00253 # else
00254 auto I = fhicl::ParameterSetRegistry::begin(),
00255 E = fhicl::ParameterSetRegistry::end();
00256 # endif
00257 I != E; ++I)
00258 {
00259 std::string pset_str = I->second.to_string();
00260
00261 msg.WriteStdString(pset_str);
00262 }
00263 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming parameter sets.");
00264
00265
00266
00267
00268 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): Streaming MasterProductRegistry ...");
00269 art::ProductList productList(
00270 art::ProductMetaData::instance().productList());
00271 msg.WriteObjectAny(&productList, product_list_class);
00272 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): Finished streaming MasterProductRegistry.");
00273
00274
00275
00276
00277 if (art::debugit() >= 2)
00278 {
00279
00280
00281
00282 # if ART_HEX_VERSION >= 0x20703
00283 art::BranchIDLists const * bilr =
00284 &art::BranchIDListRegistry::instance().data();
00285 # else
00286 art::BranchIDLists* bilr =
00287 &art::BranchIDListRegistry::instance()->data();
00288 # endif
00289 FDEBUG(2) << "RootMPIOutput static send_init_message(): "
00290 "Content of BranchIDLists\n";
00291 int max_bli = bilr->size();
00292 FDEBUG(2) << "RootMPIOutput static send_init_message(): "
00293 "max_bli: " << max_bli << '\n';
00294 for (int i = 0; i < max_bli; ++i)
00295 {
00296 int max_prdidx = (*bilr)[i].size();
00297 FDEBUG(2) << "RootMPIOutput static send_init_message(): "
00298 "max_prdidx: " << max_prdidx << '\n';
00299 for (int j = 0; j < max_prdidx; ++j)
00300 {
00301 FDEBUG(2) << "RootMPIOutput static send_init_message(): "
00302 "bli: " << i
00303 << " prdidx: " << j
00304 << " bid: 0x" << std::hex
00305 << static_cast<unsigned long>((*bilr)[i][j])
00306 << std::dec << '\n';
00307 }
00308 }
00309 }
00310
00311 # if ART_HEX_VERSION >= 0x20703
00312 art::ProcessHistoryMap phr;
00313 for (auto const& pr : art::ProcessHistoryRegistry::get()) {
00314 phr.emplace(pr);
00315 }
00316 # endif
00317
00318
00319
00320 if (art::debugit() >= 1)
00321 {
00322 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00323 "Dumping ProcessHistoryRegistry ...");
00324
00325
00326 # if ART_HEX_VERSION < 0x20703
00327 art::ProcessHistoryMap const& phr = art::ProcessHistoryRegistry::get();
00328 # endif
00329 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00330 "phr: size: " + std::to_string(phr.size()));
00331 for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
00332 {
00333 std::ostringstream OS;
00334 I->first.print(OS);
00335 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00336 "phr: id: '" + OS.str() + "'");
00337 }
00338 }
00339
00340
00341
00342 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00343 "Streaming ProcessHistoryRegistry ...");
00344
00345
00346 # if ART_HEX_VERSION >= 0x20703
00347 const art::ProcessHistoryMap& phm = phr;
00348 # else
00349 const art::ProcessHistoryMap& phm = art::ProcessHistoryRegistry::get();
00350 # endif
00351 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00352 "phm: size: " + std::to_string(phm.size()));
00353 msg.WriteObjectAny(&phm, process_history_map_class);
00354 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00355 "Finished streaming ProcessHistoryRegistry.");
00356
00357
00358
00359
00360 TRACE(5, "RootMPIOutput: static send_init_message(): "
00361 "Streaming ParentageRegistry ...");
00362 # if ART_HEX_VERSION >= 0x20703
00363 art::ParentageMap parentageMap{};
00364 for (auto const& pr : art::ParentageRegistry::get()) {
00365 parentageMap.emplace(pr.first, pr.second);
00366 }
00367 # else
00368 const art::ParentageMap& parentageMap = art::ParentageRegistry::get();
00369 # endif
00370
00371 msg.WriteObjectAny(&parentageMap, parentage_map_class);
00372
00373 TRACE(5, "RootMPIOutput: static send_init_message(): Finished streaming ParentageRegistry.");
00374
00375
00376
00377
00378
00379 art::ServiceHandle<NetMonTransportService> transport;
00380 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00381 "Sending the init message to "
00382 + std::to_string(transport->dataReceiverCount()) +
00383 " data receivers ...");
00384 for (size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
00385 {
00386 transport->sendMessage(idx, artdaq::Fragment::InitFragmentType, msg);
00387 }
00388 TRACE(5, "RootMPIOutput: RootMPIOutput static send_init_message(): "
00389 "Init message(s) sent.");
00390
00391 TRACE(5, "RootMPIOutput: End: RootMPIOutput static send_init_message()");
00392 }
00393
00394
00395
00396 void
00397 art::RootMPIOutput::
00398 writeDataProducts(TBufferFile& msg, const Principal& principal,
00399 std::vector<BranchKey*>& bkv)
00400 {
00401 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput::writeDataProducts(...)");
00402
00403
00404
00405
00406 static TClass* branch_key_class = TClass::GetClass("art::BranchKey");
00407 if (branch_key_class == nullptr)
00408 {
00409 throw art::Exception(art::errors::DictionaryNotFound) <<
00410 "RootMPIOutput::writeDataProducts(...): "
00411 "Could not get TClass for art::BranchKey!";
00412 }
00413 static TClass* prdprov_class = TClass::GetClass("art::ProductProvenance");
00414 if (prdprov_class == nullptr)
00415 {
00416 throw art::Exception(art::errors::DictionaryNotFound) <<
00417 "RootMPIOutput::writeDataProducts(...): "
00418 "Could not get TClass for art::ProductProvenance!";
00419 }
00420
00421
00422
00423 unsigned long prd_cnt = 0;
00424
00425 for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
00426 {
00427 if (I->second->productUnavailable() || !selected(I->second->productDescription()))
00428 {
00429 continue;
00430 }
00431 ++prd_cnt;
00432 }
00433
00434
00435
00436 TRACE(5, "RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
00437 "Streaming product count: " + std::to_string(prd_cnt));
00438 msg.WriteULong(prd_cnt);
00439 TRACE(5, "RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
00440 "Finished streaming product count.");
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 bkv.reserve(prd_cnt);
00453
00454 for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
00455 {
00456 if (I->second->productUnavailable() || !selected(I->second->productDescription()))
00457 {
00458 continue;
00459 }
00460 const BranchDescription& bd(I->second->productDescription());
00461 bkv.push_back(new BranchKey(bd));
00462 if (art::debugit() >= 2)
00463 {
00464 FDEBUG(2) << "RootMPIOutput::writeDataProducts(...): "
00465 "Dumping branch key of class: '"
00466 << bkv.back()->friendlyClassName_
00467 << "' modlbl: '"
00468 << bkv.back()->moduleLabel_
00469 << "' instnm: '"
00470 << bkv.back()->productInstanceName_
00471 << "' procnm: '"
00472 << bkv.back()->processName_
00473 << "'";
00474 }
00475 TRACE(5, "RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
00476 "Streaming branch key of class: '"
00477 + bd.producedClassName()
00478 + "' modlbl: '"
00479 + bd.moduleLabel()
00480 + "' instnm: '"
00481 + bd.productInstanceName()
00482 + "' procnm: '"
00483 + bd.processName()
00484 + "'");
00485 msg.WriteObjectAny(bkv.back(), branch_key_class);
00486 TRACE(5, "RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
00487 "Streaming product of class: '"
00488 + bd.producedClassName()
00489 + "' modlbl: '"
00490 + bd.moduleLabel()
00491 + "' instnm: '"
00492 + bd.productInstanceName()
00493 + "' procnm: '"
00494 + bd.processName()
00495 + "'");
00496 OutputHandle oh = principal.getForOutput(bd.branchID(), true);
00497 const EDProduct* prd = oh.wrapper();
00498 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
00499 TRACE(5, "RootMPIOutput: RootMPIOutput::writeDataProducts(...): "
00500 "Streaming product provenance of class: '"
00501 + bd.producedClassName()
00502 + "' modlbl: '"
00503 + bd.moduleLabel()
00504 + "' instnm: '"
00505 + bd.productInstanceName()
00506 + "' procnm: '"
00507 + bd.processName()
00508 + "'");
00509 const ProductProvenance* prdprov =
00510 I->second->productProvenancePtr().get();
00511 msg.WriteObjectAny(prdprov, prdprov_class);
00512 }
00513 TRACE(5, "RootMPIOutput: End: RootMPIOutput::writeDataProducts(...)");
00514 }
00515
00516 void
00517 art::RootMPIOutput::
00518 write(CONST_WRITE EventPrincipal& ep)
00519 {
00520
00521
00522
00523 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput::"
00524 "write(const EventPrincipal& ep)");
00525 if (!initMsgSent_)
00526 {
00527 send_init_message();
00528 initMsgSent_ = true;
00529 }
00530
00531
00532
00533 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
00534 if (run_aux_class == nullptr)
00535 {
00536 throw art::Exception(art::errors::DictionaryNotFound) <<
00537 "RootMPIOutput::write(const EventPrincipal& ep): "
00538 "Could not get TClass for art::RunAuxiliary!";
00539 }
00540 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
00541 if (subrun_aux_class == nullptr)
00542 {
00543 throw art::Exception(art::errors::DictionaryNotFound) <<
00544 "RootMPIOutput::write(const EventPrincipal& ep): "
00545 "Could not get TClass for art::SubRunAuxiliary!";
00546 }
00547 static TClass* event_aux_class = TClass::GetClass("art::EventAuxiliary");
00548 if (event_aux_class == nullptr)
00549 {
00550 throw art::Exception(art::errors::DictionaryNotFound) <<
00551 "RootMPIOutput::write(const EventPrincipal& ep): "
00552 "Could not get TClass for art::EventAuxiliary!";
00553 }
00554 static TClass* history_class = TClass::GetClass("art::History");
00555 if (history_class == nullptr)
00556 {
00557 throw art::Exception(art::errors::DictionaryNotFound) <<
00558 "RootMPIOutput::write(const EventPrincipal& ep): "
00559 "Could not get TClass for art::History!";
00560 }
00561
00562
00563
00564 TBufferFile msg(TBuffer::kWrite);
00565 msg.SetWriteMode();
00566
00567
00568
00569 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00570 "Streaming message type code ...");
00571 msg.WriteULong(4);
00572 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00573 "Finished streaming message type code.");
00574
00575
00576
00577
00578 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00579 "Streaming RunAuxiliary ...");
00580 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
00581 run_aux_class);
00582 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00583 "Finished streaming RunAuxiliary.");
00584
00585
00586
00587
00588 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00589 "Streaming SubRunAuxiliary ...");
00590 msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
00591 subrun_aux_class);
00592 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00593 "Finished streaming SubRunAuxiliary.");
00594
00595
00596
00597
00598 {
00599 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00600 "Streaming EventAuxiliary ...");
00601 msg.WriteObjectAny(&ep.aux(), event_aux_class);
00602 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00603 "Finished streaming EventAuxiliary.");
00604 }
00605
00606
00607
00608 {
00609 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00610 "Streaming History ...");
00611 msg.WriteObjectAny(&ep.history(), history_class);
00612 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00613 "Finished streaming History.");
00614 }
00615
00616
00617
00618 std::vector<BranchKey*> bkv;
00619 writeDataProducts(msg, ep, bkv);
00620
00621
00622
00623 {
00624 ServiceHandle<NetMonTransportService> transport;
00625 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00626 "Sending a message ...");
00627 transport->sendMessage(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
00628 TRACE(5, "RootMPIOutput: RootMPIOutput::write(const EventPrincipal& ep): "
00629 "Message sent.");
00630 }
00631
00632
00633
00634 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
00635 {
00636 delete *I;
00637 *I = 0;
00638 }
00639 TRACE(5, "RootMPIOutput: End: RootMPIOutput::write(const EventPrincipal& ep)");
00640 }
00641
00642 void
00643 art::RootMPIOutput::
00644 writeRun(CONST_WRITE RunPrincipal& rp)
00645 {
00646
00647
00648
00649 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput::writeRun(const RunPrincipal& rp)");
00650 (void)rp;
00651 if (!initMsgSent_)
00652 {
00653 send_init_message();
00654 initMsgSent_ = true;
00655 }
00656 #if 0
00657
00658
00659
00660
00661 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
00662 assert(run_aux_class != nullptr && "writeRun: Could not get TClass for "
00663 "art::RunAuxiliary!");
00664
00665
00666
00667 TBufferFile msg(TBuffer::kWrite);
00668 msg.SetWriteMode();
00669
00670
00671
00672 {
00673 TRACE(5, "RootMPIOutput: writeRun: streaming message type code ...");
00674 msg.WriteULong(2);
00675 TRACE(5, "RootMPIOutput: writeRun: finished streaming message type code.");
00676 }
00677
00678
00679
00680 {
00681 TRACE(5, "RootMPIOutput: writeRun: streaming RunAuxiliary ...");
00682 if (art::debugit() >= 1) {
00683 TRACE(5, "RootMPIOutput: writeRun: dumping ProcessHistoryRegistry ...");
00684
00685
00686 art::ProcessHistoryMap const& phr =
00687 art::ProcessHistoryRegistry::get();
00688 TRACE(5, "RootMPIOutput: writeRun: phr: size: " << phr.size() << '\n';
00689 for (auto I = phr.begin(), E = phr.end(); I != E; ++I) {
00690 std::ostringstream OS;
00691 I->first.print(OS);
00692 TRACE(5, "RootMPIOutput: writeRun: phr: id: '" << OS.str() << "'");
00693 OS.str("");
00694 TRACE(5, "RootMPIOutput: writeRun: phr: data.size(): "
00695 << I->second.data().size() << '\n';
00696 if (I->second.data().size()) {
00697 I->second.data().back().id().print(OS);
00698 TRACE(5, "RootMPIOutput: writeRun: phr: data.back().id(): '"
00699 << OS.str() << "'");
00700 }
00701 }
00702 if (!rp.aux().processHistoryID().isValid()) {
00703 TRACE(5, "RootMPIOutput: writeRun: ProcessHistoryID: 'INVALID'");
00704 }
00705 else {
00706 std::ostringstream OS;
00707 rp.aux().processHistoryID().print(OS);
00708 TRACE(5, "RootMPIOutput: writeRun: ProcessHistoryID: '"
00709 << OS.str() << "'");
00710 OS.str("");
00711 const ProcessHistory& processHistory =
00712 ProcessHistoryRegistry::get(rp.aux().processHistoryID());
00713 if (processHistory.data().size()) {
00714
00715 processHistory.data().back().id().print(OS);
00716 TRACE(5, "RootMPIOutput: writeRun: ProcessConfigurationID: '"
00717 << OS.str() << "'");
00718 OS.str("");
00719 TRACE(5, "RootMPIOutput: writeRun: ProcessConfiguration: '"
00720 << processHistory.data().back() << '\n';
00721 }
00722 }
00723 }
00724 msg.WriteObjectAny(&rp.aux(), run_aux_class);
00725 TRACE(5, "RootMPIOutput: writeRun: streamed RunAuxiliary.");
00726 }
00727
00728
00729
00730 std::vector<BranchKey*> bkv;
00731 writeDataProducts(msg, rp, bkv);
00732
00733
00734
00735 {
00736 ServiceHandle<NetMonTransportService> transport;
00737 TRACE(5, "RootMPIOutput: writeRun: sending a message ...");
00738 transport->sendMessage(0, artdaq::Fragment::EndOfRunFragmentType, msg);
00739 TRACE(5, "RootMPIOutput: writeRun: message sent.");
00740 }
00741
00742
00743
00744 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I) {
00745 delete *I;
00746 *I = 0;
00747 }
00748 #endif // 0
00749 TRACE(5, "RootMPIOutput: End: RootMPIOutput::writeRun(const RunPrincipal& rp)");
00750 }
00751
00752 void
00753 art::RootMPIOutput::writeSubRun(CONST_WRITE SubRunPrincipal& srp)
00754 {
00755
00756
00757
00758 TRACE(5, "RootMPIOutput: Begin: RootMPIOutput::"
00759 "writeSubRun(const SubRunPrincipal& srp)");
00760 if (!initMsgSent_)
00761 {
00762 send_init_message();
00763 initMsgSent_ = true;
00764 }
00765
00766
00767
00768
00769 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
00770 if (subrun_aux_class == nullptr)
00771 {
00772 throw art::Exception(art::errors::DictionaryNotFound) <<
00773 "RootMPIOutput::writeSubRun: "
00774 "Could not get TClass for art::SubRunAuxiliary!";
00775 }
00776
00777
00778
00779 TBufferFile msg(TBuffer::kWrite);
00780 msg.SetWriteMode();
00781
00782
00783
00784 {
00785 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00786 "streaming message type code ...");
00787 msg.WriteULong(3);
00788 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00789 "finished streaming message type code.");
00790 }
00791
00792
00793
00794 {
00795 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00796 "streaming SubRunAuxiliary ...");
00797 if (art::debugit() >= 1)
00798 {
00799 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00800 "dumping ProcessHistoryRegistry ...");
00801
00802
00803 # if ART_HEX_VERSION >= 0x20703
00804 for (auto I = std::begin(art::ProcessHistoryRegistry::get())
00805 , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I)
00806 # else
00807 art::ProcessHistoryMap const& phr =
00808 art::ProcessHistoryRegistry::get();
00809 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00810 "phr: size: " + std::to_string(phr.size()));
00811 for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
00812 # endif
00813 {
00814 std::ostringstream OS;
00815 I->first.print(OS);
00816 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00817 "phr: id: '" + OS.str() + "'");
00818 OS.str("");
00819 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00820 "phr: data.size(): %zu",I->second.data().size() );
00821 if (I->second.data().size())
00822 {
00823 I->second.data().back().id().print(OS);
00824 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00825 "phr: data.back().id(): '"
00826 + OS.str() + "'");
00827 }
00828 }
00829 if (!srp.aux().processHistoryID().isValid())
00830 {
00831 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00832 "ProcessHistoryID: 'INVALID'");
00833 }
00834 else
00835 {
00836 std::ostringstream OS;
00837 srp.aux().processHistoryID().print(OS);
00838 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: ProcessHistoryID: '"
00839 + OS.str() + "'");
00840 OS.str("");
00841 # if ART_HEX_VERSION >= 0x20703
00842 ProcessHistory processHistory;
00843 ProcessHistoryRegistry::get(srp.aux().processHistoryID(),processHistory);
00844 # else
00845 const ProcessHistory& processHistory =
00846 ProcessHistoryRegistry::get(srp.aux().processHistoryID());
00847 # endif
00848 if (processHistory.data().size())
00849 {
00850
00851 processHistory.data().back().id().print(OS);
00852 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00853 "ProcessConfigurationID: '"
00854 + OS.str() + "'");
00855 OS.str("");
00856 OS << processHistory.data().back();
00857 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00858 "ProcessConfiguration: '"
00859 + OS.str());
00860 }
00861 }
00862 }
00863 msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
00864 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: streamed SubRunAuxiliary.");
00865 }
00866
00867
00868
00869 std::vector<BranchKey*> bkv;
00870 writeDataProducts(msg, srp, bkv);
00871
00872
00873
00874 ServiceHandle<NetMonTransportService> transport;
00875 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00876 "Sending the EndOfSubrun message to "
00877 + std::to_string(transport->dataReceiverCount())
00878 + " data receivers ...");
00879 for (size_t idx = 0; idx < transport->dataReceiverCount(); ++idx)
00880 {
00881 transport->sendMessage(idx, artdaq::Fragment::EndOfSubrunFragmentType, msg);
00882 }
00883 TRACE(5, "RootMPIOutput: RootMPIOutput::writeSubRun: "
00884 "EndOfSubrun message(s) sent.");
00885
00886
00887
00888 transport->disconnect();
00889
00890
00891
00892
00893 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
00894 {
00895 delete *I;
00896 *I = 0;
00897 }
00898 TRACE(5, "RootMPIOutput: End: RootMPIOutput::writeSubRun(const SubRunPrincipal& srp)");
00899 }
00900
00901 DEFINE_ART_MODULE(art::RootMPIOutput)