19#if defined(__FastCaloSimStandAlone__)
20#include "CLHEP/Random/TRandomEngine.h"
22#include <CLHEP/Random/RanluxEngine.h>
38#include "CLHEP/Random/RandFlat.h"
55 long unsigned int event_index,
long unsigned int layer_index,
56 const std::vector<unsigned int>& bin_index_vector,
57 const std::vector<float>& E_vector) {
65 if (layer_index >=
m_eventlibrary.at(event_index).event_data.size()) {
71 layer.bin_index_vector = bin_index_vector;
72 layer.E_vector = E_vector;
76 std::vector<float>& R_lower,
77 std::vector<float>& R_size,
78 std::vector<float>& alpha_lower,
79 std::vector<float>& alpha_size) {
90 long unsigned int event_index,
long unsigned int reference_layer_index,
91 float eta_center,
float phi_center) {
95 reference_layer_index, eta_center);
97 m_geo->getDDE(reference_layer_index, eta_center, phi_center)->phi();
98 float phi_within_cell = fmod(phi_center - phi_cell, phi_cell_size);
99 if (phi_within_cell < 0) {
100 phi_within_cell += phi_cell_size;
107 reference_layer_index) {
108 m_eventlibrary.at(event_index).event_data.resize(reference_layer_index + 1);
115 float eta_center,
float phi_center,
float e_init,
116 long unsigned int reference_layer_index,
bool phi_mod_matching)
const {
118 float phi_cell_size, phi_within_cell;
120 if (phi_mod_matching) {
122 m_geo->getDDE(reference_layer_index, eta_center, phi_center);
124 reference_layer_index, eta_center);
126 float phi_cell = cellele->
phi();
127 phi_within_cell = phi_center - phi_cell;
129 phi_within_cell = fmod(phi_within_cell, phi_cell_size);
130 if (phi_within_cell < 0)
131 phi_within_cell += phi_cell_size;
135 float best_distance = std::numeric_limits<float>::max();
138 for (
long unsigned int event_index = 0; event_index <
m_eventlibrary.size();
148 std::log(
m_eventlibrary.at(event_index).e_init / e_init) / std::log(2);
151 float dist2 = eta_diff * eta_diff + e_diff * e_diff;
153 if (phi_mod_matching) {
155 float phi_diff = (phi_mod - phi_within_cell) / phi_cell_size;
156 dist2 = dist2 + phi_diff * phi_diff;
158 float distance = TMath::Sqrt(dist2);
160 if (distance < best_distance) {
161 best_distance = distance;
162 best_match = event_index;
170 << eta_center <<
" / "
180 float e_init,
long unsigned int reference_layer_index)
const {
184 "No event library loaded. Please load an event libray for "
185 "TFCSBinnedShower::get_event.");
189 simulstate.
setAuxInfo<
float>(
"BSEinit"_FCShash, e_init);
191 long unsigned int event_index;
193 event_index = simulstate.
getAuxInfo<
int>(
"EventNr"_FCShash);
201 event_index = std::floor(CLHEP::RandFlat::shoot(
206 event_index = std::floor(CLHEP::RandFlat::shoot(simulstate.
randomEngine(),
210 ATH_MSG_DEBUG(
"Using event index " << event_index <<
" for eta " << eta_center
211 <<
" and phi " << phi_center);
215 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash, event_ptr);
224 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
225 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
228 long unsigned int n_layers =
event->event_data.size();
229 std::vector<std::vector<long unsigned int>> hits_per_layer;
230 std::vector<float> elayer;
231 hits_per_layer.resize(n_layers);
232 elayer.resize(n_layers, 0.0f);
234 for (
long unsigned int layer_index = 0; layer_index < n_layers;
237 layer_t &layer =
event->event_data.at(layer_index);
240 long unsigned int n_hits = 0;
241 for (
float e_voxel : layer.E_vector) {
242 long unsigned int hits_per_bin;
243 if (e_voxel > std::numeric_limits<float>::epsilon()) {
247 elayer.at(layer_index) += e_voxel * e_init;
252 n_hits += hits_per_bin;
253 hits_per_layer.at(layer_index).push_back(n_hits);
257 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
258 new std::vector<std::vector<long unsigned int>>(std::move(hits_per_layer));
259 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash, hits_per_layer_ptr);
262 std::vector<float> *elayer_ptr =
new std::vector<float>(std::move(elayer));
263 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash, elayer_ptr);
269 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
270 static_cast<std::vector<std::vector<long unsigned int>
> *>(
271 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
273 if (!hits_per_layer_ptr) {
278 return hits_per_layer_ptr->at(layer_index).back();
282 long unsigned int layer_index)
const {
283 std::vector<float> *elayer_ptr =
static_cast<std::vector<float> *
>(
284 simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash));
289 if (layer_index >= elayer_ptr->size()) {
292 return elayer_ptr->at(layer_index);
297 long unsigned int hit_index)
const {
298 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
299 static_cast<std::vector<std::vector<long unsigned int>
> *>(
300 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
301 if (!hits_per_layer_ptr) {
306 if (layer_index >= hits_per_layer_ptr->size()) {
307 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
308 << hits_per_layer_ptr->size());
313 const std::vector<long unsigned int> &hits =
314 hits_per_layer_ptr->at(layer_index);
315 auto it = std::upper_bound(hits.begin(), hits.end(), hit_index);
316 long unsigned int energy_index = std::distance(hits.begin(), it);
318 if (energy_index >= hits.size()) {
320 <<
" >= " << hits.size());
323 for (
const auto &hit : hits) {
334 int bin_index)
const {
335 float R_min =
m_coordinates.at(layer_index).R_lower.at(bin_index);
336 float R_max =
m_coordinates.at(layer_index).R_size.at(bin_index) +
339 float alpha_min =
m_coordinates.at(layer_index).alpha_lower.at(bin_index);
340 float alpha_max =
m_coordinates.at(layer_index).alpha_size.at(bin_index) +
344 upscale(simulstate, R_min, R_max, alpha_min, alpha_max, layer_index,
348 if (TMath::Abs(R_max - R_min) > std::numeric_limits<float>::epsilon()) {
349 R = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), R_min, R_max);
354 CLHEP::RandFlat::shoot(simulstate.
randomEngine(), alpha_min, alpha_max);
356 return std::make_tuple(R, alpha);
360 float &R_max,
float &alpha_min,
float &alpha_max,
361 long unsigned int layer_index,
362 int bin_index)
const {
364 float p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
366 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
369 unsigned int e_index = 0;
371 std::vector<float> probabilities = {0.25f, 0.5f, 0.75f};
373 if (available_energies.size() > 1) {
375 auto it = std::upper_bound(available_energies.begin(),
376 available_energies.end(), e_init);
377 if (it != available_energies.end()) {
378 e_index = std::distance(available_energies.begin(), it);
380 e_index = available_energies.size() - 1;
383 float e_high = available_energies.at(e_index);
384 if (e_high < e_init || e_index == 0) {
392 float e_low = available_energies.at(e_index - 1);
393 float f_low = std::log(e_high / e_init) / (std::log(e_high / e_low));
394 float f_high = 1 - f_low;
395 for (
unsigned int i = 0; i < 3; ++i) {
404 probabilities[i] = f_low * p_low + f_high * p_high;
410 else if (available_energies.size() == 1) {
414 float p_alpha_low = probabilities[2] - probabilities[1] + probabilities[0];
417 if (p < p_alpha_low) {
418 alpha_max = (alpha_min + alpha_max) / 2.;
419 p_r = probabilities[0] / (p_alpha_low);
421 alpha_min = (alpha_min + alpha_max) / 2.;
422 p_r = (probabilities[1] - probabilities[0]) / (1 - p_alpha_low);
425 p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
426 if (layer_index != 2){
429 R_min = (R_min + R_max) / 2.;
432 R_max = (R_min + R_max) / 2.;
442 }
else if (p_r > 0.75) {
444 }
else if (TMath::Abs(p_r - 0.5) < std::numeric_limits<float>::epsilon()) {
449 float r = (1. - 4. * p_r) / (2. - 4. * p_r) -
450 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
451 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
452 p / ((1. / 2.) - p_r));
454 r = (1. - 4. * p_r) / (2. - 4. * p_r) +
455 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
456 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
457 p / ((1. / 2.) - p_r));
460 R_min = R_min +
r / 2 * (R_max - R_min);
468 long unsigned int hit_index)
const {
471 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
473 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
475 if (layer_index >= event->event_data.size()) {
476 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
477 << event->event_data.size());
478 return std::make_tuple(0.0f, 0.0f, 0.0f);
482 simulstate, layer_index, hit_index);
484 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
485 static_cast<std::vector<std::vector<long unsigned int>
> *>(
486 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
488 long unsigned int hits_per_bin;
489 if (energy_index == 0) {
490 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index);
492 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index) -
493 hits_per_layer_ptr->at(layer_index).at(energy_index - 1);
498 layer_t &layer =
event->event_data.at(layer_index);
501 layer.bin_index_vector.at(energy_index));
503 float E = layer.E_vector.at(energy_index) * e_init / hits_per_bin;
505 return std::make_tuple(
r, alpha, E);
510 void *event_ptr = simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash);
512 delete static_cast<event_t *
>(event_ptr);
513 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash,
nullptr);
518 void *n_hits_ptr = simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash);
520 delete static_cast<std::vector<std::vector<long unsigned int>
> *>(
522 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash,
nullptr);
527 void *elayer_ptr = simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash);
529 delete static_cast<std::vector<float> *
>(elayer_ptr);
530 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash,
nullptr);
532 ATH_MSG_ERROR(
"No event layer energy data found to delete.");
539 const std::string &filename, std::vector<long unsigned int> &layers,
540 bool only_load_meta_data) {
542 if (!only_load_meta_data) {
553 for (
long unsigned int layer_index : layers) {
555 ATH_MSG_INFO(
"Loading layer " << layer_index <<
" from file: " << filename);
560 if (!only_load_meta_data) {
568 !only_load_meta_data) {
575std::tuple<std::vector<float>, std::vector<hsize_t>,
bool>
577 const std::string &datasetname) {
580 H5::H5File
file(filename, H5F_ACC_RDONLY);
583 if (!
file.exists(datasetname)) {
584 return std::make_tuple(std::vector<float>{}, std::vector<hsize_t>{},
false);
587 H5::DataSet
dataset =
file.openDataSet(datasetname);
590 H5::DataSpace dataspace =
dataset.getSpace();
593 int rank = dataspace.getSimpleExtentNdims();
594 std::vector<hsize_t> dims_out(rank);
595 dataspace.getSimpleExtentDims(dims_out.data(), NULL);
599 for (
const auto &dim : dims_out) {
605 dataset.read(data.data(), H5::PredType::NATIVE_FLOAT);
607 return std::make_tuple(data, dims_out,
true);
611 long unsigned int layer_index) {
613 std::string datasetname =
"energy_layer_" + std::to_string(layer_index);
615 std::vector<float> data;
616 std::vector<hsize_t> dims;
620 ATH_MSG_ERROR(
"Error while extracting the layer energy for layer "
621 << layer_index <<
" from " << filename <<
".");
626 std::vector<unsigned int> bin_index_vector;
627 std::vector<float> E_vector;
629 for (
size_t i = 0; i < data.size(); ++i) {
630 long unsigned int event_index = i / dims.at(1);
631 float bin_index = i % dims.at(1);
633 if (bin_index == 0) {
634 bin_index_vector.clear();
638 if (data.at(i) != 0.0) {
639 bin_index_vector.push_back(bin_index);
640 E_vector.push_back(data.at(i));
652 long unsigned int layer_index) {
659 std::vector<std::string> datasetnames = {
660 "binstart_radius_layer_",
"binsize_radius_layer_",
661 "binstart_alpha_layer_",
"binsize_alpha_layer_"};
663 for (
long unsigned int i = 0; i < datasetnames.size(); i++) {
664 std::string datasetname = datasetnames.at(i) + std::to_string(layer_index);
665 std::vector<float> data;
666 std::vector<hsize_t> dims;
670 ATH_MSG_ERROR(
"Error while extracting the bin boundaries for layer "
671 << layer_index <<
" from " << filename <<
"."
672 <<
"Specifically, the key " << datasetname
673 <<
" could not be loaded.");
681 event_bins.R_lower = std::move(data);
684 event_bins.R_size = std::move(data);
687 event_bins.alpha_lower = std::move(data);
690 event_bins.alpha_size = std::move(data);
697 const std::string &filename) {
700 H5::H5File
file(filename, H5F_ACC_RDONLY);
703 std::vector<std::string> datasetnames = {
"phi_mod",
"center_eta",
706 for (
long unsigned int i = 0; i < datasetnames.size(); i++) {
707 std::string datasetname = datasetnames.at(i);
708 std::vector<float> data;
709 std::vector<hsize_t> dims;
719 "Error while extracting the shower center information from "
721 <<
"Specifically, the key " << datasetname
722 <<
" could not be loaded.");
727 for (
long unsigned int event_index = 0; event_index < data.size();
744void TFCSBinnedShower::Streamer(TBuffer &R__b) {
747 if (R__b.IsReading()) {
748 R__b.ReadClassBuffer(TFCSBinnedShower::Class(),
this);
752 std::vector<long unsigned int> layers;
753 for (
long unsigned int i = 0; i <
m_n_layers; ++i) {
761 "Using existing event library of size: " <<
m_eventlibrary.size());
771 R__b.WriteClassBuffer(TFCSBinnedShower::Class(),
this);
777 TFile *
file = TFile::Open(filename.c_str(),
"READ");
779 std::cerr <<
"Failed to open file: " << filename << std::endl;
783 std::regex pattern(R
"(probabilities_layer_(\d+)_energy_([0-9.]+))");
784 std::map<float, std::map<int, std::vector<std::vector<float>>>> temp_storage;
786 TIter next(file->GetListOfKeys());
789 while ((key = (TKey *)next())) {
790 std::string keyname = key->GetName();
792 if (std::regex_match(keyname,
match, pattern)) {
793 int layer = std::stoi(
match[1].
str());
794 float energy = std::stod(
match[2].
str());
796 TMatrixD *matrix =
dynamic_cast<TMatrixD *
>(
file->Get(keyname.c_str()));
798 std::vector<std::vector<float>> mat_vec(
799 matrix->GetNrows(), std::vector<float>(matrix->GetNcols()));
800 for (
int i = 0; i < matrix->GetNrows(); ++i) {
801 for (
int j = 0; j < matrix->GetNcols(); ++j) {
802 mat_vec[i][j] =
static_cast<float>((*matrix)(i, j));
805 temp_storage[energy][layer] = std::move(mat_vec);
814 std::vector<float> energies;
815 std::vector<std::vector<std::vector<std::vector<float>>>>
818 for (
const auto &[energy, layer_map] : temp_storage) {
819 energies.push_back(energy);
821 for (
const auto &[l, _] : layer_map)
822 max_layer = std::max(max_layer, l);
824 std::vector<std::vector<std::vector<float>>> layer_vec(max_layer + 1);
825 for (
const auto &[layer_idx, mat] : layer_map) {
826 layer_vec[layer_idx] = mat;
828 data.push_back(std::move(layer_vec));
832 for (
size_t i = 0; i < energies.size(); ++i) {
833 std::cout <<
"Energy index " << i <<
": " << energies[i] <<
" GeV\n";
834 for (
size_t j = 0; j < data[i].size(); ++j) {
835 if (!data[i][j].
empty()) {
836 std::cout <<
" Layer " << j <<
" Shape: (" << data[i][j].size() <<
", "
837 << data[i][j][0].size() <<
")\n";
static unsigned int totalSize(const MultiDimArray< T, N > &ht)
static const Attributes_t empty
This class groups all DetDescr information related to a CaloCell.
float phi() const
cell phi
TFCSBinnedShowerBase(const char *name=nullptr, const char *title=nullptr)
float m_default_hit_energy
virtual long unsigned int get_n_hits(TFCSSimulationState &simulstate, long unsigned int layer_index) const override
void load_event_library(const std::string &filename, std::vector< long unsigned int > &layers, bool only_load_meta_data=false)
void set_bin_boundaries(long unsigned int layer_index, std::vector< float > &R_lower, std::vector< float > &R_size, std::vector< float > &alpha_lower, std::vector< float > &alpha_size)
virtual float get_layer_energy(TFCSSimulationState &simulstate, long unsigned int layer_index) const override
virtual ~TFCSBinnedShower()
const long unsigned int m_n_layers
void load_sub_bin_distribution(const std::string &filename)
long unsigned int get_energy_index(TFCSSimulationState &simulstate, long unsigned int layer_index, long unsigned int hit_index) const
TFCSBinnedShower(const char *name=nullptr, const char *title=nullptr)
event_bins_t m_coordinates
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
void load_layer_energy(const std::string &filename, long unsigned int layer_index)
std::vector< std::vector< std::vector< std::vector< float > > > > m_sub_bin_distribution
void load_shower_center_information(const std::string &filename)
virtual void delete_event(TFCSSimulationState &simulstate) 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
bool m_use_event_matching
const event_bins_t & get_coordinates()
void set_shower_center_information(long unsigned int event_index, long unsigned int reference_layer_index, float eta_center, float phi_center)
void set_layer_energy(long unsigned int event_index, long unsigned int layer_index, const std::vector< unsigned int > &bin_index_vector, const std::vector< float > &E_vector)
bool m_use_event_cherry_picking
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
std::tuple< std::vector< float >, std::vector< hsize_t >, bool > load_hdf5_dataset(const std::string &filename, const std::string &datasetname)
virtual void compute_n_hits_and_elayer(TFCSSimulationState &simulstate) const
void load_bin_boundaries(const std::string &filename, long unsigned int layer_index)
eventvector_t m_eventlibrary
std::vector< float > m_upscaling_energies
long unsigned int find_best_match(float eta_center, float phi_center, float e_init, long unsigned int reference_layer_index, bool phi_mod_matching) const
static float get_phi_cell_size(long unsigned int layer, float eta)
bool hasAuxInfo(std::uint32_t index) const
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