artdaq_demo  v2_10_00
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
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 
16 #include "cetlib/exception.h"
17 #include "fhiclcpp/ParameterSet.h"
18 
19 #include <fstream>
20 #include <iomanip>
21 #include <iterator>
22 #include <iostream>
23 
24 #include <unistd.h>
25 #include "trace.h" // TRACE
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  , readout_buffer_(nullptr)
34  , fragment_type_(static_cast<decltype(fragment_type_)>(artdaq::Fragment::InvalidFragmentType))
35  , distribution_type_(static_cast<ToyHardwareInterface::DistributionType>(ps.get<int>("distribution_type")))
36 {
37  hardware_interface_->AllocateReadoutBuffer(&readout_buffer_);
38 
39  metadata_.board_serial_number = hardware_interface_->SerialNumber();
40  metadata_.num_adc_bits = hardware_interface_->NumADCBits();
41 
42  switch (hardware_interface_->BoardType())
43  {
44  case 1002:
45  fragment_type_ = toFragmentType("TOY1");
46  break;
47  case 1003:
48  fragment_type_ = toFragmentType("TOY2");
49  break;
50  default:
51  throw cet::exception("ToySimulator") << "Unable to determine board type supplied by hardware";
52  }
53 }
54 
56 {
57  hardware_interface_->FreeReadoutBuffer(readout_buffer_);
58 }
59 
60 bool demo::ToySimulator::getNext_(artdaq::FragmentPtrs& frags)
61 {
62  if (should_stop())
63  {
64  return false;
65  }
66 
67  // ToyHardwareInterface (an instance to which "hardware_interface_"
68  // is a unique_ptr object) is just one example of the sort of
69  // interface a hardware library might offer. For example, other
70  // interfaces might require you to allocate and free the memory used
71  // to store hardware data in your generator using standard C++ tools
72  // (rather than via the "AllocateReadoutBuffer" and
73  // "FreeReadoutBuffer" functions provided here), or could have a
74  // function which directly returns a pointer to the data buffer
75  // rather than sticking the data in the location pointed to by your
76  // pointer (which is what happens here with readout_buffer_)
77 
78  std::size_t bytes_read = 0;
79  hardware_interface_->FillBuffer(readout_buffer_, &bytes_read);
80 
81  // We'll use the static factory function
82 
83  // artdaq::Fragment::FragmentBytes(std::size_t payload_size_in_bytes, sequence_id_t sequence_id,
84  // fragment_id_t fragment_id, type_t type, const T & metadata)
85 
86  // which will then return a unique_ptr to an artdaq::Fragment
87  // object.
88 
89 #if 1
90  std::unique_ptr<artdaq::Fragment> fragptr(
91  artdaq::Fragment::FragmentBytes(bytes_read,
92  ev_counter(), fragment_id(),
93  fragment_type_,
94  metadata_, timestamp_));
95  frags.emplace_back(std::move(fragptr));
96 #else
97  std::unique_ptr<artdaq::Fragment> fragptr(
98  artdaq::Fragment::FragmentBytes(/*bytes_read*/ 1024-40,
99  ev_counter(), fragment_id(),
100  fragment_type_,
101  metadata_, timestamp_));
102  frags.emplace_back(std::move(fragptr));
103  artdaq::detail::RawFragmentHeader *hdr = (artdaq::detail::RawFragmentHeader*)(frags.back()->headerBeginBytes());
104  // Need a way to fake frag->sizeBytes() (which calls frag->size() which calls fragmentHeader()->word_count
105  hdr->word_count = ceil( (bytes_read+32) / static_cast<double>(sizeof(artdaq::RawDataType)) );
106 #endif
107 
109  memcpy(frags.back()->dataBeginBytes(), readout_buffer_, bytes_read);
110 
111  TRACE( 50, "ToySimulator::getNext_ after memcpy %zu bytes and std::move dataSizeBytes()=%zu metabytes=%zu", bytes_read, frags.back()->sizeBytes(), sizeof(metadata_) );
112 
113  if (metricMan != nullptr)
114  {
115  metricMan->sendMetric("Fragments Sent", ev_counter(), "Events", 3);
116  }
117 
118  ev_counter_inc();
119  timestamp_ += timestampScale_;
120 
121  return true;
122 }
123 
124 void demo::ToySimulator::start()
125 {
126  hardware_interface_->StartDatataking();
127 }
128 
129 void demo::ToySimulator::stop()
130 {
131  hardware_interface_->StopDatataking();
132 }
133 
134 // The following macro is defined in artdaq's GeneratorMacros.hh header
135 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