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