artdaq_demo  v3_01_00
ToySimulator_generator.cc
1 // For an explanation of this class, look at its header,
2 // ToySimulator.hh, as well as
3 // https://cdcvs.fnal.gov/redmine/projects/artdaq-demo/wiki/Fragments_and_FragmentGenerators_w_Toy_Fragments_as_Examples
4 
5 #include "artdaq-demo/Generators/ToySimulator.hh"
6 
7 #include "canvas/Utilities/Exception.h"
8 
9 #include "artdaq/Application/GeneratorMacros.hh"
10 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh"
11 
12 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
13 #include "artdaq-core-demo/Overlays/FragmentType.hh"
14 
15 #include "fhiclcpp/ParameterSet.h"
16 
17 #include <fstream>
18 #include <iomanip>
19 #include <iterator>
20 #include <iostream>
21 
22 #include <unistd.h>
23 #define TRACE_NAME "ToySimulator"
24 #include "tracemf.h" // TRACE, TLOG*
25 #include "cetlib_except/exception.h"
26 
27 demo::ToySimulator::ToySimulator(fhicl::ParameterSet const& ps)
28  :
29  CommandableFragmentGenerator(ps)
30  , hardware_interface_(new ToyHardwareInterface(ps))
31  , timestamp_(0)
32  , timestampScale_(ps.get<int>("timestamp_scale_factor", 1))
33  , metadata_({0,0,0})
34  , readout_buffer_(nullptr)
35  , fragment_type_(static_cast<decltype(fragment_type_)>(artdaq::Fragment::InvalidFragmentType))
36  , distribution_type_(static_cast<ToyHardwareInterface::DistributionType>(ps.get<int>("distribution_type")))
37 {
38  hardware_interface_->AllocateReadoutBuffer(&readout_buffer_);
39 
40  metadata_.board_serial_number = hardware_interface_->SerialNumber();
41  metadata_.num_adc_bits = hardware_interface_->NumADCBits();
42  TLOG(TLVL_INFO) << "Constructor: metadata_.unused = 0x" << std::hex << metadata_.unused << " sizeof(metadata_) = " << std::dec << sizeof(metadata_);
43 
44  switch (hardware_interface_->BoardType())
45  {
46  case 1002:
47  fragment_type_ = toFragmentType("TOY1");
48  break;
49  case 1003:
50  fragment_type_ = toFragmentType("TOY2");
51  break;
52  default:
53  throw cet::exception("ToySimulator") << "Unable to determine board type supplied by hardware";
54  }
55 }
56 
58 {
59  hardware_interface_->FreeReadoutBuffer(readout_buffer_);
60 }
61 
62 bool demo::ToySimulator::getNext_(artdaq::FragmentPtrs& frags)
63 {
64  if (should_stop())
65  {
66  return false;
67  }
68 
69  // ToyHardwareInterface (an instance to which "hardware_interface_"
70  // is a unique_ptr object) is just one example of the sort of
71  // interface a hardware library might offer. For example, other
72  // interfaces might require you to allocate and free the memory used
73  // to store hardware data in your generator using standard C++ tools
74  // (rather than via the "AllocateReadoutBuffer" and
75  // "FreeReadoutBuffer" functions provided here), or could have a
76  // function which directly returns a pointer to the data buffer
77  // rather than sticking the data in the location pointed to by your
78  // pointer (which is what happens here with readout_buffer_)
79 
80  std::size_t bytes_read = 0;
81  hardware_interface_->FillBuffer(readout_buffer_, &bytes_read);
82 
83  // We'll use the static factory function
84 
85  // artdaq::Fragment::FragmentBytes(std::size_t payload_size_in_bytes, sequence_id_t sequence_id,
86  // fragment_id_t fragment_id, type_t type, const T & metadata)
87 
88  // which will then return a unique_ptr to an artdaq::Fragment
89  // object.
90 
91 #if 1
92  std::unique_ptr<artdaq::Fragment> fragptr(
93  artdaq::Fragment::FragmentBytes(bytes_read,
94  ev_counter(), fragment_id(),
95  fragment_type_,
96  metadata_, timestamp_));
97  frags.emplace_back(std::move(fragptr));
98 #else
99  std::unique_ptr<artdaq::Fragment> fragptr(
100  artdaq::Fragment::FragmentBytes(/*bytes_read*/ 1024 - 40,
101  ev_counter(), fragment_id(),
102  fragment_type_,
103  metadata_, timestamp_));
104  frags.emplace_back(std::move(fragptr));
105  artdaq::detail::RawFragmentHeader *hdr = (artdaq::detail::RawFragmentHeader*)(frags.back()->headerBeginBytes());
106  // Need a way to fake frag->sizeBytes() (which calls frag->size() which calls fragmentHeader()->word_count
107  hdr->word_count = ceil((bytes_read + 32) / static_cast<double>(sizeof(artdaq::RawDataType)));
108 #endif
109 
111  memcpy(frags.back()->dataBeginBytes(), readout_buffer_, bytes_read);
112 
113  TLOG(50) << "getNext_ after memcpy " << std::to_string(bytes_read)
114  << " bytes and std::move dataSizeBytes()=" << std::to_string(frags.back()->sizeBytes()) << " metabytes=" << std::to_string(sizeof(metadata_)) ;
115 
116  if (metricMan != nullptr)
117  {
118  metricMan->sendMetric("Fragments Sent", ev_counter(), "Events", 3, artdaq::MetricMode::LastPoint);
119  }
120 
121  ev_counter_inc();
122  timestamp_ += timestampScale_;
123 
124  return true;
125 }
126 
127 void demo::ToySimulator::start()
128 {
129  hardware_interface_->StartDatataking();
130  timestamp_ = 0;
131 }
132 
133 void demo::ToySimulator::stop()
134 {
135  hardware_interface_->StopDatataking();
136 }
137 
138 // The following macro is defined in artdaq's GeneratorMacros.hh header
139 DEFINE_ARTDAQ_COMMANDABLE_GENERATOR(demo::ToySimulator)
A use-after-free expliot distribution.
ToySimulator(fhicl::ParameterSet const &ps)
ToySimulator Constructor.
JCF, Mar-17-2016: ToyHardwareInterface is meant to mimic a vendor-provided hardware API...
virtual ~ToySimulator()
Shutdown the ToySimulator.
ToySimulator is a simple type of fragment generator intended to be studied by new users of artdaq as ...
Definition: ToySimulator.hh:37