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