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