00001
00002
00003
00004
00005 #include "artdaq-demo/Generators/ToySimulator.hh"
00006
00007 #include "canvas/Utilities/Exception.h"
00008
00009 #include "artdaq/Application/GeneratorMacros.hh"
00010 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh"
00011
00012 #include "artdaq-core-demo/Overlays/ToyFragment.hh"
00013 #include "artdaq-core-demo/Overlays/FragmentType.hh"
00014
00015 #include "fhiclcpp/ParameterSet.h"
00016
00017 #include <fstream>
00018 #include <iomanip>
00019 #include <iterator>
00020 #include <iostream>
00021
00022 #include <unistd.h>
00023 #define TRACE_NAME "ToySimulator"
00024 #include "tracemf.h"
00025 #include "cetlib_except/exception.h"
00026
00027 demo::ToySimulator::ToySimulator(fhicl::ParameterSet const& ps)
00028 :
00029 CommandableFragmentGenerator(ps)
00030 , hardware_interface_(new ToyHardwareInterface(ps))
00031 , timestamp_(0)
00032 , timestampScale_(ps.get<int>("timestamp_scale_factor", 1))
00033 , rollover_subrun_interval_(ps.get<int>("rollover_subrun_interval", 0))
00034 , metadata_({ 0,0,0 })
00035 , readout_buffer_(nullptr)
00036 , fragment_type_(static_cast<decltype(fragment_type_)>(artdaq::Fragment::InvalidFragmentType))
00037 , distribution_type_(static_cast<ToyHardwareInterface::DistributionType>(ps.get<int>("distribution_type")))
00038 , generated_fragments_per_event_(ps.get<int>("generated_fragments_per_event", 1))
00039 {
00040 hardware_interface_->AllocateReadoutBuffer(&readout_buffer_);
00041
00042 metadata_.board_serial_number = hardware_interface_->SerialNumber() & 0xFFFF;
00043 metadata_.num_adc_bits = hardware_interface_->NumADCBits();
00044 TLOG(TLVL_INFO) << "Constructor: metadata_.unused = 0x" << std::hex << metadata_.unused << " sizeof(metadata_) = " << std::dec << sizeof(metadata_);
00045
00046 switch (hardware_interface_->BoardType())
00047 {
00048 case 1002:
00049 fragment_type_ = toFragmentType("TOY1");
00050 break;
00051 case 1003:
00052 fragment_type_ = toFragmentType("TOY2");
00053 break;
00054 default:
00055 throw cet::exception("ToySimulator") << "Unable to determine board type supplied by hardware";
00056 }
00057 }
00058
00059 demo::ToySimulator::~ToySimulator()
00060 {
00061 hardware_interface_->FreeReadoutBuffer(readout_buffer_);
00062 }
00063
00064 bool demo::ToySimulator::getNext_(artdaq::FragmentPtrs& frags)
00065 {
00066 if (should_stop())
00067 {
00068 return false;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 std::size_t bytes_read = 0;
00083 hardware_interface_->FillBuffer(readout_buffer_, &bytes_read);
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #if 1
00094 for (auto i_f = 0; i_f < generated_fragments_per_event_; ++i_f) {
00095
00096
00097
00098
00099
00100
00101 auto offset = i_f == 0 ? 0 : i_f + 10000;
00102 std::unique_ptr<artdaq::Fragment> fragptr(
00103 artdaq::Fragment::FragmentBytes(bytes_read,
00104 ev_counter(),
00105 fragment_id() + offset,
00106 fragment_type_,
00107 metadata_, timestamp_));
00108 frags.emplace_back(std::move(fragptr));
00109 }
00110 #else
00111 std::unique_ptr<artdaq::Fragment> fragptr(
00112 artdaq::Fragment::FragmentBytes( 1024 - 40,
00113 ev_counter(), fragment_id(),
00114 fragment_type_,
00115 metadata_, timestamp_));
00116 frags.emplace_back(std::move(fragptr));
00117 artdaq::detail::RawFragmentHeader *hdr = (artdaq::detail::RawFragmentHeader*)(frags.back()->headerBeginBytes());
00118
00119 hdr->word_count = ceil((bytes_read + 32) / static_cast<double>(sizeof(artdaq::RawDataType)));
00120 #endif
00121
00122 if ( !frags.empty() ) {
00123
00124 if (distribution_type_ != ToyHardwareInterface::DistributionType::uninitialized)
00125 memcpy(frags.back()->dataBeginBytes(), readout_buffer_, bytes_read);
00126 else
00127 {
00128
00129 memcpy(frags.back()->dataBeginBytes(), readout_buffer_, sizeof(ToyFragment::Header));
00130 }
00131
00132 TLOG(50) << "getNext_ after memcpy " << bytes_read
00133 << " bytes and std::move dataSizeBytes()=" << frags.back()->sizeBytes() << " metabytes=" << sizeof(metadata_);
00134 }
00135
00136 if (metricMan != nullptr)
00137 {
00138 metricMan->sendMetric("Fragments Sent", ev_counter(), "Events", 3, artdaq::MetricMode::LastPoint);
00139 }
00140
00141 ev_counter_inc();
00142 timestamp_ += timestampScale_;
00143
00144 if (rollover_subrun_interval_ > 0 && ev_counter() % rollover_subrun_interval_ == 0 && fragment_id() == 0)
00145 {
00146 artdaq::FragmentPtr endOfSubrunFrag(new artdaq::Fragment(static_cast<size_t>(ceil(sizeof(my_rank) / static_cast<double>(sizeof(artdaq::Fragment::value_type))))));
00147 endOfSubrunFrag->setSystemType(artdaq::Fragment::EndOfSubrunFragmentType);
00148 endOfSubrunFrag->setSequenceID(ev_counter());
00149 *endOfSubrunFrag->dataBegin() = my_rank;
00150 frags.emplace_back(std::move(endOfSubrunFrag));
00151 }
00152
00153
00154 return true;
00155 }
00156
00157 void demo::ToySimulator::start()
00158 {
00159 hardware_interface_->StartDatataking();
00160 timestamp_ = 0;
00161 }
00162
00163 void demo::ToySimulator::stop()
00164 {
00165 hardware_interface_->StopDatataking();
00166 }
00167
00168
00169 DEFINE_ARTDAQ_COMMANDABLE_GENERATOR(demo::ToySimulator)