15#include "HepPDT/ParticleData.hh"
16#include "HepPDT/ParticleDataTable.hh"
18#include "CLHEP/Random/RandGauss.h"
19#include "CLHEP/Random/RandFlat.h"
21#if defined(__FastCaloSimStandAlone__)
22#include "CLHEP/Random/TRandomEngine.h"
24#include <CLHEP/Random/RanluxEngine.h>
32#include "lwtnn/LightweightGraph.hh"
33#include "lwtnn/parse_json.hh"
36#include <libxml/xmlmemory.h>
37#include <libxml/parser.h>
38#include <libxml/tree.h>
39#include <libxml/xmlreader.h>
40#include <libxml/xpath.h>
41#include <libxml/xpathInternals.h>
85 int pid,
int etaMin,
const std::string &FastCaloGANInputFolderName) {
91 "Using FastCaloGANInputFolderName: " << FastCaloGANInputFolderName);
93 int etaMax = etaMin + 5;
105 std::string inputFile =
106 FastCaloGANInputFolderName +
"/neural_net_" + std::to_string(pid) +
107 "_eta_" + std::to_string(etaMin) +
"_" + std::to_string(etaMax) +
".json";
108 if (inputFile.empty()) {
112 ATH_MSG_INFO(
"For pid: " << pid <<
" and eta " << etaMin <<
"-" << etaMax
113 <<
", loading json file " << inputFile);
114 std::ifstream input(inputFile);
115 std::stringstream sin;
116 sin << input.rdbuf();
119 auto config = lwt::parse_json_graph(sin);
122 ATH_MSG_ERROR(
"Could not create LightWeightGraph from " << inputFile);
128 m_input =
new std::string(sin.str());
133 GetBinning(pid, (etaMin + etaMax) / 2, FastCaloGANInputFolderName);
144 int pid,
int etaMid,
const std::string &FastCaloGANInputFolderName) {
145 std::string xmlFullFileName = FastCaloGANInputFolderName +
"/binning.xml";
148 std::vector<Binning> AllBinning;
149 std::vector<int> EtaMaxList;
151 xmlDocPtr doc = xmlParseFile(xmlFullFileName.c_str());
152 for (xmlNodePtr nodeRoot = doc->children; nodeRoot !=
nullptr;
153 nodeRoot = nodeRoot->next) {
154 if (xmlStrEqual(nodeRoot->name, BAD_CAST
"Bins")) {
155 for (xmlNodePtr nodeBin = nodeRoot->children; nodeBin !=
nullptr;
156 nodeBin = nodeBin->next) {
157 if (xmlStrEqual(nodeBin->name, BAD_CAST
"Bin")) {
158 int nodePid = atof((
const char *)xmlGetProp(nodeBin, BAD_CAST
"pid"));
162 atof((
const char *)xmlGetProp(nodeBin, BAD_CAST
"etaMax"));
165 bool correctentry =
true;
167 correctentry =
false;
169 for (xmlNodePtr nodeLayer = nodeBin->children; nodeLayer !=
nullptr;
170 nodeLayer = nodeLayer->next) {
171 if (xmlStrEqual(nodeLayer->name, BAD_CAST
"Layer")) {
172 std::vector<double> edges;
174 (
const char *)xmlGetProp(nodeLayer, BAD_CAST
"r_edges"));
176 std::istringstream
ss(s);
179 while (std::getline(
ss, token,
',')) {
180 edges.push_back(atof(token.c_str()));
183 int binsInAlpha = atof(
184 (
const char *)xmlGetProp(nodeLayer, BAD_CAST
"n_bin_alpha"));
186 atof((
const char *)xmlGetProp(nodeLayer, BAD_CAST
"id"));
190 << nodeEtaMax <<
" Layer: " << layer
191 <<
" binsInAlpha: " << binsInAlpha
194 std::string name =
"hist_pid_" + std::to_string(nodePid) +
196 std::to_string(EtaMaxList.size()) +
"_layer_" +
197 std::to_string(layer);
198 int xBins = edges.size() - 1;
205 TH2D(name.c_str(), name.c_str(), xBins, &edges[0],
206 binsInAlpha, -TMath::Pi(), TMath::Pi());
207 binsInLayer[layer].SetDirectory(
nullptr);
213 AllBinning.push_back(std::move(binsInLayer));
214 EtaMaxList.push_back(nodeEtaMax);
221 for (
int etaMax : EtaMaxList) {
222 if (etaMid < etaMax) {
237 Form(
"layer=%d", simulstate.
getAuxInfo<
int>(
"GANlayer"_FCShash)));
245 trueEnergy = truth->P();
246 double randUniformZ = 0.;
249 randUniformZ = CLHEP::RandFlat::shoot(simulstate.
randomEngine(), -1., 1.);
250 inputs[
"node_0"].insert(
251 std::pair<std::string, double>(std::to_string(i), randUniformZ));
256 inputs[
"node_1"].insert(
257 std::pair<std::string, double>(
"0", trueEnergy / (std::pow(2, 22))));
266 const int pdgId = truth->
pdgid();
267 const float charge = HepPDT::ParticleID(pdgId).charge();
270 const float Ekin = truth->
Ekin();
272 Einit = simulstate.
E();
292 for (
const auto& element : binsInLayers) {
293 int layer = element.first;
295 const TH2D *
h = &element.second;
296 int xBinNum =
h->GetNbinsX();
301 <<
" has only one bin in r, this means is it not used, "
302 "skipping (this is needed to keep correct "
303 "syncronisation of voxel and layers)");
310 int yBinNum =
h->GetNbinsY();
313 for (
int iy = 1; iy <= yBinNum; ++iy) {
314 for (
int ix = 1; ix <= xBinNum; ++ix) {
315 double energyInVoxel = outputs[
"out_" + std::to_string(vox)];
317 <<
" binx " << ix <<
" biny " << iy);
319 if (energyInVoxel == 0) {
324 simulstate.
add_E(layer, Einit * energyInVoxel);
330 for (
unsigned int ichain =
m_bin_start.back(); ichain <
size(); ++ichain) {
339 for (
const auto& element : binsInLayers) {
340 int layer = element.first;
341 simulstate.
setAuxInfo<
int>(
"GANlayer"_FCShash, layer);
344 const TH2D *
h = &element.second;
345 int xBinNum =
h->GetNbinsX();
350 <<
" has only one bin in r, this means is it not used, "
351 "skipping (this is needed to keep correct "
352 "syncronisation of voxel and layers)");
358 const int bin =
get_bin(simulstate, truth, extrapol);
366 <<
chain()[ichain]->GetName());
367 if (
chain()[ichain]->InheritsFrom(
368 TFCSLateralShapeParametrizationHitBase::Class())) {
371 if (sim->
simulate_hit(hit, simulstate, truth, extrapol) !=
376 <<
chain()[ichain]->GetName());
383 <<
chain()[ichain]->GetName()
384 <<
" does not inherit from "
385 "TFCSLateralShapeParametrizationHitBase");
396 int binResolution = 5;
397 if (layer == 1 || layer == 5) {
401 const double center_eta = hit.center_eta();
402 const double center_phi = hit.center_phi();
403 const double center_r = hit.center_r();
404 const double center_z = hit.center_z();
407 <<
" phi " << center_phi <<
" R " << center_r);
409 const float dist000 =
410 TMath::Sqrt(center_r * center_r + center_z * center_z);
411 const float eta_jakobi = TMath::Abs(2.0 * TMath::Exp(-center_eta) /
412 (1.0 + TMath::Exp(-2 * center_eta)));
417 int yBinNum =
h->GetNbinsY();
420 for (
int iy = 1; iy <= yBinNum; ++iy) {
421 for (
int ix = 1; ix <= xBinNum; ++ix) {
423 double energyInVoxel = outputs[
"out_" + std::to_string(vox)];
425 <<
" binx " << ix <<
" biny " << iy);
427 if (energyInVoxel == 0) {
432 const TAxis *
x =
h->GetXaxis();
433 nHitsR =
x->GetBinUpEdge(ix) -
x->GetBinLowEdge(ix);
436 double r =
x->GetBinUpEdge(ix);
437 nHitsAlpha = ceil(2 * TMath::Pi() *
r / binResolution);
441 const TAxis *
y =
h->GetYaxis();
442 double angle =
y->GetBinUpEdge(iy) -
y->GetBinLowEdge(iy);
443 double r =
x->GetBinUpEdge(ix);
444 double d = 2 *
r * sin(
angle / 2 *
r);
445 nHitsAlpha = ceil(d / binResolution);
448 nHitsAlpha = std::min(10, std::max(1, nHitsAlpha));
449 nHitsR = std::min(10, std::max(1, nHitsR));
451 for (
int ir = 0;
ir < nHitsR; ++
ir) {
452 const TAxis *
x =
h->GetXaxis();
454 x->GetBinLowEdge(ix) +
x->GetBinWidth(ix) / (nHitsR + 1) *
ir;
456 for (
int ialpha = 0; ialpha < nHitsAlpha; ++ialpha) {
462 const TAxis *
y =
h->GetYaxis();
463 alpha =
y->GetBinLowEdge(iy) +
464 y->GetBinWidth(iy) / (nHitsAlpha + 1) * ialpha;
468 hit.E() = Einit * energyInVoxel / (nHitsAlpha * nHitsR);
471 float delta_eta_mm =
r * cos(alpha);
472 float delta_phi_mm =
r * sin(alpha);
482 delta_eta_mm = -delta_eta_mm;
486 if ((
charge < 0. && pdgId!=11) || pdgId==-11)
487 delta_phi_mm = -delta_phi_mm;
489 const float delta_eta = delta_eta_mm / eta_jakobi / dist000;
490 const float delta_phi = delta_phi_mm / center_r;
492 hit.eta() = center_eta + delta_eta;
493 hit.phi() = center_phi + delta_phi;
496 <<
" layer " << layer);
498 const float hit_r =
r * cos(alpha) + center_r;
499 float delta_phi =
r * sin(alpha) / center_r;
504 if ((
charge < 0. && pdgId!=11) || pdgId==-11)
505 delta_phi = -delta_phi;
506 const float hit_phi = delta_phi + center_phi;
507 hit.x() = hit_r * cos(hit_phi);
508 hit.y() = hit_r * sin(hit_phi);
511 <<
" layer " << layer);
515 const int bin =
get_bin(simulstate, truth, extrapol);
517 for (
unsigned int ichain =
523 <<
chain()[ichain]->GetName());
524 if (
chain()[ichain]->InheritsFrom(
525 TFCSLateralShapeParametrizationHitBase::Class())) {
529 if (sim->
simulate_hit(hit, simulstate, truth, extrapol) !=
535 <<
chain()[ichain]->GetName());
542 <<
chain()[ichain]->GetName()
543 <<
" does not inherit from "
544 "TFCSLateralShapeParametrizationHitBase");
568 if (simulstate.
E() > std::numeric_limits<double>::epsilon()) {
570 simulstate.
set_Efrac(ilayer, simulstate.
E(ilayer) / simulstate.
E());
583 for (
unsigned int ichain = 0; ichain <
m_bin_start[0]; ++ichain) {
602 if (!
fillEnergy(simulstate, truth, extrapol, std::move(inputs))) {
614 bool shortprint = opt.Index(
"short") >= 0;
615 bool longprint =
msgLvl(MSG::DEBUG) || (
msgLvl(MSG::INFO) && !shortprint);
616 TString optprint = opt;
617 optprint.ReplaceAll(
"short",
"");
625 <<
"; Binning size=" <<
m_Binning.size());
629 <<
"layer=" << l.first
630 <<
" nR=" << l.second.GetNbinsX()
631 <<
" nalpha=" << l.second.GetNbinsY());
635 TString prefix =
"- ";
636 for (
unsigned int ichain = 0; ichain <
size(); ++ichain) {
637 if (ichain == 0 && ichain !=
m_bin_start.front()) {
647 prefix = Form(
"%-2d", ibin);
657 chain()[ichain]->Print(opt + prefix);
661void TFCSEnergyAndHitGAN::Streamer(TBuffer &R__b) {
664 if (R__b.IsReading()) {
665 R__b.ReadClassBuffer(TFCSEnergyAndHitGAN::Class(),
this);
671 std::stringstream
sin;
673 auto config = lwt::parse_json_graph(sin);
674 m_graph =
new lwt::LightweightGraph(config);
676#ifndef __FastCaloSimStandAlone__
684 R__b.WriteClassBuffer(TFCSEnergyAndHitGAN::Class(),
this);
693#if defined(__FastCaloSimStandAlone__)
701 t->SetPtEtaPhiM(20000, 0.225, 0, 130);
707 e->set_IDCaloBoundary_eta(truth->Eta());
708 for (
int i = 0; i < 24; ++i) {
729 int etaMax = etaMin + 5;
732 "/eos/atlas/atlascerngroupdisk/proj-simul/VoxalisationOutputs/nominal/"
733 "GAN_michele_normE_MaxE/input_for_service_new");
734 for (
int i = 0; i < 24; ++i)
737 Form(
"center%d", i), Form(
"center layer %d", i));
738 c->set_calosample(i);
739 c->setExtrapWeight(0.5);
740 c->setLevel(MSG::VERBOSE);
746 c->set_eta_min(etaMin / 100.0);
747 c->set_eta_max(etaMax / 100.0);
748 c->set_eta_nominal((etaMin + etaMax) / 200.0);
756 TFile *fGAN = TFile::Open(
"FCSGANtest.root",
"recreate");
761 fGAN = TFile::Open(
"FCSGANtest.root");
766 GAN2->
simulate(*simulstate, truth, extrapol);
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Helper for getting a const version of a pointer.
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 FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
unsigned int get_nr_of_init(unsigned int bin) const
bool OnlyScaleEnergy() const
lwt::LightweightGraph * m_graph
void set_nr_of_init(unsigned int bin, unsigned int ninit)
virtual void Print(Option_t *option="") const override
virtual int get_bin(TFCSSimulationState &simulstate, const TFCSTruthState *, const TFCSExtrapolationState *) const override
use the layer to be done as binning of the GAN chain
Binning m_Binning
Do not persistify.
TFCSEnergyAndHitGAN(const char *name=nullptr, const char *title=nullptr)
bool fillEnergy(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol, NetworkInputs inputs) const
const Binning & get_Binning() const
std::map< std::string, double > NetworkOutputs
virtual ~TFCSEnergyAndHitGAN()
virtual const std::string get_variable_text(TFCSSimulationState &simulstate, const TFCSTruthState *, const TFCSExtrapolationState *) const override
std::map< std::string, std::map< std::string, double > > NetworkInputs
std::map< int, TH2D > Binning
void GetBinning(int pid, int etaMax, const std::string &FastCaloGANInputFolderName)
virtual bool is_match_calosample(int calosample) const override
bool initializeNetwork(int pid, int etaMin, const std::string &FastCaloGANInputFolderName)
std::vector< int > m_bin_ninit
static void unit_test(TFCSSimulationState *simulstate=nullptr, const TFCSTruthState *truth=nullptr, const TFCSExtrapolationState *extrapol=nullptr)
bool fillFastCaloGanNetworkInputs(TFCSSimulationState &simulstate, const TFCSTruthState *truth, NetworkInputs &inputs, double &trueEnergy) const
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
const T * as_const_ptr(const T *p)
Helper for getting a const version of a pointer.