7#include "CLHEP/Random/RandFlat.h"
8#include "CLHEP/Random/RandGauss.h"
22#if defined(__FastCaloSimStandAlone__)
23#include "CLHEP/Random/TRandomEngine.h"
25#include <CLHEP/Random/RanluxEngine.h>
73 int const &pid,
int const &etaMin,
74 const std::string &FastCaloGANInputFolderName) {
80 "Using FastCaloGANInputFolderName: " << FastCaloGANInputFolderName);
82 const int etaMax = etaMin + 5;
95 if (pid != 22 && pid != 11) {
99 const int etaMid = (etaMin + etaMax) / 2;
100 m_param.InitialiseFromXML(pidForXml, etaMid, FastCaloGANInputFolderName);
111 Form(
"layer=%d", simulstate.
getAuxInfo<
int>(
"GANlayer"_FCShash)));
127 const int pdgId = truth->
pdgid();
131 const float Ekin = truth->
Ekin();
133 Einit = simulstate.
E();
139 if (!
m_slice->IsGanCorrectlyLoaded()) {
144 m_slice->GetNetworkOutputs(truth, extrapol, simulstate);
148 const auto ganVersion =
m_param.GetGANVersion();
154 double totalEnergy = 0;
155 for (
const auto & output : outputs) {
156 totalEnergy += output.second;
158 if (totalEnergy < 0) {
168 for (
const auto &[layer,
h] : binsInLayers) {
169 const int xBinNum =
h.GetNbinsX();
170 const int yBinNum =
h.GetNbinsY();
171 const TAxis *
x =
h.GetXaxis();
177 <<
" has only one bin in r, this means is it not used, "
178 "skipping (this is needed to keep correct "
179 "syncronisation of voxel and layers)");
187 for (
int ix = 1; ix <= xBinNum; ++ix) {
189 for (
int iy = 1; iy <= binsInAlphaInRBin; ++iy) {
190 const double energyInVoxel = outputs.at(std::to_string(vox));
192 <<
" binx " << ix <<
" biny " << iy);
194 if (energyInVoxel <= 0) {
199 simulstate.
add_E(layer, Einit * energyInVoxel);
205 for (
unsigned int ichain =
m_bin_start.back(); ichain <
size(); ++ichain) {
214 for (
const auto &[layer,
h] : binsInLayers) {
215 const int xBinNum =
h.GetNbinsX();
216 const int yBinNum =
h.GetNbinsY();
217 const TAxis *
x =
h.GetXaxis();
218 const TAxis *
y =
h.GetYaxis();
220 simulstate.
setAuxInfo<
int>(
"GANlayer"_FCShash, layer);
227 <<
" has only one bin in r, this means is it not used, "
228 "skipping (this is needed to keep correct "
229 "syncronisation of voxel and layers)");
235 const int bin =
get_bin(simulstate, truth, extrapol);
243 <<
chain()[ichain]->GetName());
244 if (
chain()[ichain]->InheritsFrom(
245 TFCSLateralShapeParametrizationHitBase::Class())) {
253 <<
chain()[ichain]->GetName());
260 <<
chain()[ichain]->GetName()
261 <<
" does not inherit from "
262 "TFCSLateralShapeParametrizationHitBase");
273 int binResolution = 5;
274 if (layer == 1 || layer == 5) {
278 const double center_eta =
hit.center_eta();
279 const double center_phi =
hit.center_phi();
280 const double center_r =
hit.center_r();
281 const double center_z =
hit.center_z();
284 <<
" phi " << center_phi <<
" R " << center_r);
286 const float dist000 =
287 TMath::Sqrt(center_r * center_r + center_z * center_z);
288 const float eta_jakobi = TMath::Abs(2.0 * TMath::Exp(-center_eta) /
289 (1.0 + TMath::Exp(-2 * center_eta)));
295 for (
int ix = 1; ix <= xBinNum; ++ix) {
299 const int binsToMerge = yBinNum == 32 ? 32 / binsInAlphaInRBin : 1;
300 for (
int iy = 1; iy <= binsInAlphaInRBin; ++iy) {
301 const double energyInVoxel = outputs.at(std::to_string(vox));
302 const int lowEdgeIndex = (iy - 1) * binsToMerge + 1;
305 <<
" binx " << ix <<
" biny " << iy);
307 if (energyInVoxel <= 0) {
312 if (std::abs(pdgId) == 22 || std::abs(pdgId) == 11) {
314 int maxHitsInVoxel = energyInVoxel * truth->
Ekin() / 10;
315 if (maxHitsInVoxel < 1)
317 nHitsAlpha = std::sqrt(maxHitsInVoxel);
318 nHitsR = std::sqrt(maxHitsInVoxel);
321 nHitsR =
x->GetBinUpEdge(ix) -
x->GetBinLowEdge(ix);
324 const double r =
x->GetBinUpEdge(ix);
325 nHitsAlpha = ceil(2 * TMath::Pi() *
r / binResolution);
329 const double angle =
y->GetBinUpEdge(iy) -
y->GetBinLowEdge(iy);
330 const double r =
x->GetBinUpEdge(ix);
331 const double d = 2 *
r * sin(
angle / 2 *
r);
332 nHitsAlpha = ceil(d / binResolution);
335 if (layer != 1 && layer != 5) {
339 const int maxNhits = 10;
340 nHitsAlpha = std::min(maxNhits, std::max(1, nHitsAlpha));
341 nHitsR = std::min(maxNhits, std::max(1, nHitsR));
345 for (
int ir = 0;
ir < nHitsR; ++
ir) {
347 x->GetBinLowEdge(ix) +
x->GetBinWidth(ix) / (nHitsR + 1) *
ir;
349 for (
int ialpha = 1; ialpha <= nHitsAlpha; ++ialpha) {
350 if (ganVersion > 1) {
351 if (fitResults.at(layer)[ix - 1] != 0) {
354 x->GetBinLowEdge(ix),
355 x->GetBinUpEdge(ix));
357 log((
a -
x->GetBinLowEdge(ix)) / (
x->GetBinWidth(ix))) /
358 fitResults.at(layer)[ix - 1];
359 while ((rand_r < x->GetBinLowEdge(ix) ||
360 rand_r >
x->GetBinUpEdge(ix)) &&
363 x->GetBinLowEdge(ix),
364 x->GetBinUpEdge(ix));
366 log((
a -
x->GetBinLowEdge(ix)) / (
x->GetBinWidth(ix))) /
367 fitResults.at(layer)[ix - 1];
372 <<
x->GetBinLowEdge(ix) <<
"-"
373 <<
x->GetBinUpEdge(ix) <<
"] having slope "
374 << fitResults.at(layer)[ix - 1]
375 <<
" will use grid (old method)");
383 if (binsInAlphaInRBin == 1) {
384 alpha = CLHEP::RandFlat::shoot(simulstate.
randomEngine(),
385 -TMath::Pi(), TMath::Pi());
388 y->GetBinLowEdge(lowEdgeIndex) +
389 y->GetBinWidth(iy) * binsToMerge / (nHitsAlpha + 1) * ialpha;
391 if (
m_param.IsSymmetrisedAlpha()) {
393 -TMath::Pi(), TMath::Pi()) < 0) {
400 hit.E() = Einit * energyInVoxel / (nHitsAlpha * nHitsR);
403 float delta_eta_mm =
r * cos(alpha);
404 float delta_phi_mm =
r * sin(alpha);
414 delta_eta_mm = -delta_eta_mm;
419 if ((
charge < 0. && pdgId != 11) || pdgId == -11)
420 delta_phi_mm = -delta_phi_mm;
422 const float delta_eta = delta_eta_mm / eta_jakobi / dist000;
423 const float delta_phi = delta_phi_mm / center_r;
425 hit.eta() = center_eta + delta_eta;
426 hit.phi() = TVector2::Phi_mpi_pi(center_phi + delta_phi);
429 <<
" layer " << layer);
431 const float hit_r =
r * cos(alpha) + center_r;
432 float delta_phi =
r * sin(alpha) / center_r;
437 if ((
charge < 0. && pdgId != 11) || pdgId == -11)
438 delta_phi = -delta_phi;
439 const float hit_phi =
440 TVector2::Phi_mpi_pi(center_phi + delta_phi);
441 hit.x() = hit_r * cos(hit_phi);
442 hit.y() = hit_r * sin(hit_phi);
445 <<
" layer " << layer);
449 const int bin =
get_bin(simulstate, truth, extrapol);
451 for (
unsigned int ichain =
457 <<
chain()[ichain]->GetName());
458 if (
chain()[ichain]->InheritsFrom(
459 TFCSLateralShapeParametrizationHitBase::Class())) {
469 <<
chain()[ichain]->GetName());
476 <<
chain()[ichain]->GetName()
477 <<
" does not inherit from "
478 "TFCSLateralShapeParametrizationHitBase");
501 if (simulstate.
E() > std::numeric_limits<double>::epsilon()) {
503 simulstate.
set_Efrac(ilayer, simulstate.
E(ilayer) / simulstate.
E());
514 for (
unsigned int ichain = 0; ichain <
m_bin_start[0]; ++ichain) {
523 if (!
fillEnergy(simulstate, truth, extrapol)) {
535 const bool shortprint = opt.Index(
"short") >= 0;
536 const bool longprint =
537 msgLvl(MSG::DEBUG) || (
msgLvl(MSG::INFO) && !shortprint);
538 TString optprint = opt;
539 optprint.ReplaceAll(
"short",
"");
541 TString prefix =
"- ";
542 for (
unsigned int ichain = 0; ichain <
size(); ++ichain) {
543 if (ichain == 0 && ichain !=
m_bin_start.front()) {
553 prefix = Form(
"%-2d", ibin);
563 chain()[ichain]->Print(opt + prefix);
573 "/eos/atlas/atlascerngroupdisk/proj-simul/AF3_Run3/"
574 "InputsToBigParamFiles/FastCaloGANWeightsVer02/";
575 test_path(path, simulstate, truth, extrapol,
"lwtnn");
579 "/eos/atlas/atlascerngroupdisk/proj-simul/AF3_Run3/"
580 "InputsToBigParamFiles/FastCaloGANWeightsONNXVer08/";
581 test_path(path, simulstate, truth, extrapol,
"onnx");
589 const std::string &outputname,
int pid) {
594#if defined(__FastCaloSimStandAlone__)
609 e->set_IDCaloBoundary_eta(truth->Eta());
610 for (
int i = 0; i < 24; ++i) {
629 const int etaMin = 20;
630 const int etaMax = etaMin + 5;
633 for (
int i = 0; i < 24; ++i)
636 Form(
"center%d", i), Form(
"center layer %d", i));
637 c->set_calosample(i);
638 c->setExtrapWeight(0.5);
639 c->setLevel(MSG::INFO);
645 c->set_eta_min(etaMin / 100.0);
646 c->set_eta_max(etaMax / 100.0);
647 c->set_eta_nominal((etaMin + etaMax) / 200.0);
656 const std::string outname =
"FCSGANtest_" + outputname +
".root";
657 TFile *fGAN = TFile::Open(outname.c_str(),
"recreate");
660 fGAN->WriteObjectAny(&GAN,
"TFCSEnergyAndHitGANV2",
"GAN");
667 fGAN = TFile::Open(outname.c_str());
673 GAN2->
simulate(*simulstate, truth, extrapol);
691 double binsInAlphaInRBin = yBinNum;
694 const double widthX =
x->GetBinWidth(ix);
695 const double radious =
x->GetBinCenter(ix);
696 double circumference = radious * 2. * TMath::Pi();
697 if (
m_param.IsSymmetrisedAlpha()) {
698 circumference = radious * TMath::Pi();
701 const double bins = circumference / widthX;
703 ATH_MSG_DEBUG(
"Bin in alpha: " << binsInAlphaInRBin <<
" for r bin: " << ix
704 <<
" (" <<
x->GetBinLowEdge(ix) <<
"-"
705 <<
x->GetBinUpEdge(ix) <<
")");
707 return binsInAlphaInRBin;
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
double charge(const T &p)
ATLAS-specific HepMC functions.
#define ATH_MSG_NOCLASS(logger_name, x)
static const std::vector< std::string > bins
A number of constexpr particle constants to avoid hardcoding them directly in various places.
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Header file for AthHistogramAlgorithm.
bool msgLvl(const MSG::Level lvl) const
Check whether the logging system is active at the provided verbosity level.
virtual void setLevel(MSG::Level lvl)
Update outputlevel.
virtual ~TFCSEnergyAndHitGANV2()
std::vector< int > m_bin_ninit
bool initializeNetwork(int const &pid, int const &etaMin, const std::string &FastCaloGANInputFolderName)
TFCSGANEtaSlice * m_slice
static void unit_test(TFCSSimulationState *simulstate=nullptr, const TFCSTruthState *truth=nullptr, const TFCSExtrapolationState *extrapol=nullptr)
unsigned int get_nr_of_init(unsigned int bin) const
virtual int get_bin(TFCSSimulationState &simulstate, const TFCSTruthState *, const TFCSExtrapolationState *) const override
use the layer to be done as binning of the GAN chain
static void test_path(const std::string &path, TFCSSimulationState *simulstate=nullptr, const TFCSTruthState *truth=nullptr, const TFCSExtrapolationState *extrapol=nullptr, const std::string &outputname="unnamed", int pid=211)
virtual const std::string get_variable_text(TFCSSimulationState &simulstate, const TFCSTruthState *, const TFCSExtrapolationState *) const override
int GetAlphaBinsForRBin(const TAxis *x, int ix, int yBinNum) const
static int GetBinsInFours(double const bins)
bool OnlyScaleEnergy() const
virtual void Print(Option_t *option="") const override
virtual void fixHists() override
const TFCSGANXMLParameters::Binning & get_Binning() const
virtual bool is_match_calosample(int calosample) const override
TFCSEnergyAndHitGANV2(const char *name=nullptr, const char *title=nullptr)
bool fillEnergy(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
virtual FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
void set_nr_of_init(unsigned int bin, unsigned int ninit)
TFCSGANXMLParameters m_param
std::map< int, std::vector< double > > FitResultsPerLayer
std::map< std::string, double > NetworkOutputs
std::map< int, TH2D > Binning
virtual FCSReturnCode simulate_hit(Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol)
simulated one hit position with some energy.
virtual void reset_match_all_pdgid()
void Print(Option_t *option="") const
Print object information.
virtual unsigned int get_number_of_bins() const
TFCSParametrizationBinnedChain(const char *name=nullptr, const char *title=nullptr)
std::vector< unsigned int > m_bin_start
Contains the index where the TFCSParametrizationBase* instances to run for a given bin start.
virtual void push_back_in_bin(TFCSParametrizationBase *param, unsigned int bin)
virtual const std::string get_bin_text(int bin) const
print the range of a bin; for bin -1, print the allowed range
FCSReturnCode simulate_and_retry(TFCSParametrizationBase *parametrization, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
const Chain_t & chain() const
virtual unsigned int size() const override
Some derived classes have daughter instances of TFCSParametrizationBase objects The size() and operat...
virtual void set_eta_max(double max)
virtual void add_pdgid(int id)
virtual void set_eta_nominal(double min)
virtual void set_pdgid(int id)
virtual void set_eta_min(double min)
void Print(Option_t *option="") const
void set_E(int sample, double Esample)
const T getAuxInfo(std::uint32_t index) const
void add_E(int sample, double Esample)
void set_Efrac(int sample, double Efracsample)
void setAuxInfo(std::uint32_t index, const T &val)
CLHEP::HepRandomEngine * randomEngine()
void setRandomEngine(CLHEP::HepRandomEngine *engine)
int ir
counter of the current depth
std::string find(const std::string &s)
return a remapped string
Helpers to make a nice dump of a region of memory.
static Root::TMsgLogger logger("iLumiCalc")
double charge(const T &p)
constexpr double chargedPionMassInMeV
the mass of the charged pion (in MeV)