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