$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "artdaq/ArtModules/RootNetOutput.hh" 00002 00003 #include "art/Framework/Core/ModuleMacros.h" 00004 #include "art/Framework/Services/Registry/ServiceHandle.h" 00005 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h" 00006 #include "art/Persistency/Provenance/ProductMetaData.h" 00007 00008 #include "canvas/Persistency/Provenance/BranchDescription.h" 00009 #include "canvas/Persistency/Provenance/BranchKey.h" 00010 #include "canvas/Persistency/Provenance/History.h" 00011 #include "canvas/Persistency/Provenance/ParentageRegistry.h" 00012 #include "canvas/Persistency/Provenance/ProcessConfiguration.h" 00013 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h" 00014 #include "canvas/Persistency/Provenance/ProcessHistoryID.h" 00015 #include "canvas/Persistency/Provenance/ProductList.h" 00016 #include "canvas/Persistency/Provenance/ProductProvenance.h" 00017 #include "canvas/Persistency/Provenance/RunAuxiliary.h" 00018 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h" 00019 #include "canvas/Utilities/DebugMacros.h" 00020 #include "canvas/Utilities/Exception.h" 00021 #include "cetlib/column_width.h" 00022 #include "cetlib/lpad.h" 00023 #include "cetlib/rpad.h" 00024 #include <algorithm> 00025 # include <iterator> 00026 #include "fhiclcpp/ParameterSet.h" 00027 #include "fhiclcpp/ParameterSetID.h" 00028 #include "fhiclcpp/ParameterSetRegistry.h" 00029 00030 #define TRACE_NAME "RootNetOutput" 00031 00032 #define TLVL_OPENFILE 5 00033 #define TLVL_CLOSEFILE 6 00034 #define TLVL_RESPONDTOCLOSEINPUTFILE 7 00035 #define TLVL_RESPONDTOCLOSEOUTPUTFILE 8 00036 #define TLVL_ENDJOB 9 00037 #define TLVL_SENDINIT 10 00038 #define TLVL_SENDINIT_VERBOSE1 32 00039 #define TLVL_SENDINIT_VERBOSE2 33 00040 #define TLVL_WRITEDATAPRODUCTS 11 00041 #define TLVL_WRITEDATAPRODUCTS_VERBOSE 34 00042 #define TLVL_WRITE 12 00043 #define TLVL_WRITERUN 13 00044 #define TLVL_WRITESUBRUN 14 00045 #define TLVL_WRITESUBRUN_VERBOSE 35 00046 00047 00048 #include "artdaq/DAQdata/Globals.hh" 00049 #include "artdaq/ArtModules/NetMonTransportService.h" 00050 #include "artdaq-core/Data/detail/ParentageMap.hh" 00051 #include "artdaq/DAQdata/NetMonHeader.hh" 00052 00053 #include <iomanip> 00054 #include <iostream> 00055 #include <sstream> 00056 #include <string> 00057 #include <vector> 00058 00059 #include <unistd.h> 00060 00061 #include <TClass.h> 00062 #include <TMessage.h> 00063 #include <TBufferFile.h> 00064 00065 art::RootNetOutput:: 00066 RootNetOutput(fhicl::ParameterSet const& ps) 00067 : OutputModule(ps) 00068 , initMsgSent_(false) 00069 { 00070 TLOG(TLVL_DEBUG) << "Begin: RootNetOutput::RootNetOutput(ParameterSet const& ps)"; 00071 ServiceHandle<NetMonTransportService> transport; 00072 transport->connect(); 00073 TLOG(TLVL_DEBUG) << "End: RootNetOutput::RootNetOutput(ParameterSet const& ps)"; 00074 } 00075 00076 art::RootNetOutput:: 00077 ~RootNetOutput() 00078 { 00079 TLOG(TLVL_DEBUG) << "Begin: RootNetOutput::~RootNetOutput()"; 00080 ServiceHandle<NetMonTransportService> transport; 00081 transport->disconnect(); 00082 TLOG(TLVL_DEBUG) << "End: RootNetOutput::~RootNetOutput()"; 00083 } 00084 00085 void 00086 art::RootNetOutput:: 00087 openFile(FileBlock const&) 00088 { 00089 TLOG(TLVL_OPENFILE) << "Begin/End: RootNetOutput::openFile(const FileBlock&)"; 00090 } 00091 00092 void 00093 art::RootNetOutput:: 00094 closeFile() 00095 { 00096 TLOG(TLVL_CLOSEFILE) << "Begin/End: RootNetOutput::closeFile()"; 00097 } 00098 00099 void 00100 art::RootNetOutput:: 00101 respondToCloseInputFile(FileBlock const&) 00102 { 00103 TLOG(TLVL_RESPONDTOCLOSEINPUTFILE) << "Begin/End: RootNetOutput::" 00104 "respondToCloseOutputFiles(FileBlock const&)"; 00105 } 00106 00107 void 00108 art::RootNetOutput:: 00109 respondToCloseOutputFiles(FileBlock const&) 00110 { 00111 TLOG(TLVL_RESPONDTOCLOSEOUTPUTFILE) << "Begin/End: RootNetOutput::" 00112 "respondToCloseOutputFiles(FileBlock const&)"; 00113 } 00114 00115 static 00116 void 00117 send_shutdown_message() 00118 { 00119 // 4/1/2016, ELF: Apparently, all this function does is make things not work. 00120 // At this point in the state machine, RHandles and SHandles have already been 00121 // destructed. Calling sendMessage will cause SHandles to reconnect itself, 00122 // but the other end will never recieve the message. 00123 } 00124 00125 void 00126 art::RootNetOutput:: 00127 endJob() 00128 { 00129 TLOG(TLVL_ENDJOB) << "Begin: RootNetOutput::endJob()"; 00130 send_shutdown_message(); 00131 TLOG(TLVL_ENDJOB) << "End: RootNetOutput::endJob()"; 00132 } 00133 00134 //#pragma GCC push_options 00135 //#pragma GCC optimize ("O0") 00136 static 00137 void 00138 send_init_message() 00139 { 00140 TLOG(TLVL_SENDINIT) << "Begin: RootNetOutput static send_init_message()"; 00141 // 00142 // Get the classes we will need. 00143 // 00144 //static TClass* string_class = TClass::GetClass("std::string"); 00145 //if (string_class == nullptr) { 00146 // throw art::Exception(art::errors::DictionaryNotFound) << 00147 // "RootNetOutput static send_init_message(): " 00148 // "Could not get TClass for std::string!"; 00149 //} 00150 static TClass* product_list_class = TClass::GetClass( 00151 "std::map<art::BranchKey,art::BranchDescription>"); 00152 if (product_list_class == nullptr) 00153 { 00154 throw art::Exception(art::errors::DictionaryNotFound) << 00155 "RootNetOutput static send_init_message(): " 00156 "Could not get TClass for " 00157 "map<art::BranchKey,art::BranchDescription>!"; 00158 } 00159 //typedef std::map<const ProcessHistoryID,ProcessHistory> ProcessHistoryMap; 00160 //TClass* process_history_map_class = TClass::GetClass( 00161 // "std::map<const art::ProcessHistoryID,art::ProcessHistory>"); 00162 //FIXME: Replace the "2" here with a use of the proper enum value! 00163 static TClass* process_history_map_class = TClass::GetClass( 00164 "std::map<const art::Hash<2>,art::ProcessHistory>"); 00165 if (process_history_map_class == nullptr) 00166 { 00167 throw art::Exception(art::errors::DictionaryNotFound) << 00168 "RootNetOutput static send_init_message(): " 00169 "Could not get class for " 00170 "std::map<const art::Hash<2>,art::ProcessHistory>!"; 00171 } 00172 //static TClass* parentage_map_class = TClass::GetClass( 00173 // "std::map<const art::ParentageID,art::Parentage>"); 00174 //FIXME: Replace the "5" here with a use of the proper enum value! 00175 static TClass* parentage_map_class = TClass::GetClass("art::ParentageMap"); 00176 if (parentage_map_class == nullptr) 00177 { 00178 throw art::Exception(art::errors::DictionaryNotFound) << 00179 "RootNetOutput static send_init_message(): " 00180 "Could not get class for ParentageMap."; 00181 } 00182 TLOG(TLVL_SENDINIT) << "parentage_map_class: " << (void*)parentage_map_class; 00183 00184 // 00185 // Construct and send the init message. 00186 // 00187 TBufferFile msg(TBuffer::kWrite); 00188 msg.SetWriteMode(); 00189 // 00190 // Stream the message type code. 00191 // 00192 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Streaming message type code ..."; 00193 msg.WriteULong(1); 00194 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Finished streaming message type code."; 00195 00196 // 00197 // Stream the ParameterSetRegistry. 00198 // 00199 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size(); 00200 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): parameter set count: " + std::to_string(ps_cnt); 00201 msg.WriteULong(ps_cnt); 00202 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Streaming parameter sets ..."; 00203 for ( 00204 auto I = std::begin(fhicl::ParameterSetRegistry::get()), 00205 E = std::end(fhicl::ParameterSetRegistry::get()); 00206 I != E; ++I) 00207 { 00208 std::string pset_str = I->second.to_string(); 00209 //msg.WriteObjectAny(&pset_str, string_class); 00210 msg.WriteStdString(pset_str); 00211 } 00212 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Finished streaming parameter sets."; 00213 00214 // 00215 // Stream the MasterProductRegistry. 00216 // 00217 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Streaming MasterProductRegistry ..."; 00218 art::ProductList productList( 00219 art::ProductMetaData::instance().productList()); 00220 msg.WriteObjectAny(&productList, product_list_class); 00221 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Finished streaming MasterProductRegistry."; 00222 00223 art::ProcessHistoryMap phr; 00224 for (auto const& pr : art::ProcessHistoryRegistry::get()) 00225 { 00226 phr.emplace(pr); 00227 } 00228 // 00229 // Dump the ProcessHistoryRegistry. 00230 // 00231 TLOG(TLVL_SENDINIT_VERBOSE2) << "RootNetOutput static send_init_message(): Dumping ProcessHistoryRegistry ..."; 00232 //typedef std::map<const ProcessHistoryID,ProcessHistory> 00233 // ProcessHistoryMap; 00234 TLOG(TLVL_SENDINIT_VERBOSE2) << "RootNetOutput static send_init_message(): phr: size: " << phr.size(); 00235 for (auto I = phr.begin(), E = phr.end(); I != E; ++I) 00236 { 00237 std::ostringstream OS; 00238 I->first.print(OS); 00239 TLOG(TLVL_SENDINIT_VERBOSE2) << "RootNetOutput static send_init_message(): phr: id: '" << OS.str() << "'"; 00240 } 00241 // 00242 // Stream the ProcessHistoryRegistry. 00243 // 00244 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Streaming ProcessHistoryRegistry ..."; 00245 //typedef std::map<const ProcessHistoryID,ProcessHistory> 00246 // ProcessHistoryMap; 00247 const art::ProcessHistoryMap& phm = phr; 00248 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): phm: size: " << phm.size(); 00249 msg.WriteObjectAny(&phm, process_history_map_class); 00250 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Finished streaming ProcessHistoryRegistry."; 00251 00252 // 00253 // Stream the ParentageRegistry. 00254 // 00255 TLOG(TLVL_SENDINIT) << "static send_init_message(): Streaming ParentageRegistry ..." 00256 << (void*)parentage_map_class; 00257 art::ParentageMap parentageMap{}; 00258 for (auto const& pr : art::ParentageRegistry::get()) 00259 { 00260 parentageMap.emplace(pr.first, pr.second); 00261 } 00262 00263 msg.WriteObjectAny(&parentageMap, parentage_map_class); 00264 00265 TLOG(TLVL_SENDINIT) << "static send_init_message(): Finished streaming ParentageRegistry."; 00266 00267 // 00268 // 00269 // Send init message. 00270 // 00271 art::ServiceHandle<NetMonTransportService> transport; 00272 if (!transport.get()) 00273 { 00274 TLOG(TLVL_ERROR) << "Could not get handle to NetMonTransportService!"; 00275 return; 00276 } 00277 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Sending the init message to " << transport->dataReceiverCount() << " data receivers ..."; 00278 for (size_t idx = 0; idx < transport->dataReceiverCount(); ++idx) 00279 { 00280 transport->sendMessage(idx, artdaq::Fragment::InitFragmentType, msg); 00281 } 00282 TLOG(TLVL_SENDINIT) << "RootNetOutput static send_init_message(): Init message(s) sent."; 00283 00284 TLOG(TLVL_SENDINIT) << "End: RootNetOutput static send_init_message()"; 00285 } 00286 00287 //#pragma GCC pop_options 00288 00289 void 00290 art::RootNetOutput:: 00291 writeDataProducts(TBufferFile& msg, const Principal& principal, 00292 std::vector<BranchKey*>& bkv) 00293 { 00294 TLOG(TLVL_WRITEDATAPRODUCTS) << "Begin: RootNetOutput::writeDataProducts(...)"; 00295 // 00296 // Fetch the class dictionaries we need for 00297 // writing out the data products. 00298 // 00299 static TClass* branch_key_class = TClass::GetClass("art::BranchKey"); 00300 if (branch_key_class == nullptr) 00301 { 00302 throw art::Exception(art::errors::DictionaryNotFound) << 00303 "RootNetOutput::writeDataProducts(...): " 00304 "Could not get TClass for art::BranchKey!"; 00305 } 00306 static TClass* prdprov_class = TClass::GetClass("art::ProductProvenance"); 00307 if (prdprov_class == nullptr) 00308 { 00309 throw art::Exception(art::errors::DictionaryNotFound) << 00310 "RootNetOutput::writeDataProducts(...): " 00311 "Could not get TClass for art::ProductProvenance!"; 00312 } 00313 00314 // 00315 // Calculate the data product count. 00316 // 00317 unsigned long prd_cnt = 0; 00318 //std::map<art::BranchID, std::shared_ptr<art::Group>>::const_iterator 00319 for (auto I = principal.begin(), E = principal.end(); I != E; ++I) 00320 { 00321 auto const& productDescription = I->second->productDescription(); 00322 auto const& refs = keptProducts()[productDescription.branchType()]; 00323 bool found = false; 00324 for (auto const& ref : refs) 00325 { 00326 if (*ref == productDescription) 00327 { 00328 found = true; 00329 break; 00330 } 00331 } 00332 if (I->second->productUnavailable() || !found) 00333 { 00334 continue; 00335 } 00336 ++prd_cnt; 00337 } 00338 // 00339 // Write the data product count. 00340 // 00341 TLOG(TLVL_WRITEDATAPRODUCTS) << "RootNetOutput::writeDataProducts(...): Streaming product count: " + std::to_string(prd_cnt); 00342 msg.WriteULong(prd_cnt); 00343 TLOG(TLVL_WRITEDATAPRODUCTS) << "RootNetOutput::writeDataProducts(...): Finished streaming product count."; 00344 00345 // 00346 // Loop over the groups in the RunPrincipal and 00347 // write out the data products. 00348 // 00349 // Note: We need this vector of keys because the ROOT I/O mechanism 00350 // requires that each object inserted in the message has a 00351 // unique address, so we force that by holding on to each 00352 // branch key manufactured in the loop until after we are 00353 // done constructing the message. 00354 // 00355 bkv.reserve(prd_cnt); 00356 //std::map<art::BranchID, std::shared_ptr<art::Group>>::const_iterator 00357 for (auto I = principal.begin(), E = principal.end(); I != E; ++I) 00358 { 00359 auto const& productDescription = I->second->productDescription(); 00360 auto const& refs = keptProducts()[productDescription.branchType()]; 00361 bool found = false; 00362 for (auto const& ref : refs) 00363 { 00364 if (*ref == productDescription) 00365 { 00366 found = true; 00367 break; 00368 } 00369 } 00370 if (I->second->productUnavailable() || !found) 00371 { 00372 continue; 00373 } 00374 const BranchDescription& bd(I->second->productDescription()); 00375 bkv.push_back(new BranchKey(bd)); 00376 TLOG(TLVL_WRITEDATAPRODUCTS_VERBOSE) << "RootNetOutput::writeDataProducts(...): Dumping branch key of class: '" 00377 << bkv.back()->friendlyClassName_ 00378 << "' modlbl: '" 00379 << bkv.back()->moduleLabel_ 00380 << "' instnm: '" 00381 << bkv.back()->productInstanceName_ 00382 << "' procnm: '" 00383 << bkv.back()->processName_ 00384 << "'"; 00385 TLOG(TLVL_WRITEDATAPRODUCTS) << "RootNetOutput::writeDataProducts(...): " 00386 "Streaming branch key of class: '" 00387 << bd.producedClassName() 00388 << "' modlbl: '" 00389 << bd.moduleLabel() 00390 << "' instnm: '" 00391 << bd.productInstanceName() 00392 << "' procnm: '" 00393 << bd.processName() 00394 << "'"; 00395 msg.WriteObjectAny(bkv.back(), branch_key_class); 00396 TLOG(TLVL_WRITEDATAPRODUCTS) << "RootNetOutput::writeDataProducts(...): " 00397 "Streaming product of class: '" 00398 << bd.producedClassName() 00399 << "' modlbl: '" 00400 << bd.moduleLabel() 00401 << "' instnm: '" 00402 << bd.productInstanceName() 00403 << "' procnm: '" 00404 << bd.processName() 00405 << "'"; 00406 00407 OutputHandle oh = principal.getForOutput(bd.productID(), true); 00408 const EDProduct* prd = oh.wrapper(); 00409 TLOG(TLVL_WRITEDATAPRODUCTS) << "Class for branch " << bd.wrappedName() << " is " << (void*)TClass::GetClass(bd.wrappedName().c_str()); 00410 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str())); 00411 TLOG(TLVL_WRITEDATAPRODUCTS) << "RootNetOutput::writeDataProducts(...): " 00412 "Streaming product provenance of class: '" 00413 << bd.producedClassName() 00414 << "' modlbl: '" 00415 << bd.moduleLabel() 00416 << "' instnm: '" 00417 << bd.productInstanceName() 00418 << "' procnm: '" 00419 << bd.processName() 00420 << "'"; 00421 const ProductProvenance* prdprov = I->second->productProvenancePtr().get(); 00422 msg.WriteObjectAny(prdprov, prdprov_class); 00423 } 00424 TLOG(TLVL_WRITEDATAPRODUCTS) << "End: RootNetOutput::writeDataProducts(...)"; 00425 } 00426 00427 void 00428 art::RootNetOutput:: 00429 write(EventPrincipal& ep) 00430 { 00431 // 00432 // Write an Event message. 00433 // 00434 TLOG(TLVL_WRITE) << "Begin: RootNetOutput::write(const EventPrincipal& ep)"; 00435 if (!initMsgSent_) 00436 { 00437 send_init_message(); 00438 initMsgSent_ = true; 00439 } 00440 // 00441 // Get root classes needed for I/O. 00442 // 00443 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary"); 00444 if (run_aux_class == nullptr) 00445 { 00446 throw art::Exception(art::errors::DictionaryNotFound) << 00447 "RootNetOutput::write(const EventPrincipal& ep): " 00448 "Could not get TClass for art::RunAuxiliary!"; 00449 } 00450 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary"); 00451 if (subrun_aux_class == nullptr) 00452 { 00453 throw art::Exception(art::errors::DictionaryNotFound) << 00454 "RootNetOutput::write(const EventPrincipal& ep): " 00455 "Could not get TClass for art::SubRunAuxiliary!"; 00456 } 00457 static TClass* event_aux_class = TClass::GetClass("art::EventAuxiliary"); 00458 if (event_aux_class == nullptr) 00459 { 00460 throw art::Exception(art::errors::DictionaryNotFound) << 00461 "RootNetOutput::write(const EventPrincipal& ep): " 00462 "Could not get TClass for art::EventAuxiliary!"; 00463 } 00464 static TClass* history_class = TClass::GetClass("art::History"); 00465 if (history_class == nullptr) 00466 { 00467 throw art::Exception(art::errors::DictionaryNotFound) << 00468 "RootNetOutput::write(const EventPrincipal& ep): " 00469 "Could not get TClass for art::History!"; 00470 } 00471 // 00472 // Setup message buffer. 00473 // 00474 TBufferFile msg(TBuffer::kWrite); 00475 msg.SetWriteMode(); 00476 // 00477 // Write message type code. 00478 // 00479 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Streaming message type code ..."; 00480 msg.WriteULong(4); 00481 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Finished streaming message type code."; 00482 00483 // 00484 // Write RunAuxiliary. 00485 // 00486 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Streaming RunAuxiliary ..."; 00487 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(), 00488 run_aux_class); 00489 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Finished streaming RunAuxiliary."; 00490 00491 // 00492 // Write SubRunAuxiliary. 00493 // 00494 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Streaming SubRunAuxiliary ..."; 00495 msg.WriteObjectAny(&ep.subRunPrincipal().aux(), 00496 subrun_aux_class); 00497 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Finished streaming SubRunAuxiliary."; 00498 00499 // 00500 // Write EventAuxiliary. 00501 // 00502 { 00503 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Streaming EventAuxiliary ..."; 00504 msg.WriteObjectAny(&ep.aux(), event_aux_class); 00505 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Finished streaming EventAuxiliary."; 00506 } 00507 // 00508 // Write History. 00509 // 00510 { 00511 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Streaming History ..."; 00512 msg.WriteObjectAny(&ep.history(), history_class); 00513 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Finished streaming History."; 00514 } 00515 // 00516 // Write data products. 00517 // 00518 std::vector<BranchKey*> bkv; 00519 writeDataProducts(msg, ep, bkv); 00520 // 00521 // Send message. 00522 // 00523 { 00524 ServiceHandle<NetMonTransportService> transport; 00525 if (!transport.get()) 00526 { 00527 TLOG(TLVL_ERROR) << "Could not get handle to NetMonTransportService!"; 00528 return; 00529 } 00530 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Sending a message ..."; 00531 transport->sendMessage(ep.id().event(), artdaq::Fragment::DataFragmentType, msg); 00532 TLOG(TLVL_WRITE) << "RootNetOutput::write(const EventPrincipal& ep): Message sent."; 00533 } 00534 // 00535 // Delete the branch keys we created for the message. 00536 // 00537 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I) 00538 { 00539 delete *I; 00540 *I = 0; 00541 } 00542 TLOG(TLVL_WRITE) << "End: RootNetOutput::write(const EventPrincipal& ep)"; 00543 } 00544 00545 void 00546 art::RootNetOutput:: 00547 writeRun(RunPrincipal& rp) 00548 { 00549 // 00550 // Write an EndRun message. 00551 // 00552 TLOG(TLVL_WRITERUN) << "Begin: RootNetOutput::writeRun(const RunPrincipal& rp)"; 00553 (void)rp; 00554 if (!initMsgSent_) 00555 { 00556 send_init_message(); 00557 initMsgSent_ = true; 00558 } 00559 #if 0 00560 // 00561 // Fetch the class dictionaries we need for 00562 // writing out the auxiliary information. 00563 // 00564 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary"); 00565 assert(run_aux_class != nullptr && "writeRun: Could not get TClass for art::RunAuxiliary!"); 00566 // 00567 // Begin preparing message. 00568 // 00569 TBufferFile msg(TBuffer::kWrite); 00570 msg.SetWriteMode(); 00571 // 00572 // Write message type code. 00573 // 00574 { 00575 TLOG(TLVL_WRITERUN) << "writeRun: streaming message type code ..."; 00576 msg.WriteULong(2); 00577 TLOG(TLVL_WRITERUN) << "writeRun: finished streaming message type code."; 00578 } 00579 // 00580 // Write RunAuxiliary. 00581 // 00582 { 00583 TLOG(TLVL_WRITERUN) << "writeRun: streaming RunAuxiliary ..."; 00584 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: dumping ProcessHistoryRegistry ..."; 00585 //typedef std::map<const ProcessHistoryID,ProcessHistory> 00586 // ProcessHistoryMap; 00587 art::ProcessHistoryMap const& phr = 00588 art::ProcessHistoryRegistry::get(); 00589 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: phr: size: " << phr.size(); 00590 for (auto I = phr.begin(), E = phr.end(); I != E; ++I) 00591 { 00592 std::ostringstream OS; 00593 I->first.print(OS); 00594 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: phr: id: '" << OS.str() << "'"; 00595 OS.str(""); 00596 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: phr: data.size(): " << I->second.data().size(); 00597 if (I->second.data().size()) 00598 { 00599 I->second.data().back().id().print(OS); 00600 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: phr: data.back().id(): '" << OS.str() << "'"; 00601 } 00602 } 00603 if (!rp.aux().processHistoryID().isValid()) 00604 { 00605 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: ProcessHistoryID: 'INVALID'"; 00606 } 00607 else 00608 { 00609 std::ostringstream OS; 00610 rp.aux().processHistoryID().print(OS); 00611 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: ProcessHistoryID: '" << OS.str() << "'"; 00612 OS.str(""); 00613 const ProcessHistory& processHistory = 00614 ProcessHistoryRegistry::get(rp.aux().processHistoryID()); 00615 if (processHistory.data().size()) 00616 { 00617 // FIXME: Print something special on invalid id() here! 00618 processHistory.data().back().id().print(OS); 00619 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: ProcessConfigurationID: '" << OS.str() << "'"; 00620 OS.str(""); 00621 TLOG(TLVL_WRITERUN_VERBOSE) << "writeRun: ProcessConfiguration: '" << processHistory.data().back(); 00622 } 00623 } 00624 msg.WriteObjectAny(&rp.aux(), run_aux_class); 00625 TLOG(TLVL_WRITERUN) << "writeRun: streamed RunAuxiliary."; 00626 } 00627 // 00628 // Write data products. 00629 // 00630 std::vector<BranchKey*> bkv; 00631 writeDataProducts(msg, rp, bkv); 00632 // 00633 // Send message. 00634 // 00635 { 00636 ServiceHandle<NetMonTransportService> transport; 00637 if (!transport.get()) 00638 { 00639 TLOG(TLVL_ERROR) << "Could not get handle to NetMonTransportService!"; 00640 return; 00641 } 00642 TLOG(TLVL_WRITERUN) << "writeRun: sending a message ..."; 00643 transport->sendMessage(0, artdaq::Fragment::EndOfRunFragmentType, msg); 00644 TLOG(TLVL_WRITERUN) << "writeRun: message sent."; 00645 } 00646 // 00647 // Delete the branch keys we created for the message. 00648 // 00649 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I) 00650 { 00651 delete *I; 00652 *I = 0; 00653 } 00654 #endif // 0 00655 TLOG(TLVL_WRITERUN) << "End: RootNetOutput::writeRun(const RunPrincipal& rp)"; 00656 } 00657 00658 void 00659 art::RootNetOutput::writeSubRun(SubRunPrincipal& srp) 00660 { 00661 // 00662 // Write an EndSubRun message. 00663 // 00664 TLOG(TLVL_WRITESUBRUN) << "Begin: RootNetOutput::writeSubRun(const SubRunPrincipal& srp)"; 00665 if (!initMsgSent_) 00666 { 00667 send_init_message(); 00668 initMsgSent_ = true; 00669 } 00670 // 00671 // Fetch the class dictionaries we need for 00672 // writing out the auxiliary information. 00673 // 00674 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary"); 00675 if (subrun_aux_class == nullptr) 00676 { 00677 throw art::Exception(art::errors::DictionaryNotFound) << 00678 "RootNetOutput::writeSubRun: " 00679 "Could not get TClass for art::SubRunAuxiliary!"; 00680 } 00681 // 00682 // Begin preparing message. 00683 // 00684 TBufferFile msg(TBuffer::kWrite); 00685 msg.SetWriteMode(); 00686 // 00687 // Write message type code. 00688 // 00689 { 00690 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: streaming message type code ..."; 00691 msg.WriteULong(3); 00692 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: finished streaming message type code."; 00693 } 00694 // 00695 // Write SubRunAuxiliary. 00696 // 00697 { 00698 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: streaming SubRunAuxiliary ..."; 00699 00700 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: dumping ProcessHistoryRegistry ..."; 00701 //typedef std::map<const ProcessHistoryID,ProcessHistory> 00702 // ProcessHistoryMap; 00703 for (auto I = std::begin(art::ProcessHistoryRegistry::get()) 00704 , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I) 00705 { 00706 std::ostringstream OS; 00707 I->first.print(OS); 00708 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: phr: id: '" << OS.str() << "'"; 00709 OS.str(""); 00710 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: phr: data.size(): " << I->second.data().size(); 00711 if (I->second.data().size()) 00712 { 00713 I->second.data().back().id().print(OS); 00714 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: phr: data.back().id(): '" << OS.str() << "'"; 00715 } 00716 } 00717 if (!srp.aux().processHistoryID().isValid()) 00718 { 00719 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: ProcessHistoryID: 'INVALID'"; 00720 } 00721 else 00722 { 00723 std::ostringstream OS; 00724 srp.aux().processHistoryID().print(OS); 00725 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: ProcessHistoryID: '" << OS.str() << "'"; 00726 OS.str(""); 00727 ProcessHistory processHistory; 00728 ProcessHistoryRegistry::get(srp.aux().processHistoryID(), processHistory); 00729 if (processHistory.data().size()) 00730 { 00731 // FIXME: Print something special on invalid id() here! 00732 processHistory.data().back().id().print(OS); 00733 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: ProcessConfigurationID: '" << OS.str() << "'"; 00734 OS.str(""); 00735 OS << processHistory.data().back(); 00736 TLOG(TLVL_WRITESUBRUN_VERBOSE) << "RootNetOutput::writeSubRun: ProcessConfiguration: '" << OS.str(); 00737 } 00738 } 00739 msg.WriteObjectAny(&srp.aux(), subrun_aux_class); 00740 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: streamed SubRunAuxiliary."; 00741 } 00742 // 00743 // Write data products. 00744 // 00745 std::vector<BranchKey*> bkv; 00746 writeDataProducts(msg, srp, bkv); 00747 // 00748 // Send message. 00749 // 00750 ServiceHandle<NetMonTransportService> transport; 00751 if (!transport.get()) 00752 { 00753 TLOG(TLVL_ERROR) << "Could not get handle to NetMonTransportService!"; 00754 return; 00755 } 00756 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: Sending the EndOfSubrun message"; 00757 transport->sendMessage(0, artdaq::Fragment::EndOfSubrunFragmentType, msg); 00758 TLOG(TLVL_WRITESUBRUN) << "RootNetOutput::writeSubRun: EndOfSubrun message sent."; 00759 00760 // Disconnecting will cause EOD fragments to be generated which will 00761 // allow components downstream to flush data and clean up. 00762 //transport->disconnect(); 00763 00764 // 00765 // Delete the branch keys we created for the message. 00766 // 00767 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I) 00768 { 00769 delete *I; 00770 *I = 0; 00771 } 00772 TLOG(TLVL_WRITESUBRUN) << "End: RootNetOutput::writeSubRun(const SubRunPrincipal& srp)"; 00773 } 00774 00775 DEFINE_ART_MODULE(art::RootNetOutput)