19#if defined(__FastCaloSimStandAlone__)
20#include "CLHEP/Random/TRandomEngine.h"
22#include <CLHEP/Random/RanluxEngine.h>
38#include "CLHEP/Random/RandFlat.h"
62 float e_init,
long unsigned int reference_layer_index)
const {
64 (void)reference_layer_index;
73 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash, event_ptr);
74 simulstate.
setAuxInfo<
float>(
"BSEinit"_FCShash, e_init);
80 const std::string &filename, std::vector<long unsigned int> &layers) {
89 for (
long unsigned int layer_index : layers) {
91 ATH_MSG_INFO(
"Loading layer " << layer_index <<
" from file: " << filename);
100std::tuple<std::vector<float>, std::vector<hsize_t>,
bool>
102 const std::string &datasetname) {
105 H5::H5File
file(filename, H5F_ACC_RDONLY);
108 if (!
file.exists(datasetname)) {
109 return std::make_tuple(std::vector<float>{}, std::vector<hsize_t>{},
false);
112 H5::DataSet
dataset =
file.openDataSet(datasetname);
115 H5::DataSpace dataspace =
dataset.getSpace();
118 int rank = dataspace.getSimpleExtentNdims();
119 std::vector<hsize_t> dims_out(rank);
120 dataspace.getSimpleExtentDims(dims_out.data(), NULL);
124 for (
const auto &dim : dims_out) {
130 dataset.read(data.data(), H5::PredType::NATIVE_FLOAT);
132 return std::make_tuple(data, dims_out,
true);
136 long unsigned int layer_index) {
143 std::vector<std::string> datasetnames = {
144 "binstart_radius_layer_",
"binsize_radius_layer_",
145 "binstart_alpha_layer_",
"binsize_alpha_layer_"};
147 for (
long unsigned int i = 0; i < datasetnames.size(); i++) {
148 std::string datasetname = datasetnames.at(i) + std::to_string(layer_index);
149 std::vector<float> data;
150 std::vector<hsize_t> dims;
154 ATH_MSG_ERROR(
"Error while extracting the bin boundaries for layer "
155 << layer_index <<
" from " << filename <<
"."
156 <<
"Specifically, the key " << datasetname
157 <<
" could not be loaded.");
165 event_bins.R_lower = std::move(data);
168 event_bins.R_size = std::move(data);
171 event_bins.alpha_lower = std::move(data);
174 event_bins.alpha_size = std::move(data);
181void TFCSBinnedShowerONNX::Streamer(TBuffer &R__b) {
184 if (R__b.IsReading()) {
185 R__b.ReadClassBuffer(TFCSBinnedShowerONNX::Class(),
this);
189 R__b.WriteClassBuffer(TFCSBinnedShowerONNX::Class(),
this);
194 const std::vector<float>& R_lower,
195 const std::vector<float>& R_size,
196 const std::vector<float>& alpha_lower,
197 const std::vector<float>& alpha_size) {
212 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
213 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
216 long unsigned int n_layers =
event->event_data.size();
217 std::vector<std::vector<long unsigned int>> hits_per_layer;
218 std::vector<float> elayer;
219 hits_per_layer.resize(n_layers);
220 elayer.resize(n_layers, 0.0f);
222 for (
long unsigned int layer_index = 0; layer_index < n_layers;
228 long unsigned int n_hits = 0;
229 for (
float e_voxel : layer.E_vector) {
230 long unsigned int hits_per_bin;
231 if (e_voxel > std::numeric_limits<float>::epsilon()) {
235 elayer.at(layer_index) += e_voxel * e_init;
240 n_hits += hits_per_bin;
241 hits_per_layer.at(layer_index).push_back(n_hits);
245 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
246 new std::vector<std::vector<long unsigned int>>(std::move(hits_per_layer));
247 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash, hits_per_layer_ptr);
250 std::vector<float> *elayer_ptr =
new std::vector<float>(std::move(elayer));
251 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash, elayer_ptr);
257 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
258 static_cast<std::vector<std::vector<long unsigned int>
> *>(
259 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
261 if (!hits_per_layer_ptr) {
266 return hits_per_layer_ptr->at(layer_index).back();
271 std::vector<float> *elayer_ptr =
static_cast<std::vector<float> *
>(
272 simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash));
277 if (layer_index >= elayer_ptr->size()) {
282 <<
": " << elayer_ptr->at(layer_index));
284 return elayer_ptr->at(layer_index);
289 long unsigned int hit_index)
const {
290 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
291 static_cast<std::vector<std::vector<long unsigned int>
> *>(
292 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
293 if (!hits_per_layer_ptr) {
298 if (layer_index >= hits_per_layer_ptr->size()) {
299 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
300 << hits_per_layer_ptr->size());
305 const std::vector<long unsigned int> &hits =
306 hits_per_layer_ptr->at(layer_index);
307 auto it = std::upper_bound(hits.begin(), hits.end(), hit_index);
308 long unsigned int energy_index = std::distance(hits.begin(), it);
310 if (energy_index >= hits.size()) {
312 <<
" >= " << hits.size());
315 for (
const auto &hit : hits) {
326 int bin_index)
const {
327 float R_min =
m_coordinates.at(layer_index).R_lower.at(bin_index);
328 float R_max =
m_coordinates.at(layer_index).R_size.at(bin_index) +
331 float alpha_min =
m_coordinates.at(layer_index).alpha_lower.at(bin_index);
332 float alpha_max =
m_coordinates.at(layer_index).alpha_size.at(bin_index) +
336 upscale(simulstate, R_min, R_max, alpha_min, alpha_max, layer_index,
340 float R = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), R_min, R_max);
342 CLHEP::RandFlat::shoot(simulstate.
randomEngine(), alpha_min, alpha_max);
344 return std::make_tuple(R, alpha);
348 float &R_min,
float &R_max,
float &alpha_min,
350 long unsigned int layer_index,
351 int bin_index)
const {
353 float p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
355 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
358 unsigned int e_index = 0;
360 std::vector<float> probabilities = {0.25f, 0.5f, 0.75f};
362 if (available_energies.size() > 1) {
364 auto it = std::upper_bound(available_energies.begin(),
365 available_energies.end(), e_init);
366 if (it != available_energies.end()) {
367 e_index = std::distance(available_energies.begin(), it);
369 e_index = available_energies.size() - 1;
372 float e_high = available_energies.at(e_index);
373 if (e_high < e_init || e_index == 0) {
381 float e_low = available_energies.at(e_index - 1);
382 float f_low = std::log(e_high / e_init) / (std::log(e_high / e_low));
383 float f_high = 1 - f_low;
384 for (
unsigned int i = 0; i < 3; ++i) {
393 probabilities[i] = f_low * p_low + f_high * p_high;
399 else if (available_energies.size() == 1) {
403float p_alpha_low = probabilities[2] - probabilities[1] + probabilities[0];
406 if (p < p_alpha_low) {
407 alpha_max = (alpha_min + alpha_max) / 2.;
408 p_r = probabilities[0] / (p_alpha_low);
410 alpha_min = (alpha_min + alpha_max) / 2.;
411 p_r = (probabilities[1] - probabilities[0]) / (1 - p_alpha_low);
414 p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
415 if (layer_index != 2){
418 R_min = (R_min + R_max) / 2.;
421 R_max = (R_min + R_max) / 2.;
431 }
else if (p_r > 0.75) {
433 }
else if (TMath::Abs(p_r - 0.5) < std::numeric_limits<float>::epsilon()) {
438 float r = (1. - 4. * p_r) / (2. - 4. * p_r) -
439 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
440 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
441 p / ((1. / 2.) - p_r));
443 r = (1. - 4. * p_r) / (2. - 4. * p_r) +
444 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
445 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
446 p / ((1. / 2.) - p_r));
449 R_min = R_min +
r / 2 * (R_max - R_min);
453std::tuple<float, float, float>
456 long unsigned int hit_index)
const {
460 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
462 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
464 if (layer_index >= event->event_data.size()) {
465 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
466 << event->event_data.size());
467 return std::make_tuple(0.0f, 0.0f, 0.0f);
471 simulstate, layer_index, hit_index);
473 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
474 static_cast<std::vector<std::vector<long unsigned int>
> *>(
475 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
477 long unsigned int hits_per_bin;
478 if (energy_index == 0) {
479 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index);
481 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index) -
482 hits_per_layer_ptr->at(layer_index).at(energy_index - 1);
490 layer.bin_index_vector.at(energy_index));
492 float E = layer.E_vector.at(energy_index) * e_init / hits_per_bin;
494 return std::make_tuple(
r, alpha, E);
499 void *event_ptr = simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash);
502 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash,
nullptr);
507 void *n_hits_ptr = simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash);
509 delete static_cast<std::vector<std::vector<long unsigned int>
> *>(
511 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash,
nullptr);
516 void *elayer_ptr = simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash);
518 delete static_cast<std::vector<float> *
>(elayer_ptr);
519 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash,
nullptr);
521 ATH_MSG_ERROR(
"No event layer energy data found to delete.");
528 const std::string &filename) {
530 TFile *
file = TFile::Open(filename.c_str(),
"READ");
537 std::regex pattern(R
"(probabilities_layer_(\d+)_energy_([0-9.]+))");
538 std::map<float, std::map<int, std::vector<std::vector<float>>>> temp_storage;
540 TIter next(file->GetListOfKeys());
543 while ((key = (TKey *)next())) {
544 std::string keyname = key->GetName();
546 if (std::regex_match(keyname,
match, pattern)) {
547 int layer = std::stoi(
match[1].
str());
548 float energy = std::stod(
match[2].
str());
550 TMatrixD *matrix =
dynamic_cast<TMatrixD *
>(
file->Get(keyname.c_str()));
552 std::vector<std::vector<float>> mat_vec(
553 matrix->GetNrows(), std::vector<float>(matrix->GetNcols()));
554 for (
int i = 0; i < matrix->GetNrows(); ++i) {
555 for (
int j = 0; j < matrix->GetNcols(); ++j) {
556 mat_vec[i][j] =
static_cast<float>((*matrix)(i, j));
559 temp_storage[energy][layer] = std::move(mat_vec);
568 std::vector<float> energies;
569 std::vector<std::vector<std::vector<std::vector<float>>>>
572 for (
const auto &[energy, layer_map] : temp_storage) {
573 energies.push_back(energy);
575 for (
const auto &[l, _] : layer_map)
576 max_layer = std::max(max_layer, l);
578 std::vector<std::vector<std::vector<float>>> layer_vec(max_layer + 1);
579 for (
const auto &[layer_idx, mat] : layer_map) {
580 layer_vec[layer_idx] = mat;
582 data.push_back(std::move(layer_vec));
586 for (
size_t i = 0; i < energies.size(); ++i) {
587 std::cout <<
"Energy index " << i <<
": " << energies[i] <<
" GeV\n";
588 for (
size_t j = 0; j < data[i].size(); ++j) {
589 if (!data[i][j].
empty()) {
590 std::cout <<
" Layer " << j <<
" Shape: (" << data[i][j].size() <<
", "
591 << data[i][j][0].size() <<
")\n";
static unsigned int totalSize(const MultiDimArray< T, N > &ht)
static const Attributes_t empty
TFCSBinnedShowerBase(const char *name=nullptr, const char *title=nullptr)
virtual void compute_n_hits_and_elayer(TFCSSimulationState &simulstate) const
long unsigned int get_energy_index(TFCSSimulationState &simulstate, long unsigned int layer_index, long unsigned int hit_index) const
void load_bin_boundaries(const std::string &filename, long unsigned int layer_index)
std::vector< float > m_upscaling_energies
std::vector< std::vector< std::vector< std::vector< float > > > > m_sub_bin_distribution
float m_default_hit_energy
TFCSMLCalorimeterSimulator * m_ai_simulator
const event_bins_t & get_coordinates()
virtual float get_layer_energy(TFCSSimulationState &simulstate, long unsigned int layer_index) const override
void load_sub_bin_distribution(const std::string &filename)
void set_bin_boundaries(long unsigned int layer_index, const std::vector< float > &R_lower, const std::vector< float > &R_size, const std::vector< float > &alpha_lower, const std::vector< float > &alpha_size)
void upscale(TFCSSimulationState &simulstate, float &R_min, float &R_max, float &alpha_min, float &alpha_max, long unsigned int layer_index, int bin_index) const
TFCSBinnedShowerONNX(const char *name=nullptr, const char *title=nullptr)
virtual ~TFCSBinnedShowerONNX()
void load_meta_data(const std::string &filename, std::vector< long unsigned int > &layers)
std::tuple< std::vector< float >, std::vector< hsize_t >, bool > load_hdf5_dataset(const std::string &filename, const std::string &datasetname)
virtual void get_event(TFCSSimulationState &simulstate, float eta_center, float phi_center, float e_init, long unsigned int reference_layer_index) const override
do not persistify
virtual long unsigned int get_n_hits(TFCSSimulationState &simulstate, long unsigned int layer_index) const override
virtual std::tuple< float, float, float > get_hit_position_and_energy(TFCSSimulationState &simulstate, long unsigned int layer_index, long unsigned int hit_index) const override
event_bins_t m_coordinates
virtual void delete_event(TFCSSimulationState &simulstate) const override
const T getAuxInfo(std::uint32_t index) const
void setAuxInfo(std::uint32_t index, const T &val)
CLHEP::HepRandomEngine * randomEngine()
bool match(std::string s1, std::string s2)
match the individual directories of two strings