31#include <fmt/format.h>
49std::array<int, 156> getDeIds()
51 static std::array<int, 156> deids;
52 static bool first =
true;
63std::array<int, 156> getNofPads()
65 static bool first =
true;
66 static std::array<int, 156> npads;
69 auto deids = getDeIds();
70 for (
auto deid : deids) {
72 int16_t nofPads =
static_cast<int16_t
>(
seg.
nofPads());
92 if (mOccupancy <= 0.0 || mOccupancy > 1.0) {
93 throw std::invalid_argument(
"occupancy must be between >0 and <=1");
99 std::random_device
rd;
102 mMersenneTwister.seed(mSeed);
105 "Will generate {:7.2f}% of pads in {:4d} ROFs "
106 "per timeframe, for {:4d} timeframes",
119 std::vector<Digit>
digits;
120 std::vector<ROFRecord> rofs;
123 for (
auto i = 0;
i < mNofRofPerTimeFrame;
i++) {
126 rofs.emplace_back(
ir, ndigits,
n);
154 std::vector<Digit>&
digits)
157 std::uniform_int_distribution<int32_t>
adc{0, 1024 * 1024};
158 std::uniform_int_distribution<int32_t> tfTime{0, 512 * 3564};
159 std::uniform_int_distribution<int32_t> nofSamples{0, 1023};
160 std::uniform_real_distribution<float> sat{0.0, 1.0};
162 auto deids = getDeIds();
163 auto nofPadsPerDe = getNofPads();
164 auto& mt = mMersenneTwister;
166 for (
auto i = 0;
i < deids.size();
i++) {
167 auto deid = deids[
i];
168 int16_t nofPads =
static_cast<int16_t
>(nofPadsPerDe[
i]);
169 std::uniform_int_distribution<int16_t> padid{0, nofPads};
170 int nch = nofPads * occupancy;
171 for (
int i = 0;
i < nch;
i++) {
173 bool isSaturated = (sat(mt) > 0.9);
174 digits.emplace_back(deid, p, tfTime(mt),
adc(mt), nofSamples(mt), isSaturated);
182 float mOccupancy = 1.0;
185 int mNofRofPerTimeFrame = 100;
187 std::mt19937 mMersenneTwister;
198 {
OPTNAME_OCCUPANCY, VariantType::Float, 0.01f, {
"occupancy (fraction of fired pad per DE per ROF)"}},
199 {
OPTNAME_SEED, VariantType::Int, 0, {
"seed for number generator (if 0 use default_seed)"}},
201 options.insert(options.end(), commonOptions.begin(), commonOptions.end());
205 "mch-digits-random-generator",
208 OutputSpec{{
"rofs"},
"MCH",
"DIGITROFS", 0, Lifetime::Timeframe}},
o2::mch::mapping::CathodeSegmentation seg
void init(InitContext &ic)
void run(ProcessingContext &pc)
int generateRandomDigits(float occupancy, std::vector< Digit > &digits)
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
ServiceRegistryRef services()
The services registry associated with this processing context.
void printFull(gsl::span< const Digit > digits, gsl::span< const ROFRecord > rofs) const
void printSummary(gsl::span< const Digit > digits, gsl::span< const ROFRecord > rofs, const char *suffix="") const
void init(o2::framework::InitContext &ic)
void incNofProcessedTFs()
bool shouldProcess() const
A Segmentation lets you find pads of a detection element and then inspect those pads.
WorkflowSpec defineDataProcessing(const ConfigContext &cc)
constexpr const char * OPTNAME_OCCUPANCY
constexpr const char * OPTNAME_NOF_ROFS_PER_TF
constexpr const char * OPTNAME_SEED
Defining PrimaryVertex explicitly as messageable.
std::vector< DataProcessorSpec > WorkflowSpec
std::vector< InputSpec > Inputs
std::vector< OutputSpec > Outputs
std::vector< ConfigParamSpec > getCommonOptions()
void forEachDetectionElement(CALLABLE &&func)
std::vector< o2::mch::ChannelCode > cc
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits