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"
63 float e_init,
long unsigned int reference_layer_index)
const {
65 (void)reference_layer_index;
74 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash, event_ptr);
75 simulstate.
setAuxInfo<
float>(
"BSEinit"_FCShash, e_init);
81 const std::string &
filename, std::vector<long unsigned int> &
layers) {
90 for (
long unsigned int layer_index :
layers) {
101 std::tuple<std::vector<float>, std::vector<hsize_t>,
bool>
103 const std::string &datasetname) {
109 if (!
file.exists(datasetname)) {
110 return std::make_tuple(std::vector<float>{}, std::vector<hsize_t>{},
false);
113 H5::DataSet
dataset =
file.openDataSet(datasetname);
116 H5::DataSpace dataspace =
dataset.getSpace();
119 int rank = dataspace.getSimpleExtentNdims();
120 std::vector<hsize_t> dims_out(rank);
121 dataspace.getSimpleExtentDims(dims_out.data(), NULL);
125 for (
const auto &
dim : dims_out) {
131 dataset.read(
data.data(), H5::PredType::NATIVE_FLOAT);
133 return std::make_tuple(
data, dims_out,
true);
137 long unsigned int layer_index) {
144 std::vector<std::string> datasetnames = {
145 "binstart_radius_layer_",
"binsize_radius_layer_",
146 "binstart_alpha_layer_",
"binsize_alpha_layer_"};
148 for (
long unsigned int i = 0;
i < datasetnames.size();
i++) {
149 std::string datasetname = datasetnames.at(
i) +
std::to_string(layer_index);
150 std::vector<float>
data;
151 std::vector<hsize_t> dims;
155 ATH_MSG_ERROR(
"Error while extracting the bin boundaries for layer "
156 << layer_index <<
" from " <<
filename <<
"."
157 <<
"Specifically, the key " << datasetname
158 <<
" could not be loaded.");
166 event_bins.R_lower = std::move(
data);
169 event_bins.R_size = std::move(
data);
172 event_bins.alpha_lower = std::move(
data);
175 event_bins.alpha_size = std::move(
data);
182 void TFCSBinnedShowerONNX::Streamer(TBuffer &R__b) {
185 if (R__b.IsReading()) {
186 R__b.ReadClassBuffer(TFCSBinnedShowerONNX::Class(),
this);
190 R__b.WriteClassBuffer(TFCSBinnedShowerONNX::Class(),
this);
195 const std::vector<float>& R_lower,
196 const std::vector<float>& R_size,
197 const std::vector<float>& alpha_lower,
198 const std::vector<float>& alpha_size) {
213 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
214 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
217 long unsigned int n_layers =
event->event_data.size();
218 std::vector<std::vector<long unsigned int>> hits_per_layer;
219 std::vector<float> elayer;
220 hits_per_layer.resize(n_layers);
221 elayer.resize(n_layers, 0.0
f);
223 for (
long unsigned int layer_index = 0; layer_index < n_layers;
229 long unsigned int n_hits = 0;
230 for (
float e_voxel :
layer.E_vector) {
231 long unsigned int hits_per_bin;
236 elayer.at(layer_index) += e_voxel * e_init;
241 n_hits += hits_per_bin;
242 hits_per_layer.at(layer_index).push_back(n_hits);
246 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
247 new std::vector<std::vector<long unsigned int>>(std::move(hits_per_layer));
248 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash, hits_per_layer_ptr);
251 std::vector<float> *elayer_ptr =
new std::vector<float>(std::move(elayer));
252 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash, elayer_ptr);
258 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
259 static_cast<std::vector<std::vector<long unsigned int>
> *>(
260 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
262 if (!hits_per_layer_ptr) {
267 return hits_per_layer_ptr->at(layer_index).back();
272 std::vector<float> *elayer_ptr =
static_cast<std::vector<float> *
>(
273 simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash));
278 if (layer_index >= elayer_ptr->size()) {
283 <<
": " << elayer_ptr->at(layer_index));
285 return elayer_ptr->at(layer_index);
290 long unsigned int hit_index)
const {
291 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
292 static_cast<std::vector<std::vector<long unsigned int>
> *>(
293 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
294 if (!hits_per_layer_ptr) {
299 if (layer_index >= hits_per_layer_ptr->size()) {
300 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
301 << hits_per_layer_ptr->size());
306 const std::vector<long unsigned int> &
hits =
307 hits_per_layer_ptr->at(layer_index);
308 auto it = std::upper_bound(
hits.begin(),
hits.end(), hit_index);
311 if (energy_index >=
hits.size()) {
313 <<
" >= " <<
hits.size());
316 for (
const auto &hit :
hits) {
327 int bin_index)
const {
328 float R_min =
m_coordinates.at(layer_index).R_lower.at(bin_index);
329 float R_max =
m_coordinates.at(layer_index).R_size.at(bin_index) +
332 float alpha_min =
m_coordinates.at(layer_index).alpha_lower.at(bin_index);
333 float alpha_max =
m_coordinates.at(layer_index).alpha_size.at(bin_index) +
337 upscale(simulstate, R_min, R_max, alpha_min, alpha_max, layer_index,
341 float R = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), R_min, R_max);
343 CLHEP::RandFlat::shoot(simulstate.
randomEngine(), alpha_min, alpha_max);
345 return std::make_tuple(
R,
alpha);
349 float &R_min,
float &R_max,
float &alpha_min,
351 long unsigned int layer_index,
352 int bin_index)
const {
354 float p = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), 0, 1);
356 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
359 unsigned int e_index = 0;
361 std::vector<float> probabilities = {0.25f, 0.5f, 0.75f};
363 if (available_energies.size() > 1) {
365 auto it = std::upper_bound(available_energies.begin(),
366 available_energies.end(), e_init);
367 if (
it != available_energies.end()) {
370 e_index = available_energies.size() - 1;
373 float e_high = available_energies.at(e_index);
374 if (e_high < e_init || e_index == 0) {
382 float e_low = available_energies.at(e_index - 1);
384 float f_high = 1 - f_low;
385 for (
unsigned int i = 0;
i < 3; ++
i) {
394 probabilities[
i] = f_low * p_low + f_high * p_high;
400 else if (available_energies.size() == 1) {
404 float p_alpha_low = probabilities[2] - probabilities[1] + probabilities[0];
407 if (
p < p_alpha_low) {
408 alpha_max = (alpha_min + alpha_max) / 2.;
409 p_r = probabilities[0] / (p_alpha_low);
411 alpha_min = (alpha_min + alpha_max) / 2.;
412 p_r = (probabilities[1] - probabilities[0]) / (1 - p_alpha_low);
416 if (layer_index != 2){
419 R_min = (R_min + R_max) / 2.;
422 R_max = (R_min + R_max) / 2.;
432 }
else if (p_r > 0.75) {
439 float r = (1. - 4. * p_r) / (2. - 4. * p_r) -
440 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
441 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
442 p / ((1. / 2.) - p_r));
444 r = (1. - 4. * p_r) / (2. - 4. * p_r) +
445 TMath::Sqrt(((1. - 4. * p_r) / (2. - 4. * p_r)) *
446 ((1. - 4. * p_r) / (2. - 4. * p_r)) +
447 p / ((1. / 2.) - p_r));
450 R_min = R_min +
r / 2 * (R_max - R_min);
454 std::tuple<float, float, float>
457 long unsigned int hit_index)
const {
461 simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash));
463 float e_init = simulstate.
getAuxInfo<
float>(
"BSEinit"_FCShash);
465 if (layer_index >=
event->event_data.size()) {
466 ATH_MSG_ERROR(
"Layer index out of bounds: " << layer_index <<
" >= "
467 <<
event->event_data.size());
468 return std::make_tuple(0.0
f, 0.0
f, 0.0
f);
472 simulstate, layer_index, hit_index);
474 std::vector<std::vector<long unsigned int>> *hits_per_layer_ptr =
475 static_cast<std::vector<std::vector<long unsigned int>
> *>(
476 simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash));
478 long unsigned int hits_per_bin;
479 if (energy_index == 0) {
480 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index);
482 hits_per_bin = hits_per_layer_ptr->at(layer_index).at(energy_index) -
483 hits_per_layer_ptr->at(layer_index).at(energy_index - 1);
491 layer.bin_index_vector.at(energy_index));
493 float E =
layer.E_vector.at(energy_index) * e_init / hits_per_bin;
495 return std::make_tuple(
r,
alpha,
E);
500 void *event_ptr = simulstate.
getAuxInfo<
void *>(
"BSEventData"_FCShash);
503 simulstate.
setAuxInfo<
void *>(
"BSEventData"_FCShash,
nullptr);
508 void *n_hits_ptr = simulstate.
getAuxInfo<
void *>(
"BSNHits"_FCShash);
510 delete static_cast<std::vector<std::vector<long unsigned int>
> *>(
512 simulstate.
setAuxInfo<
void *>(
"BSNHits"_FCShash,
nullptr);
517 void *elayer_ptr = simulstate.
getAuxInfo<
void *>(
"BSELayer"_FCShash);
519 delete static_cast<std::vector<float> *
>(elayer_ptr);
520 simulstate.
setAuxInfo<
void *>(
"BSELayer"_FCShash,
nullptr);
522 ATH_MSG_ERROR(
"No event layer energy data found to delete.");
533 std::cerr <<
"Failed to open file: " <<
filename << std::endl;
538 std::map<float, std::map<int, std::vector<std::vector<float>>>> temp_storage;
543 while ((
key = (TKey *)
next())) {
544 std::string keyname =
key->GetName();
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));
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)
578 std::vector<std::vector<std::vector<float>>> layer_vec(max_layer + 1);
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";