10 #include "HepPDT/ParticleData.hh"
20 #if defined(__FastCaloSimStandAlone__)
21 #include "CLHEP/Random/TRandomEngine.h"
23 #include <CLHEP/Random/RanluxEngine.h>
39 #include "CLHEP/Random/RandFlat.h"
56 long unsigned int event_index,
long unsigned int layer_index,
57 const std::vector<unsigned int>& bin_index_vector,
58 const std::vector<float>& E_vector) {
66 if (layer_index >=
m_eventlibrary.at(event_index).event_data.size()) {
72 layer.bin_index_vector = bin_index_vector;
73 layer.E_vector = E_vector;
77 std::vector<float>& R_lower,
78 std::vector<float>& R_size,
79 std::vector<float>& alpha_lower,
80 std::vector<float>& alpha_size) {
91 long unsigned int event_index,
long unsigned int reference_layer_index,
92 float eta_center,
float phi_center) {
96 reference_layer_index, eta_center);
98 m_geo->
getDDE(reference_layer_index, eta_center, phi_center)->
phi();
99 float phi_within_cell = fmod(phi_center - phi_cell, phi_cell_size);
100 if (phi_within_cell < 0) {
101 phi_within_cell += phi_cell_size;
108 reference_layer_index) {
109 m_eventlibrary.at(event_index).event_data.resize(reference_layer_index + 1);
116 float eta_center,
float phi_center,
float e_init,
117 long unsigned int reference_layer_index,
bool phi_mod_matching)
const {
119 float phi_cell_size, phi_within_cell;
121 if (phi_mod_matching) {
123 m_geo->
getDDE(reference_layer_index, eta_center, phi_center);
125 reference_layer_index, eta_center);
127 float phi_cell = cellele->
phi();
128 phi_within_cell = phi_center - phi_cell;
130 phi_within_cell = fmod(phi_within_cell, phi_cell_size);
131 if (phi_within_cell < 0)
132 phi_within_cell += phi_cell_size;
139 for (
long unsigned int event_index = 0; event_index <
m_eventlibrary.size();
154 if (phi_mod_matching) {
156 float phi_diff = (phi_mod - phi_within_cell) / phi_cell_size;
157 dist2 = dist2 + phi_diff * phi_diff;
159 float distance = TMath::Sqrt(dist2);
163 best_match = event_index;
171 << eta_center <<
" / "
181 float e_init,
long unsigned int reference_layer_index)
const {
185 "No event library loaded. Please load an event libray for "
186 "TFCSBinnedShower::get_event.");
190 simulstate.
setAuxInfo<
float>(
"BSEinit"_FCShash, e_init);
192 long unsigned int event_index;
194 event_index = simulstate.
getAuxInfo<
int>(
"EventNr"_FCShash);
202 event_index = std::floor(CLHEP::RandFlat::shoot(
207 event_index = std::floor(CLHEP::RandFlat::shoot(simulstate.
randomEngine(),
211 ATH_MSG_DEBUG(
"Using event index " << event_index <<
" for eta " << eta_center
212 <<
" and phi " << phi_center);
216 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash, event_ptr);
225 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
226 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
229 long unsigned int n_layers =
event->event_data.size();
230 std::vector<std::vector<long unsigned int>> hits_per_layer;
231 std::vector<float> elayer;
232 hits_per_layer.resize(n_layers);
233 elayer.resize(n_layers, 0.0
f);
235 for (
long unsigned int layer_index = 0; layer_index < n_layers;
241 long unsigned int n_hits = 0;
242 for (
float e_voxel :
layer.E_vector) {
243 long unsigned int hits_per_bin;
248 elayer.at(layer_index) += e_voxel * e_init;
253 n_hits += hits_per_bin;
254 hits_per_layer.at(layer_index).push_back(n_hits);
258 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
259 new std::vector<std::vector<long unsigned int>>(std::move(hits_per_layer));
260 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash, hits_per_layer_ptr);
263 std::vector<float> *elayer_ptr =
new std::vector<float>(std::move(elayer));
264 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash, elayer_ptr);
270 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
271 static_cast<std::vector<std::vector<long unsigned int>
> *>(
272 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
274 if (!hits_per_layer_ptr) {
279 return hits_per_layer_ptr->at(layer_index).back();
283 long unsigned int layer_index)
const {
284 std::vector<float> *elayer_ptr =
static_cast<std::vector<float> *
>(
285 simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash));
290 if (layer_index >= elayer_ptr->size()) {
293 return elayer_ptr->at(layer_index);
298 long unsigned int hit_index)
const {
299 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
300 static_cast<std::vector<std::vector<long unsigned int>
> *>(
301 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
302 if (!hits_per_layer_ptr) {
307 if (layer_index >= hits_per_layer_ptr->size()) {
308 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
309 << hits_per_layer_ptr->size());
314 const std::vector<long unsigned int> &
hits =
315 hits_per_layer_ptr->at(layer_index);
316 auto it = std::upper_bound(
hits.begin(),
hits.end(), hit_index);
319 if (energy_index >=
hits.size()) {
321 <<
" >= " <<
hits.size());
324 for (
const auto &hit :
hits) {
335 int bin_index)
const {
336 float R_min =
m_coordinates.at(layer_index).R_lower.at(bin_index);
337 float R_max =
m_coordinates.at(layer_index).R_size.at(bin_index) +
340 float alpha_min =
m_coordinates.at(layer_index).alpha_lower.at(bin_index);
341 float alpha_max =
m_coordinates.at(layer_index).alpha_size.at(bin_index) +
345 upscale(simulstate, R_min, R_max, alpha_min, alpha_max, layer_index,
350 R = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), R_min, R_max);
355 CLHEP::RandFlat::shoot(simulstate.
randomEngine(), alpha_min, alpha_max);
357 return std::make_tuple(
R,
alpha);
361 float &R_max,
float &alpha_min,
float &alpha_max,
362 long unsigned int layer_index,
363 int bin_index)
const {
365 float p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
367 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
370 unsigned int e_index = 0;
372 std::vector<float> probabilities = {0.25f, 0.5f, 0.75f};
374 if (available_energies.size() > 1) {
376 auto it = std::upper_bound(available_energies.begin(),
377 available_energies.end(), e_init);
378 if (
it != available_energies.end()) {
381 e_index = available_energies.size() - 1;
384 float e_high = available_energies.at(e_index);
385 if (e_high < e_init || e_index == 0) {
393 float e_low = available_energies.at(e_index - 1);
395 float f_high = 1 - f_low;
396 for (
unsigned int i = 0;
i < 3; ++
i) {
405 probabilities[
i] = f_low * p_low + f_high * p_high;
411 else if (available_energies.size() == 1) {
415 float p_alpha_low = probabilities[2] - probabilities[1] + probabilities[0];
418 if (
p < p_alpha_low) {
419 alpha_max = (alpha_min + alpha_max) / 2.;
420 p_r = probabilities[0] / (p_alpha_low);
422 alpha_min = (alpha_min + alpha_max) / 2.;
423 p_r = (probabilities[1] - probabilities[0]) / (1 - p_alpha_low);
427 if (layer_index != 2){
430 R_min = (R_min + R_max) / 2.;
433 R_max = (R_min + R_max) / 2.;
443 }
else if (p_r > 0.75) {
450 float r = (1. - 4. * p_r) / (2. - 4. * p_r) -
451 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
452 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
453 p / ((1. / 2.) - p_r));
455 r = (1. - 4. * p_r) / (2. - 4. * p_r) +
456 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
457 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
458 p / ((1. / 2.) - p_r));
461 R_min = R_min +
r / 2 * (R_max - R_min);
469 long unsigned int hit_index)
const {
472 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
474 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
476 if (layer_index >=
event->event_data.size()) {
477 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
478 <<
event->event_data.size());
479 return std::make_tuple(0.0
f, 0.0
f, 0.0
f);
483 simulstate, layer_index, hit_index);
485 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
486 static_cast<std::vector<std::vector<long unsigned int>
> *>(
487 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
489 long unsigned int hits_per_bin;
490 if (energy_index == 0) {
491 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index);
493 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index) -
494 hits_per_layer_ptr->at(layer_index).at(energy_index - 1);
502 layer.bin_index_vector.at(energy_index));
504 float E =
layer.E_vector.at(energy_index) * e_init / hits_per_bin;
506 return std::make_tuple(
r,
alpha,
E);
511 void *event_ptr = simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash);
513 delete static_cast<event_t *
>(event_ptr);
514 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash,
nullptr);
519 void *n_hits_ptr = simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash);
521 delete static_cast<std::vector<std::vector<long unsigned int>
> *>(
523 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash,
nullptr);
528 void *elayer_ptr = simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash);
530 delete static_cast<std::vector<float> *
>(elayer_ptr);
531 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash,
nullptr);
533 ATH_MSG_ERROR(
"No event layer energy data found to delete.");
540 const std::string &
filename, std::vector<long unsigned int> &
layers,
541 bool only_load_meta_data) {
543 if (!only_load_meta_data) {
554 for (
long unsigned int layer_index :
layers) {
561 if (!only_load_meta_data) {
569 !only_load_meta_data) {
576 std::tuple<std::vector<float>, std::vector<hsize_t>,
bool>
578 const std::string &datasetname) {
584 if (!
file.exists(datasetname)) {
585 return std::make_tuple(std::vector<float>{}, std::vector<hsize_t>{},
false);
588 H5::DataSet
dataset =
file.openDataSet(datasetname);
591 H5::DataSpace dataspace =
dataset.getSpace();
594 int rank = dataspace.getSimpleExtentNdims();
595 std::vector<hsize_t> dims_out(rank);
596 dataspace.getSimpleExtentDims(dims_out.data(), NULL);
600 for (
const auto &
dim : dims_out) {
606 dataset.read(
data.data(), H5::PredType::NATIVE_FLOAT);
608 return std::make_tuple(
data, dims_out,
true);
612 long unsigned int layer_index) {
614 std::string datasetname =
"energy_layer_" +
std::to_string(layer_index);
616 std::vector<float>
data;
617 std::vector<hsize_t> dims;
621 ATH_MSG_ERROR(
"Error while extracting the layer energy for layer "
622 << layer_index <<
" from " <<
filename <<
".");
627 std::vector<unsigned int> bin_index_vector;
628 std::vector<float> E_vector;
630 for (
size_t i = 0;
i <
data.size(); ++
i) {
631 long unsigned int event_index =
i / dims.at(1);
632 float bin_index =
i % dims.at(1);
634 if (bin_index == 0) {
635 bin_index_vector.clear();
639 if (
data.at(
i) != 0.0) {
640 bin_index_vector.push_back(bin_index);
641 E_vector.push_back(
data.at(
i));
653 long unsigned int layer_index) {
660 std::vector<std::string> datasetnames = {
661 "binstart_radius_layer_",
"binsize_radius_layer_",
662 "binstart_alpha_layer_",
"binsize_alpha_layer_"};
664 for (
long unsigned int i = 0;
i < datasetnames.size();
i++) {
665 std::string datasetname = datasetnames.at(
i) +
std::to_string(layer_index);
666 std::vector<float>
data;
667 std::vector<hsize_t> dims;
671 ATH_MSG_ERROR(
"Error while extracting the bin boundaries for layer "
672 << layer_index <<
" from " <<
filename <<
"."
673 <<
"Specifically, the key " << datasetname
674 <<
" could not be loaded.");
682 event_bins.R_lower = std::move(
data);
685 event_bins.R_size = std::move(
data);
688 event_bins.alpha_lower = std::move(
data);
691 event_bins.alpha_size = std::move(
data);
704 std::vector<std::string> datasetnames = {
"phi_mod",
"center_eta",
707 for (
long unsigned int i = 0;
i < datasetnames.size();
i++) {
708 std::string datasetname = datasetnames.at(
i);
709 std::vector<float>
data;
710 std::vector<hsize_t> dims;
720 "Error while extracting the shower center information from "
722 <<
"Specifically, the key " << datasetname
723 <<
" could not be loaded.");
728 for (
long unsigned int event_index = 0; event_index <
data.size();
745 void TFCSBinnedShower::Streamer(TBuffer &R__b) {
748 if (R__b.IsReading()) {
749 R__b.ReadClassBuffer(TFCSBinnedShower::Class(),
this);
753 std::vector<long unsigned int>
layers;
762 "Using existing event library of size: " <<
m_eventlibrary.size());
772 R__b.WriteClassBuffer(TFCSBinnedShower::Class(),
this);
780 std::cerr <<
"Failed to open file: " <<
filename << std::endl;
785 std::map<float, std::map<int, std::vector<std::vector<float>>>> temp_storage;
790 while ((
key = (TKey *)
next())) {
791 std::string keyname =
key->GetName();
797 TMatrixD *
matrix =
dynamic_cast<TMatrixD *
>(
file->Get(keyname.c_str()));
799 std::vector<std::vector<float>> mat_vec(
800 matrix->GetNrows(), std::vector<float>(
matrix->GetNcols()));
801 for (
int i = 0;
i <
matrix->GetNrows(); ++
i) {
802 for (
int j = 0; j <
matrix->GetNcols(); ++j) {
803 mat_vec[
i][j] =
static_cast<float>((*matrix)(
i, j));
815 std::vector<float> energies;
816 std::vector<std::vector<std::vector<std::vector<float>>>>
819 for (
const auto &[
energy, layer_map] : temp_storage) {
820 energies.push_back(
energy);
822 for (
const auto &[
l,
_] : layer_map)
825 std::vector<std::vector<std::vector<float>>> layer_vec(max_layer + 1);
829 data.push_back(std::move(layer_vec));
833 for (
size_t i = 0;
i < energies.size(); ++
i) {
834 std::cout <<
"Energy index " <<
i <<
": " << energies[
i] <<
" GeV\n";
835 for (
size_t j = 0; j <
data[
i].size(); ++j) {
836 if (!
data[
i][j].empty()) {
837 std::cout <<
" Layer " << j <<
" Shape: (" <<
data[
i][j].size() <<
", "
838 <<
data[
i][j][0].size() <<
")\n";