artdaq  v3_04_00
TransferOutput_module.cc
1 #define TRACE_NAME "TransferOutput"
2 
3 #include "art/Framework/Core/ModuleMacros.h"
4 #include "art/Framework/Core/OutputModule.h"
5 #include "art/Framework/Principal/EventPrincipal.h"
6 #include "art/Framework/Principal/OutputHandle.h"
7 #include "art/Framework/Principal/RunPrincipal.h"
8 #include "art/Framework/Principal/SubRunPrincipal.h"
9 #include "art/Framework/Services/Registry/ServiceHandle.h"
10 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
11 #include "art/Persistency/Provenance/ProductMetaData.h"
12 
13 #include "canvas/Persistency/Provenance/BranchDescription.h"
14 #include "canvas/Persistency/Provenance/BranchKey.h"
15 #include "canvas/Persistency/Provenance/History.h"
16 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
17 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
18 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
19 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
20 #include "canvas/Persistency/Provenance/ProductList.h"
21 #include "canvas/Persistency/Provenance/ProductProvenance.h"
22 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
23 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
24 #include "canvas/Utilities/DebugMacros.h"
25 #include "canvas/Utilities/Exception.h"
26 #include "cetlib/column_width.h"
27 #include "cetlib/lpad.h"
28 #include "cetlib/rpad.h"
29 #include <algorithm>
30 # include <iterator>
31 #include "fhiclcpp/ParameterSet.h"
32 #include "fhiclcpp/ParameterSetID.h"
33 #include "fhiclcpp/ParameterSetRegistry.h"
34 
35 #include "artdaq/TransferPlugins/TransferInterface.hh"
36 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
37 #include "artdaq-core/Data/detail/ParentageMap.hh"
38 #include "artdaq/DAQdata/Globals.hh"
39 #include "artdaq/DAQdata/NetMonHeader.hh"
40 
41 #include <iomanip>
42 #include <iostream>
43 #include <sstream>
44 #include <string>
45 #include <vector>
46 
47 #include <unistd.h>
48 
49 #include <TClass.h>
50 #include <TMessage.h>
51 
52 namespace art
53 {
54  class TransferOutput;
55 }
56 
57 
63 class art::TransferOutput : public OutputModule
64 {
65 public:
73  explicit TransferOutput(fhicl::ParameterSet const& ps);
74 
79 
80 private:
81  virtual void openFile(FileBlock const&);
82 
83  virtual void closeFile();
84 
85  virtual void respondToCloseInputFile(FileBlock const&);
86 
87  virtual void respondToCloseOutputFiles(FileBlock const&);
88 
89  virtual void endJob();
90 
91  virtual void write(EventPrincipal&);
92 
93  virtual void writeRun(RunPrincipal&);
94 
95  virtual void writeSubRun(SubRunPrincipal&);
96 
97  void writeDataProducts(TBufferFile&, const Principal&,
98  std::vector<BranchKey*>&);
99 
100 private:
101  bool initMsgSent_;
102  size_t send_timeout_us_;
103  size_t send_retry_count_;
104  std::unique_ptr<artdaq::TransferInterface> transfer_;
105 
106  void sendMessage_(uint64_t sequenceId, uint8_t messageType, TBufferFile& msg);
107  void send_init_message();
108 
109 };
110 
112 TransferOutput(fhicl::ParameterSet const& ps)
113  : OutputModule(ps)
114  , initMsgSent_(false)
115  , send_timeout_us_(ps.get<size_t>("send_timeout_us", 5000000))
116  , send_retry_count_(ps.get<size_t>("send_retry_count", 5))
117 {
118  TLOG(TLVL_DEBUG) << "Begin: TransferOutput::TransferOutput(ParameterSet const& ps)";
119  transfer_ = artdaq::MakeTransferPlugin(ps, "transfer_plugin", artdaq::TransferInterface::Role::kSend);
120  TLOG(TLVL_DEBUG) << "END: TransferOutput::TransferOutput";
121 }
122 
125 {
126  TLOG(TLVL_DEBUG) << "Begin: TransferOutput::~TransferOutput()";
127 
128  auto sts = transfer_->transfer_fragment_reliable_mode(std::move(*artdaq::Fragment::eodFrag(0)));
129  if (sts != artdaq::TransferInterface::CopyStatus::kSuccess) TLOG(TLVL_ERROR) << "Error sending EOD Fragment!";
130  transfer_.reset(nullptr);
131  TLOG(TLVL_DEBUG) << "End: TransferOutput::~TransferOutput()";
132 }
133 
134 void
135 art::TransferOutput::
136 openFile(FileBlock const&)
137 {
138  TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::openFile(const FileBlock&)";
139 }
140 
141 void
142 art::TransferOutput::
143 closeFile()
144 {
145  TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::closeFile()";
146 }
147 
148 void
149 art::TransferOutput::
150 respondToCloseInputFile(FileBlock const&)
151 {
152  TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::" <<
153  "respondToCloseOutputFiles(FileBlock const&)";
154 }
155 
156 void
157 art::TransferOutput::
158 respondToCloseOutputFiles(FileBlock const&)
159 {
160  TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::" <<
161  "respondToCloseOutputFiles(FileBlock const&)";
162 }
163 
164 void
165 art::TransferOutput::
166 endJob()
167 {
168  TLOG(TLVL_TRACE) << "Begin: TransferOutput::endJob()";
169 }
170 
171 //#pragma GCC push_options
172 //#pragma GCC optimize ("O0")
173 void
174 art::TransferOutput::
175 send_init_message()
176 {
177  TLOG(TLVL_TRACE) << "Begin: TransferOutput static send_init_message()";
178  //
179  // Get the classes we will need.
180  //
181  //static TClass* string_class = TClass::GetClass("std::string");
182  //if (string_class == nullptr) {
183  // throw art::Exception(art::errors::DictionaryNotFound) <<
184  // "TransferOutput static send_init_message(): "
185  // "Could not get TClass for std::string!";
186  //}
187  static TClass* product_list_class = TClass::GetClass(
188  "std::map<art::BranchKey,art::BranchDescription>");
189  if (product_list_class == nullptr)
190  {
191  throw art::Exception(art::errors::DictionaryNotFound) <<
192  "TransferOutput static send_init_message(): "
193  "Could not get TClass for "
194  "map<art::BranchKey,art::BranchDescription>!";
195  }
196  //typedef std::map<const ProcessHistoryID,ProcessHistory> ProcessHistoryMap;
197  //TClass* process_history_map_class = TClass::GetClass(
198  // "std::map<const art::ProcessHistoryID,art::ProcessHistory>");
199  //FIXME: Replace the "2" here with a use of the proper enum value!
200  static TClass* process_history_map_class = TClass::GetClass(
201  "std::map<const art::Hash<2>,art::ProcessHistory>");
202  if (process_history_map_class == nullptr)
203  {
204  throw art::Exception(art::errors::DictionaryNotFound) <<
205  "TransferOutput static send_init_message(): "
206  "Could not get class for "
207  "std::map<const art::Hash<2>,art::ProcessHistory>!";
208  }
209  //static TClass* parentage_map_class = TClass::GetClass(
210  // "std::map<const art::ParentageID,art::Parentage>");
211  //FIXME: Replace the "5" here with a use of the proper enum value!
212  static TClass* parentage_map_class = TClass::GetClass("art::ParentageMap");
213  if (parentage_map_class == nullptr)
214  {
215  throw art::Exception(art::errors::DictionaryNotFound) <<
216  "TransferOutput static send_init_message(): "
217  "Could not get class for ParentageMap";
218  }
219  //
220  // Construct and send the init message.
221  //
222  TBufferFile msg(TBuffer::kWrite);
223  msg.SetWriteMode();
224  //
225  // Stream the message type code.
226  //
227  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
228  "Streaming message type code ...";
229  msg.WriteULong(1);
230  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
231  "Finished streaming message type code.";
232 
233  //
234  // Stream the ParameterSetRegistry.
235  //
236  unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
237  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): parameter set count: " << ps_cnt;
238  msg.WriteULong(ps_cnt);
239  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Streaming parameter sets ...";
240  for (
241  auto I = std::begin(fhicl::ParameterSetRegistry::get()),
242  E = std::end(fhicl::ParameterSetRegistry::get());
243  I != E; ++I)
244  {
245  std::string pset_str = I->second.to_string();
246  //msg.WriteObjectAny(&pset_str, string_class);
247  msg.WriteStdString(pset_str);
248  }
249  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Finished streaming parameter sets.";
250 
251  //
252  // Stream the MasterProductRegistry.
253  //
254  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Streaming MasterProductRegistry ...";;
255  art::ProductList productList(art::ProductMetaData::instance().productList());
256  msg.WriteObjectAny(&productList, product_list_class);
257  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Finished streaming MasterProductRegistry.";
258 
259  art::ProcessHistoryMap phr;
260  for (auto const& pr : art::ProcessHistoryRegistry::get())
261  {
262  phr.emplace(pr);
263  }
264  //
265  // Dump the ProcessHistoryRegistry.
266  //
267  if (art::debugit() >= 1)
268  {
269  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
270  "Dumping ProcessHistoryRegistry ...";
271  //typedef std::map<const ProcessHistoryID,ProcessHistory>
272  // ProcessHistoryMap;
273  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
274  "phr: size: " + std::to_string(phr.size());
275  for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
276  {
277  std::ostringstream OS;
278  I->first.print(OS);
279  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
280  "phr: id: '" + OS.str() + "'";
281  }
282 }
283  //
284  // Stream the ProcessHistoryRegistry.
285  //
286 
287  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
288  "Streaming ProcessHistoryRegistry ...";
289  //typedef std::map<const ProcessHistoryID,ProcessHistory>
290  // ProcessHistoryMap;
291  const art::ProcessHistoryMap& phm = phr;
292  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
293  "phm: size: " << phm.size();
294  msg.WriteObjectAny(&phm, process_history_map_class);
295  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
296  "Finished streaming ProcessHistoryRegistry.";
297 
298  //
299  // Stream the ParentageRegistry.
300  //
301 #if 0
302  TLOG(TLVL_DEBUG) << "TransferOutput static send_init_message(): " <<
303  "Streaming ParentageRegistry ... sz=" << msg.Length();
304 #endif
305  art::ParentageMap parentageMap{};
306  for (auto const& pr : art::ParentageRegistry::get())
307  {
308  parentageMap.emplace(pr.first, pr.second);
309  }
310 
311  TLOG(TLVL_TRACE) << "Before WriteObjectAny ParentageMap";
312 #if 0
313  auto sts =
314 #endif
315  msg.WriteObjectAny(&parentageMap, parentage_map_class);
316  TLOG(TLVL_TRACE) << "After WriteObjectAny ParentageMap";
317 #if 0
318  TLOG(TLVL_DEBUG) << "TransferOutput: TransferOutput static send_init_message(): " <<
319  "Finished streaming ParentageRegistry." << " sts=" << sts << ", sz=" << msg.Length();
320 #endif
321 
322  //
323  //
324  // Send init message.
325  //
326  TLOG(TLVL_DEBUG) << "TransferOutput: TransferOutput static send_init_message(): " << "Sending the init message.";
327  sendMessage_(artdaq::Fragment::InvalidSequenceID - 1, artdaq::Fragment::InitFragmentType, msg);
328  TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
329  "Init message(s) sent.";
330 
331  TLOG(TLVL_TRACE) << " End: TransferOutput static send_init_message()";
332 }
333 
334 #//pragma GCC pop_options
335 
336 void
337 art::TransferOutput::
338 writeDataProducts(TBufferFile& msg, const Principal& principal,
339  std::vector<BranchKey*>& bkv)
340 {
341  TLOG(TLVL_TRACE) << " Begin: TransferOutput::writeDataProducts(...)";
342  //
343  // Fetch the class dictionaries we need for
344  // writing out the data products.
345  //
346  static TClass* branch_key_class = TClass::GetClass("art::BranchKey");
347  if (branch_key_class == nullptr)
348  {
349  throw art::Exception(art::errors::DictionaryNotFound) <<
350  "TransferOutput::writeDataProducts(...): "
351  "Could not get TClass for art::BranchKey!";
352  }
353  static TClass* prdprov_class = TClass::GetClass("art::ProductProvenance");
354  if (prdprov_class == nullptr)
355  {
356  throw art::Exception(art::errors::DictionaryNotFound) <<
357  "TransferOutput::writeDataProducts(...): "
358  "Could not get TClass for art::ProductProvenance!";
359  }
360  //
361  // Calculate the data product count.
362  //
363  unsigned long prd_cnt = 0;
364  //std::map<art::BranchID, std::shared_ptr<art::Group>>::const_iterator
365  for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
366  {
367  auto const& productDescription = I->second->productDescription();
368  auto const& refs = keptProducts()[productDescription.branchType()];
369  bool found = false;
370  for (auto const& ref : refs)
371  {
372  if (*ref == productDescription)
373  {
374  found = true;
375  break;
376  }
377  }
378  if (I->second->productUnavailable() || !found)
379  {
380  continue;
381  }
382  ++prd_cnt;
383  }
384  //
385  // Write the data product count.
386  //
387  {
388  TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
389  "Streaming product count: " << prd_cnt;
390  msg.WriteULong(prd_cnt);
391  TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
392  "Finished streaming product count.";
393  }
394  //
395  // Loop over the groups in the RunPrincipal and
396  // write out the data products.
397  //
398  // Note: We need this vector of keys because the ROOT I/O mechanism
399  // requires that each object inserted in the message has a
400  // unique address, so we force that by holding on to each
401  // branch key manufactured in the loop until after we are
402  // done constructing the message.
403  //
404  bkv.reserve(prd_cnt);
405  //std::map<art::BranchID, std::shared_ptr<art::Group>>::const_iterator
406  for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
407  {
408  auto const& productDescription = I->second->productDescription();
409  auto const& refs = keptProducts()[productDescription.branchType()];
410  bool found = false;
411  for (auto const& ref : refs)
412  {
413  if (*ref == productDescription)
414  {
415  found = true;
416  break;
417  }
418  }
419  if (I->second->productUnavailable() || !found)
420  {
421  continue;
422  }
423  const BranchDescription& bd(I->second->productDescription());
424  bkv.push_back(new BranchKey(bd));
425  if (art::debugit() >= 2)
426  {
427  TLOG(TLVL_TRACE) << "TransferOutput::writeDataProducts(...): "
428  "Dumping branch key of class: '"
429  << bkv.back()->friendlyClassName_
430  << "' modlbl: '"
431  << bkv.back()->moduleLabel_
432  << "' instnm: '"
433  << bkv.back()->productInstanceName_
434  << "' procnm: '"
435  << bkv.back()->processName_
436  << "'";
437  }
438  {
439  TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
440  "Streaming branch key of class: '"
441  + bd.producedClassName()
442  + "' modlbl: '"
443  + bd.moduleLabel()
444  + "' instnm: '"
445  + bd.productInstanceName()
446  + "' procnm: '"
447  + bd.processName()
448  + "'";
449  msg.WriteObjectAny(bkv.back(), branch_key_class);
450  }
451  {
452  TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
453  "Streaming product of class: '"
454  + bd.producedClassName()
455  + "' modlbl: '"
456  + bd.moduleLabel()
457  + "' instnm: '"
458  + bd.productInstanceName()
459  + "' procnm: '"
460  + bd.processName()
461  + "'";
462 
463  OutputHandle oh = principal.getForOutput(bd.productID(), true);
464  const EDProduct* prd = oh.wrapper();
465  msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
466  }
467  {
468  TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
469  "Streaming product provenance of class: '"
470  + bd.producedClassName()
471  + "' modlbl: '"
472  + bd.moduleLabel()
473  + "' instnm: '"
474  + bd.productInstanceName()
475  + "' procnm: '"
476  + bd.processName()
477  + "'";
478  const ProductProvenance* prdprov =
479  I->second->productProvenancePtr().get();
480  msg.WriteObjectAny(prdprov, prdprov_class);
481  }
482  }
483  TLOG(TLVL_TRACE) << " End: TransferOutput::writeDataProducts(...)";
484  }
485 
486 void
487 art::TransferOutput::
488 write(EventPrincipal& ep)
489 {
490  //
491  // Write an Event message.
492  //
493  TLOG(TLVL_TRACE) << " Begin: TransferOutput::"
494  "write(const EventPrincipal& ep)";
495  if (!initMsgSent_)
496  {
497  send_init_message();
498  initMsgSent_ = true;
499  }
500  //
501  // Get root classes needed for I/O.
502  //
503  static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
504  if (run_aux_class == nullptr)
505  {
506  throw art::Exception(art::errors::DictionaryNotFound) <<
507  "TransferOutput::write(const EventPrincipal& ep): "
508  "Could not get TClass for art::RunAuxiliary!";
509  }
510  static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
511  if (subrun_aux_class == nullptr)
512  {
513  throw art::Exception(art::errors::DictionaryNotFound) <<
514  "TransferOutput::write(const EventPrincipal& ep): "
515  "Could not get TClass for art::SubRunAuxiliary!";
516  }
517  static TClass* event_aux_class = TClass::GetClass("art::EventAuxiliary");
518  if (event_aux_class == nullptr)
519  {
520  throw art::Exception(art::errors::DictionaryNotFound) <<
521  "TransferOutput::write(const EventPrincipal& ep): "
522  "Could not get TClass for art::EventAuxiliary!";
523  }
524  static TClass* history_class = TClass::GetClass("art::History");
525  if (history_class == nullptr)
526  {
527  throw art::Exception(art::errors::DictionaryNotFound) <<
528  "TransferOutput::write(const EventPrincipal& ep): "
529  "Could not get TClass for art::History!";
530  }
531  //
532  // Setup message buffer.
533  //
534  TBufferFile msg(TBuffer::kWrite);
535  msg.SetWriteMode();
536  //
537  // Write message type code.
538  //
539  {
540  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
541  "Streaming message type code ...";
542  msg.WriteULong(4);
543  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
544  "Finished streaming message type code.";
545  }
546  //
547  // Write RunAuxiliary.
548  //
549  {
550  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
551  "Streaming RunAuxiliary ...";
552  msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
553  run_aux_class);
554  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
555  "Finished streaming RunAuxiliary.";
556  }
557  //
558  // Write SubRunAuxiliary.
559  //
560  {
561  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
562  "Streaming SubRunAuxiliary ...";
563  msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
564  subrun_aux_class);
565  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
566  "Finished streaming SubRunAuxiliary.";
567  }
568  //
569  // Write EventAuxiliary.
570  //
571  {
572  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
573  "Streaming EventAuxiliary ...";
574  msg.WriteObjectAny(&ep.aux(), event_aux_class);
575  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
576  "Finished streaming EventAuxiliary.";
577  }
578  //
579  // Write History.
580  //
581  {
582  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
583  "Streaming History ...";
584  msg.WriteObjectAny(&ep.history(), history_class);
585  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
586  "Finished streaming History.";
587  }
588  //
589  // Write data products.
590  //
591  std::vector<BranchKey*> bkv;
592  writeDataProducts(msg, ep, bkv);
593  //
594  // Send message.
595  //
596  {
597  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
598  "Sending a message ...";
599  sendMessage_(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
600  TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
601  "Message sent.";
602  }
603  //
604  // Delete the branch keys we created for the message.
605  //
606  for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
607  {
608  delete *I;
609  *I = 0;
610  }
611  TLOG(TLVL_TRACE) << " End: TransferOutput::write(const EventPrincipal& ep)";
612 }
613 
614 void
615 art::TransferOutput::
616 writeRun(RunPrincipal& rp)
617 {
618  //
619  // Write an EndRun message.
620  //
621  TLOG(TLVL_TRACE) << " Begin: TransferOutput::writeRun(const RunPrincipal& rp)";
622  (void)rp;
623  if (!initMsgSent_)
624  {
625  send_init_message();
626  initMsgSent_ = true;
627  }
628 #if 0
629  //
630  // Fetch the class dictionaries we need for
631  // writing out the auxiliary information.
632  //
633  static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
634  assert(run_aux_class != nullptr && "writeRun: Could not get TClass for "
635  "art::RunAuxiliary!");
636  //
637  // Begin preparing message.
638  //
639  TBufferFile msg(TBuffer::kWrite);
640  msg.SetWriteMode();
641  //
642  // Write message type code.
643  //
644  {
645  TLOG(TLVL_TRACE) << " writeRun: streaming message type code ...");
646  msg.WriteULong(2);
647  TLOG(TLVL_TRACE) << " writeRun: finished streaming message type code.");
648  }
649  //
650  // Write RunAuxiliary.
651  //
652  {
653  TLOG(TLVL_TRACE) << " writeRun: streaming RunAuxiliary ...");
654  if (art::debugit() >= 1)
655  {
656  TLOG(TLVL_TRACE) << " writeRun: dumping ProcessHistoryRegistry ...");
657  //typedef std::map<const ProcessHistoryID,ProcessHistory>
658  // ProcessHistoryMap;
659  art::ProcessHistoryMap const& phr =
660  art::ProcessHistoryRegistry::get();
661  TLOG(TLVL_TRACE) << " writeRun: phr: size: " << phr.size() << '\n';
662  for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
663  {
664  std::ostringstream OS;
665  I->first.print(OS);
666  TLOG(TLVL_TRACE) << " writeRun: phr: id: '" << OS.str() << "'");
667  OS.str("");
668  TLOG(TLVL_TRACE) << " writeRun: phr: data.size(): "
669  << I->second.data().size() << '\n';
670  if (I->second.data().size())
671  {
672  I->second.data().back().id().print(OS);
673  TLOG(TLVL_TRACE) << " writeRun: phr: data.back().id(): '"
674  << OS.str() << "'");
675  }
676  }
677  if (!rp.aux().processHistoryID().isValid())
678  {
679  TLOG(TLVL_TRACE) << " writeRun: ProcessHistoryID: 'INVALID'");
680  }
681  else
682  {
683  std::ostringstream OS;
684  rp.aux().processHistoryID().print(OS);
685  TLOG(TLVL_TRACE) << " writeRun: ProcessHistoryID: '"
686  << OS.str() << "'");
687  OS.str("");
688  const ProcessHistory& processHistory =
689  ProcessHistoryRegistry::get(rp.aux().processHistoryID());
690  if (processHistory.data().size())
691  {
692  // FIXME: Print something special on invalid id() here!
693  processHistory.data().back().id().print(OS);
694  TLOG(TLVL_TRACE) << " writeRun: ProcessConfigurationID: '"
695  << OS.str() << "'");
696  OS.str("");
697  TLOG(TLVL_TRACE) << " writeRun: ProcessConfiguration: '"
698  << processHistory.data().back() << '\n';
699  }
700  }
701  }
702  msg.WriteObjectAny(&rp.aux(), run_aux_class);
703  TLOG(TLVL_TRACE) << " writeRun: streamed RunAuxiliary.");
704  }
705  //
706  // Write data products.
707  //
708  std::vector<BranchKey*> bkv;
709  writeDataProducts(msg, rp, bkv);
710  //
711  // Send message.
712  //
713  {
714  TLOG(TLVL_TRACE) << " writeRun: sending a message ...");
715  sendMessage_(0, artdaq::Fragment::EndOfRunFragmentType, msg);
716  TLOG(TLVL_TRACE) << " writeRun: message sent.");
717  }
718  //
719  // Delete the branch keys we created for the message.
720  //
721  for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
722  {
723  delete *I;
724  *I = 0;
725  }
726 #endif // 0
727  TLOG(TLVL_TRACE) << " End: TransferOutput::writeRun(const RunPrincipal& rp)";
728 }
729 
730 void
731 art::TransferOutput::writeSubRun(SubRunPrincipal& srp)
732 {
733  //
734  // Write an EndSubRun message.
735  //
736  TLOG(TLVL_TRACE) << " Begin: TransferOutput::"
737  "writeSubRun(const SubRunPrincipal& srp)";
738  if (!initMsgSent_)
739  {
740  send_init_message();
741  initMsgSent_ = true;
742  }
743  //
744  // Fetch the class dictionaries we need for
745  // writing out the auxiliary information.
746  //
747  static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
748  if (subrun_aux_class == nullptr)
749  {
750  throw art::Exception(art::errors::DictionaryNotFound) <<
751  "TransferOutput::writeSubRun: "
752  "Could not get TClass for art::SubRunAuxiliary!";
753  }
754  //
755  // Begin preparing message.
756  //
757  TBufferFile msg(TBuffer::kWrite);
758  msg.SetWriteMode();
759  //
760  // Write message type code.
761  //
762  {
763  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
764  "streaming message type code ...";
765  msg.WriteULong(3);
766  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
767  "finished streaming message type code.";
768  }
769  //
770  // Write SubRunAuxiliary.
771  //
772  {
773  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
774  "streaming SubRunAuxiliary ...";
775  if (art::debugit() >= 1)
776  {
777  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
778  "dumping ProcessHistoryRegistry ...";
779  //typedef std::map<const ProcessHistoryID,ProcessHistory>
780  // ProcessHistoryMap;
781  for (auto I = std::begin(art::ProcessHistoryRegistry::get())
782  , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I)
783  {
784  std::ostringstream OS;
785  I->first.print(OS);
786  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
787  "phr: id: '" + OS.str() + "'";
788  OS.str("");
789  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
790  "phr: data.size(): " << I->second.data().size();
791  if (I->second.data().size())
792  {
793  I->second.data().back().id().print(OS);
794  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
795  "phr: data.back().id(): '"
796  + OS.str() + "'";
797  }
798  }
799  if (!srp.aux().processHistoryID().isValid())
800  {
801  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
802  "ProcessHistoryID: 'INVALID'";;
803  }
804  else
805  {
806  std::ostringstream OS;
807  srp.aux().processHistoryID().print(OS);
808  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: ProcessHistoryID: '"
809  + OS.str() + "'";
810  OS.str("");
811  ProcessHistory processHistory;
812  ProcessHistoryRegistry::get(srp.aux().processHistoryID(), processHistory);
813  if (processHistory.data().size())
814  {
815  // FIXME: Print something special on invalid id() here!
816  processHistory.data().back().id().print(OS);
817  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
818  "ProcessConfigurationID: '"
819  + OS.str() + "'";
820  OS.str("");
821  OS << processHistory.data().back();
822  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
823  "ProcessConfiguration: '"
824  + OS.str();
825  }
826  }
827  }
828  msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
829  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: streamed SubRunAuxiliary.";
830  }
831  //
832  // Write data products.
833  //
834  std::vector<BranchKey*> bkv;
835  writeDataProducts(msg, srp, bkv);
836  //
837  // Send message.
838  //
839  {
840  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
841  "Sending the EndOfSubrun message.";
842  sendMessage_(0, artdaq::Fragment::EndOfSubrunFragmentType, msg);
843  TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
844  "EndOfSubrun message(s) sent.";
845 
846  }
847  //
848  // Delete the branch keys we created for the message.
849  //
850  for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
851  {
852  delete *I;
853  *I = 0;
854  }
855  TLOG(TLVL_TRACE) << " End: TransferOutput::writeSubRun(const SubRunPrincipal& srp)";
856  }
857 
858 
859 void
860 art::TransferOutput::sendMessage_(uint64_t sequenceId, uint8_t messageType, TBufferFile& msg)
861 {
862  TLOG(TLVL_DEBUG) << "Sending message with sequenceID=" << sequenceId << ", type=" << (int)messageType << ", length=" << msg.Length();
863  artdaq::NetMonHeader header;
864  header.data_length = static_cast<uint64_t>(msg.Length());
865  artdaq::Fragment
866  fragment(std::ceil(msg.Length() /
867  static_cast<double>(sizeof(artdaq::RawDataType))),
868  sequenceId, 0, messageType, header);
869 
870  memcpy(&*fragment.dataBegin(), msg.Buffer(), msg.Length());
872  size_t retries = 0;
873  while (sts != artdaq::TransferInterface::CopyStatus::kSuccess && retries <= send_retry_count_)
874  {
875  sts = transfer_->transfer_fragment_min_blocking_mode(fragment, send_timeout_us_);
876  retries++;
877  }
878 
879 #if 0
880  if (messageType == artdaq::Fragment::InitFragmentType)
881  {
882  std::fstream ostream("sendInitMessage_TransferOutput.bin", std::ios::out | std::ios::binary);
883  ostream.write(msg.Buffer(), msg.Length());
884  ostream.close();
885  }
886 #endif
887 
888 }
889 
890 DEFINE_ART_MODULE(art::TransferOutput)
~TransferOutput()
TransferOutput Destructor.
std::unique_ptr< artdaq::TransferInterface > MakeTransferPlugin(const fhicl::ParameterSet &pset, std::string plugin_label, TransferInterface::Role role)
Load a TransferInterface plugin.
TransferOutput(fhicl::ParameterSet const &ps)
TransferOutput Constructor.
Header with length information for NetMonTransport messages.
Definition: NetMonHeader.hh:14
An art::OutputModule which sends events using DataSenderManager. This module is designed for transpor...
This TransferInterface is a Sender.
Some error occurred, but no exception was thrown.
The send operation completed successfully.
uint64_t data_length
The length of the message.
Definition: NetMonHeader.hh:16