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