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