ATLAS Offline Software
Loading...
Searching...
No Matches
TFCSEnergyAndHitGANV2.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "CLHEP/Random/RandFlat.h"
8#include "CLHEP/Random/RandGauss.h"
9#include "HepPDT/ParticleData.hh"
10#include "HepPDT/ParticleDataTable.hh"
17#include "TF1.h"
18#include "TFile.h"
19#include "TH2D.h"
20
21#if defined(__FastCaloSimStandAlone__)
22#include "CLHEP/Random/TRandomEngine.h"
23#else
24#include <CLHEP/Random/RanluxEngine.h>
25#endif
26
27#include <fstream>
28#include <iostream>
29#include <limits>
30
31//=============================================
32//======= TFCSEnergyAndHitGANV2 =========
33//=============================================
34
36 const char *title)
37 : TFCSParametrizationBinnedChain(name, title) {
39}
40
42 if (m_slice != nullptr) {
43 delete m_slice;
44 }
45}
46
48 if (get_Binning().find(calosample) == get_Binning().cend())
49 return false;
50 if (get_Binning().at(calosample).GetNbinsX() == 1)
51 return false;
52 return true;
53}
54
55unsigned int TFCSEnergyAndHitGANV2::get_nr_of_init(unsigned int bin) const {
56 if (bin >= m_bin_ninit.size())
57 return 0;
58 return m_bin_ninit[bin];
59}
60
62 unsigned int ninit) {
63 if (bin >= m_bin_ninit.size()) {
64 m_bin_ninit.resize(bin + 1, 0);
65 m_bin_ninit.shrink_to_fit();
66 }
67 m_bin_ninit[bin] = ninit;
68}
69
70// initialize lwtnn network
72 int const &pid, int const &etaMin,
73 const std::string &FastCaloGANInputFolderName) {
74
75 // initialize all necessary constants
76 // FIXME eventually all these could be stored in the .json file
77
79 "Using FastCaloGANInputFolderName: " << FastCaloGANInputFolderName);
80 // get neural net JSON file as an std::istream object
81 const int etaMax = etaMin + 5;
82
84 set_pdgid(pid);
85 if (pid == 11)
86 add_pdgid(-pid);
87 if (pid == 211)
88 add_pdgid(-pid);
89 set_eta_min(etaMin / 100.0);
90 set_eta_max(etaMax / 100.0);
91 set_eta_nominal((etaMin + etaMax) / 200.0);
92
93 int pidForXml = pid;
94 if (pid != 22 && pid != 11) {
95 pidForXml = 211;
96 }
97
98 const int etaMid = (etaMin + etaMax) / 2;
99 m_param.InitialiseFromXML(pidForXml, etaMid, FastCaloGANInputFolderName);
100 m_param.Print();
101 m_slice = new TFCSGANEtaSlice(pid, etaMin, etaMax, m_param);
102 m_slice->Print();
103 return m_slice->LoadGAN();
104}
105
107 TFCSSimulationState &simulstate, const TFCSTruthState *,
108 const TFCSExtrapolationState *) const {
109 return std::string(
110 Form("layer=%d", simulstate.getAuxInfo<int>("GANlayer"_FCShash)));
111}
112
114 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
115 const TFCSExtrapolationState *extrapol) const {
116 if (!truth) {
117 ATH_MSG_ERROR("Invalid truth pointer");
118 return false;
119 }
120
121 if (!extrapol) {
122 ATH_MSG_ERROR("Invalid extrapolation pointer");
123 return false;
124 }
125
126 const int pdgId = truth->pdgid();
127 const float charge = HepPDT::ParticleID(pdgId).charge();
128
129 float Einit;
130 const float Ekin = truth->Ekin();
131 if (OnlyScaleEnergy())
132 Einit = simulstate.E();
133 else
134 Einit = Ekin;
135
136 ATH_MSG_VERBOSE("Momentum " << truth->P() << " pdgId " << truth->pdgid());
137 // check that the network exists
138 if (!m_slice->IsGanCorrectlyLoaded()) {
139 ATH_MSG_WARNING("GAN not loaded correctly.");
140 return false;
141 }
142 // This lock is an attempt to fix ATLASSIM-7031. remove if not necessary
143 // Hold until NetworkOutputs goes out of scope
144 std::scoped_lock lock(m_mutex);
146 m_slice->GetNetworkOutputs(truth, extrapol, simulstate);
147 ATH_MSG_VERBOSE("network outputs size: " << outputs.size());
148
149 const TFCSGANXMLParameters::Binning &binsInLayers = m_param.GetBinning();
150 const auto ganVersion = m_param.GetGANVersion();
151 const TFCSGANEtaSlice::FitResultsPerLayer &fitResults =
152 m_slice->GetFitResults(); // used only if GAN version > 1
153
154 ATH_MSG_DEBUG("energy voxels size = " << outputs.size());
155
156 double totalEnergy = 0;
157 for (const auto & output : outputs) {
158 totalEnergy += output.second;
159 }
160 if (totalEnergy < 0) {
161 ATH_MSG_WARNING("Energy from GAN is negative, skipping particle");
162 return false;
163 }
164
165 ATH_MSG_VERBOSE("Get binning");
166
167 simulstate.set_E(0);
168
169 int vox = 0;
170 for (const auto &[layer, h] : binsInLayers) {
171 // attempt to debug intermittent ci issues described in
172 // https://its.cern.ch/jira/browse/ATLASSIM-7031
173 if (h.IsZombie() || h.IsOnHeap() || dynamic_cast<const TH2D*>(&h) == nullptr) {
174 ATH_MSG_ERROR("Histogram for layer " << layer << " is broken; " <<
175 "zombie: " << h.IsZombie() <<
176 "on heap: " << h.IsOnHeap() <<
177 "dynamic type: " << typeid(h).name());
178 ATH_MSG_INFO("See ATLASSIM-7031.");
179
180 ATH_MSG_INFO("Got truth state: ");
181 truth->Print();
182
183 ATH_MSG_INFO("Got extrapolation state: ");
184 extrapol->Print();
185
186 ATH_MSG_INFO("Got simulation state: ");
187 simulstate.Print();
188
189 ATH_MSG_INFO("Got GAN XML parameters: ");
190 m_param.Print();
191
192 return false;
193 }
194
195 const int xBinNum = h.GetNbinsX();
196 const int yBinNum = h.GetNbinsY();
197 const TAxis *x = h.GetXaxis();
198
199 // If only one bin in r means layer is empty, no value should be added
200 if (xBinNum == 1) {
201 ATH_MSG_VERBOSE(" Layer "
202 << layer
203 << " has only one bin in r, this means is it not used, "
204 "skipping (this is needed to keep correct "
205 "syncronisation of voxel and layers)");
206 // delete h;
207 continue;
208 }
209
210 ATH_MSG_VERBOSE(" Getting energy for Layer " << layer);
211
212 // First fill energies
213 for (int ix = 1; ix <= xBinNum; ++ix) {
214 double binsInAlphaInRBin = GetAlphaBinsForRBin(x, ix, yBinNum);
215 for (int iy = 1; iy <= binsInAlphaInRBin; ++iy) {
216 const double energyInVoxel = outputs.at(std::to_string(vox));
217 ATH_MSG_VERBOSE(" Vox " << vox << " energy " << energyInVoxel
218 << " binx " << ix << " biny " << iy);
219
220 if (energyInVoxel <= 0) {
221 vox++;
222 continue;
223 }
224
225 simulstate.add_E(layer, Einit * energyInVoxel);
226 vox++;
227 }
228 }
229 }
230
231 for (unsigned int ichain = m_bin_start.back(); ichain < size(); ++ichain) {
232 ATH_MSG_DEBUG("now run for all bins: " << chain()[ichain]->GetName());
233 if (simulate_and_retry(chain()[ichain], simulstate, truth, extrapol) !=
234 FCSSuccess) {
235 return FCSFatal;
236 }
237 }
238
239 vox = 0;
240 for (const auto &[layer, h] : binsInLayers) {
241 const int xBinNum = h.GetNbinsX();
242 const int yBinNum = h.GetNbinsY();
243 const TAxis *x = h.GetXaxis();
244 const TAxis *y = h.GetYaxis();
245
246 simulstate.setAuxInfo<int>("GANlayer"_FCShash, layer);
248
249 // If only one bin in r means layer is empty, no value should be added
250 if (xBinNum == 1) {
251 ATH_MSG_VERBOSE(" Layer "
252 << layer
253 << " has only one bin in r, this means is it not used, "
254 "skipping (this is needed to keep correct "
255 "syncronisation of voxel and layers)");
256 // delete h;
257 continue;
258 }
259
260 if (get_number_of_bins() > 0) {
261 const int bin = get_bin(simulstate, truth, extrapol);
262 if (bin >= 0 && bin < (int)get_number_of_bins()) {
263 for (unsigned int ichain = m_bin_start[bin];
264 ichain < TMath::Min(m_bin_start[bin] + get_nr_of_init(bin),
265 m_bin_start[bin + 1]);
266 ++ichain) {
267 ATH_MSG_DEBUG("for " << get_variable_text(simulstate, truth, extrapol)
268 << " run init " << get_bin_text(bin) << ": "
269 << chain()[ichain]->GetName());
270 if (chain()[ichain]->InheritsFrom(
271 TFCSLateralShapeParametrizationHitBase::Class())) {
273 static_cast<TFCSLateralShapeParametrizationHitBase *>(chain()[ichain]);
274 if (sim->simulate_hit(hit, simulstate, truth, extrapol) !=
275 FCSSuccess) {
276 ATH_MSG_ERROR("error for "
277 << get_variable_text(simulstate, truth, extrapol)
278 << " run init " << get_bin_text(bin) << ": "
279 << chain()[ichain]->GetName());
280 return false;
281 }
282 } else {
283 ATH_MSG_ERROR("for "
284 << get_variable_text(simulstate, truth, extrapol)
285 << " run init " << get_bin_text(bin) << ": "
286 << chain()[ichain]->GetName()
287 << " does not inherit from "
288 "TFCSLateralShapeParametrizationHitBase");
289 return false;
290 }
291 }
292 } else {
293 ATH_MSG_WARNING("nothing to init for "
294 << get_variable_text(simulstate, truth, extrapol)
295 << ": " << get_bin_text(bin));
296 }
297 }
298
299 int binResolution = 5;
300 if (layer == 1 || layer == 5) {
301 binResolution = 1;
302 }
303
304 const double center_eta = hit.center_eta();
305 const double center_phi = hit.center_phi();
306 const double center_r = hit.center_r();
307 const double center_z = hit.center_z();
308
309 ATH_MSG_VERBOSE(" Layer " << layer << " Extrap eta " << center_eta
310 << " phi " << center_phi << " R " << center_r);
311
312 const float dist000 =
313 TMath::Sqrt(center_r * center_r + center_z * center_z);
314 const float eta_jakobi = TMath::Abs(2.0 * TMath::Exp(-center_eta) /
315 (1.0 + TMath::Exp(-2 * center_eta)));
316
317 int nHitsAlpha{};
318 int nHitsR{};
319
320 // Now create hits
321 for (int ix = 1; ix <= xBinNum; ++ix) {
322 const int binsInAlphaInRBin = GetAlphaBinsForRBin(x, ix, yBinNum);
323
324 // Horrible work around for variable # of bins along alpha direction
325 const int binsToMerge = yBinNum == 32 ? 32 / binsInAlphaInRBin : 1;
326 for (int iy = 1; iy <= binsInAlphaInRBin; ++iy) {
327 const double energyInVoxel = outputs.at(std::to_string(vox));
328 const int lowEdgeIndex = (iy - 1) * binsToMerge + 1;
329
330 ATH_MSG_VERBOSE(" Vox " << vox << " energy " << energyInVoxel
331 << " binx " << ix << " biny " << iy);
332
333 if (energyInVoxel <= 0) {
334 vox++;
335 continue;
336 }
337
338 if (std::abs(pdgId) == 22 || std::abs(pdgId) == 11) {
339 // maximum 10 MeV per hit, equaly distributed in alpha and r
340 int maxHitsInVoxel = energyInVoxel * truth->Ekin() / 10;
341 if (maxHitsInVoxel < 1)
342 maxHitsInVoxel = 1;
343 nHitsAlpha = std::sqrt(maxHitsInVoxel);
344 nHitsR = std::sqrt(maxHitsInVoxel);
345 } else {
346 // One hit per mm along r
347 nHitsR = x->GetBinUpEdge(ix) - x->GetBinLowEdge(ix);
348 if (yBinNum == 1) {
349 // nbins in alpha depend on circumference lenght
350 const double r = x->GetBinUpEdge(ix);
351 nHitsAlpha = ceil(2 * TMath::Pi() * r / binResolution);
352 } else {
353 // d = 2*r*sin (a/2r) this distance at the upper r must be 1mm for
354 // layer 1 or 5, 5mm otherwise.
355 const double angle = y->GetBinUpEdge(iy) - y->GetBinLowEdge(iy);
356 const double r = x->GetBinUpEdge(ix);
357 const double d = 2 * r * sin(angle / 2 * r);
358 nHitsAlpha = ceil(d / binResolution);
359 }
360
361 if (layer != 1 && layer != 5) {
362 // For layers that are not EMB1 or EMEC1 use a maximum of 10 hits
363 // per direction, a higher granularity is needed for the other
364 // layers
365 const int maxNhits = 10;
366 nHitsAlpha = std::min(maxNhits, std::max(1, nHitsAlpha));
367 nHitsR = std::min(maxNhits, std::max(1, nHitsR));
368 }
369 }
370
371 for (int ir = 0; ir < nHitsR; ++ir) {
372 double r =
373 x->GetBinLowEdge(ix) + x->GetBinWidth(ix) / (nHitsR + 1) * ir;
374
375 for (int ialpha = 1; ialpha <= nHitsAlpha; ++ialpha) {
376 if (ganVersion > 1) {
377 if (fitResults.at(layer)[ix - 1] != 0) {
378 int tries = 0;
379 double a = CLHEP::RandFlat::shoot(simulstate.randomEngine(),
380 x->GetBinLowEdge(ix),
381 x->GetBinUpEdge(ix));
382 double rand_r =
383 log((a - x->GetBinLowEdge(ix)) / (x->GetBinWidth(ix))) /
384 fitResults.at(layer)[ix - 1];
385 while ((rand_r < x->GetBinLowEdge(ix) ||
386 rand_r > x->GetBinUpEdge(ix)) &&
387 tries < 100) {
388 a = CLHEP::RandFlat::shoot(simulstate.randomEngine(),
389 x->GetBinLowEdge(ix),
390 x->GetBinUpEdge(ix));
391 rand_r =
392 log((a - x->GetBinLowEdge(ix)) / (x->GetBinWidth(ix))) /
393 fitResults.at(layer)[ix - 1];
394 tries++;
395 }
396 if (tries >= 100) {
397 ATH_MSG_VERBOSE(" Too many tries for bin ["
398 << x->GetBinLowEdge(ix) << "-"
399 << x->GetBinUpEdge(ix) << "] having slope "
400 << fitResults.at(layer)[ix - 1]
401 << " will use grid (old method)");
402 } else {
403 r = rand_r;
404 }
405 }
406 }
407
408 double alpha;
409 if (binsInAlphaInRBin == 1) {
410 alpha = CLHEP::RandFlat::shoot(simulstate.randomEngine(),
411 -TMath::Pi(), TMath::Pi());
412 } else {
413 alpha =
414 y->GetBinLowEdge(lowEdgeIndex) +
415 y->GetBinWidth(iy) * binsToMerge / (nHitsAlpha + 1) * ialpha;
416
417 if (m_param.IsSymmetrisedAlpha()) {
418 if (CLHEP::RandFlat::shoot(simulstate.randomEngine(),
419 -TMath::Pi(), TMath::Pi()) < 0) {
420 alpha = -alpha;
421 }
422 }
423 }
424
425 hit.reset();
426 hit.E() = Einit * energyInVoxel / (nHitsAlpha * nHitsR);
427
428 if (layer <= 20) {
429 float delta_eta_mm = r * cos(alpha);
430 float delta_phi_mm = r * sin(alpha);
431
432 ATH_MSG_VERBOSE("delta_eta_mm " << delta_eta_mm
433 << " delta_phi_mm "
434 << delta_phi_mm);
435
436 // Particles with negative eta are expected to have the same shape
437 // as those with positive eta after transformation: delta_eta -->
438 // -delta_eta
439 if (center_eta < 0.)
440 delta_eta_mm = -delta_eta_mm;
441 // We derive the shower shapes for electrons and positively
442 // charged hadrons. Particle with the opposite charge are expected
443 // to have the same shower shape after the transformation:
444 // delta_phi --> -delta_phi
445 if ((charge < 0. && pdgId != 11) || pdgId == -11)
446 delta_phi_mm = -delta_phi_mm;
447
448 const float delta_eta = delta_eta_mm / eta_jakobi / dist000;
449 const float delta_phi = delta_phi_mm / center_r;
450
451 hit.eta() = center_eta + delta_eta;
452 hit.phi() = TVector2::Phi_mpi_pi(center_phi + delta_phi);
453
454 ATH_MSG_VERBOSE(" Hit eta " << hit.eta() << " phi " << hit.phi()
455 << " layer " << layer);
456 } else { // FCAL is in (x,y,z)
457 const float hit_r = r * cos(alpha) + center_r;
458 float delta_phi = r * sin(alpha) / center_r;
459 // We derive the shower shapes for electrons and positively
460 // charged hadrons. Particle with the opposite charge are expected
461 // to have the same shower shape after the transformation:
462 // delta_phi --> -delta_phi
463 if ((charge < 0. && pdgId != 11) || pdgId == -11)
464 delta_phi = -delta_phi;
465 const float hit_phi =
466 TVector2::Phi_mpi_pi(center_phi + delta_phi);
467 hit.x() = hit_r * cos(hit_phi);
468 hit.y() = hit_r * sin(hit_phi);
469 hit.z() = center_z;
470 ATH_MSG_VERBOSE(" Hit x " << hit.x() << " y " << hit.y()
471 << " layer " << layer);
472 }
473
474 if (get_number_of_bins() > 0) {
475 const int bin = get_bin(simulstate, truth, extrapol);
476 if (bin >= 0 && bin < (int)get_number_of_bins()) {
477 for (unsigned int ichain =
479 ichain < m_bin_start[bin + 1]; ++ichain) {
481 "for " << get_variable_text(simulstate, truth, extrapol)
482 << " run " << get_bin_text(bin) << ": "
483 << chain()[ichain]->GetName());
484 if (chain()[ichain]->InheritsFrom(
485 TFCSLateralShapeParametrizationHitBase::Class())) {
488 *>(chain()[ichain]);
489 if (sim->simulate_hit(hit, simulstate, truth, extrapol) !=
490 FCSSuccess) {
492 "error for "
493 << get_variable_text(simulstate, truth, extrapol)
494 << " run init " << get_bin_text(bin) << ": "
495 << chain()[ichain]->GetName());
496 return false;
497 }
498 } else {
500 "for " << get_variable_text(simulstate, truth, extrapol)
501 << " run init " << get_bin_text(bin) << ": "
502 << chain()[ichain]->GetName()
503 << " does not inherit from "
504 "TFCSLateralShapeParametrizationHitBase");
505 return false;
506 }
507 }
508 } else {
510 "nothing to do for "
511 << get_variable_text(simulstate, truth, extrapol) << ": "
512 << get_bin_text(bin));
513 }
514 } else {
515 ATH_MSG_WARNING("no bins defined, is this intended?");
516 }
517 }
518 }
519 vox++;
520 }
521 }
522
523 ATH_MSG_VERBOSE("Number of voxels " << vox);
524 ATH_MSG_VERBOSE("Done layer " << layer);
525 }
526
527 if (simulstate.E() > std::numeric_limits<double>::epsilon()) {
528 for (int ilayer = 0; ilayer < CaloCell_ID_FCS::MaxSample; ++ilayer) {
529 simulstate.set_Efrac(ilayer, simulstate.E(ilayer) / simulstate.E());
530 }
531 }
532
533 ATH_MSG_VERBOSE("Done particle");
534 return true;
535}
536
538 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
539 const TFCSExtrapolationState *extrapol) const {
540 for (unsigned int ichain = 0; ichain < m_bin_start[0]; ++ichain) {
541 ATH_MSG_DEBUG("now run for all bins: " << chain()[ichain]->GetName());
542 if (simulate_and_retry(chain()[ichain], simulstate, truth, extrapol) !=
543 FCSSuccess) {
544 return FCSFatal;
545 }
546 }
547
548 ATH_MSG_VERBOSE("Fill Energies");
549 if (!fillEnergy(simulstate, truth, extrapol)) {
550 ATH_MSG_WARNING("Could not fill energies ");
551 // bail out but do not stop the job
552 return FCSSuccess;
553 }
554
555 return FCSSuccess;
556}
557
558void TFCSEnergyAndHitGANV2::Print(Option_t *option) const {
560 TString opt(option);
561 const bool shortprint = opt.Index("short") >= 0;
562 const bool longprint =
563 msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
564 TString optprint = opt;
565 optprint.ReplaceAll("short", "");
566
567 TString prefix = "- ";
568 for (unsigned int ichain = 0; ichain < size(); ++ichain) {
569 if (ichain == 0 && ichain != m_bin_start.front()) {
570 prefix = "> ";
571 if (longprint)
572 ATH_MSG_INFO(optprint << prefix << "Run for all bins");
573 }
574 for (unsigned int ibin = 0; ibin < get_number_of_bins(); ++ibin) {
575 if (ichain == m_bin_start[ibin]) {
576 if (ibin < get_number_of_bins() - 1)
577 if (ichain == m_bin_start[ibin + 1])
578 continue;
579 prefix = Form("%-2d", ibin);
580 if (longprint)
581 ATH_MSG_INFO(optprint << prefix << "Run for " << get_bin_text(ibin));
582 }
583 }
584 if (ichain == m_bin_start.back()) {
585 prefix = "< ";
586 if (longprint)
587 ATH_MSG_INFO(optprint << prefix << "Run for all bins");
588 }
589 chain()[ichain]->Print(opt + prefix);
590 }
591}
592
594 const TFCSTruthState *truth,
595 const TFCSExtrapolationState *extrapol) {
597 ATH_MSG_NOCLASS(logger, "Start lwtnn test" << std::endl);
598 std::string path =
599 "/eos/atlas/atlascerngroupdisk/proj-simul/AF3_Run3/"
600 "InputsToBigParamFiles/FastCaloGANWeightsVer02/";
601 test_path(path, simulstate, truth, extrapol, "lwtnn");
602
603 ATH_MSG_NOCLASS(logger, "Start onnx test" << std::endl);
604 path =
605 "/eos/atlas/atlascerngroupdisk/proj-simul/AF3_Run3/"
606 "InputsToBigParamFiles/FastCaloGANWeightsONNXVer08/";
607 test_path(path, simulstate, truth, extrapol, "onnx");
608 ATH_MSG_NOCLASS(logger, "Finish all tests" << std::endl);
609}
610
611void TFCSEnergyAndHitGANV2::test_path(const std::string &path,
612 TFCSSimulationState *simulstate,
613 const TFCSTruthState *truth,
614 const TFCSExtrapolationState *extrapol,
615 const std::string &outputname, int pid) {
617 ATH_MSG_NOCLASS(logger, "Running test on " << path << std::endl);
618 if (!simulstate) {
619 simulstate = new TFCSSimulationState();
620#if defined(__FastCaloSimStandAlone__)
621 simulstate->setRandomEngine(new CLHEP::TRandomEngine());
622#else
623 simulstate->setRandomEngine(new CLHEP::RanluxEngine());
624#endif
625 }
626 if (!truth) {
627 ATH_MSG_NOCLASS(logger, "New particle");
629 t->SetPtEtaPhiM(65536, 0, 0, ParticleConstants::chargedPionMassInMeV);
630 t->set_pdgid(pid);
631 truth = t;
632 }
633 if (!extrapol) {
635 e->set_IDCaloBoundary_eta(truth->Eta());
636 for (int i = 0; i < 24; ++i) {
637 e->set_eta(i, TFCSExtrapolationState::SUBPOS_ENT, truth->Eta());
638 e->set_eta(i, TFCSExtrapolationState::SUBPOS_EXT, truth->Eta());
639 e->set_eta(i, TFCSExtrapolationState::SUBPOS_MID, truth->Eta());
640 e->set_phi(i, TFCSExtrapolationState::SUBPOS_ENT, 0);
641 e->set_phi(i, TFCSExtrapolationState::SUBPOS_EXT, 0);
642 e->set_phi(i, TFCSExtrapolationState::SUBPOS_MID, 0);
643 e->set_r(i, TFCSExtrapolationState::SUBPOS_ENT, 1500 + i * 10);
644 e->set_r(i, TFCSExtrapolationState::SUBPOS_EXT, 1510 + i * 10);
645 e->set_r(i, TFCSExtrapolationState::SUBPOS_MID, 1505 + i * 10);
646 e->set_z(i, TFCSExtrapolationState::SUBPOS_ENT, 3500 + i * 10);
647 e->set_z(i, TFCSExtrapolationState::SUBPOS_EXT, 3510 + i * 10);
648 e->set_z(i, TFCSExtrapolationState::SUBPOS_MID, 3505 + i * 10);
649 }
650 extrapol = e;
651 }
652
653 TFCSEnergyAndHitGANV2 GAN("GAN", "GAN");
654 GAN.setLevel(MSG::INFO);
655 const int etaMin = 20;
656 const int etaMax = etaMin + 5;
657 ATH_MSG_NOCLASS(logger, "Initialize Networks");
658 GAN.initializeNetwork(pid, etaMin, path);
659 for (int i = 0; i < 24; ++i)
660 if (GAN.is_match_calosample(i)) {
662 Form("center%d", i), Form("center layer %d", i));
663 c->set_calosample(i);
664 c->setExtrapWeight(0.5);
665 c->setLevel(MSG::INFO);
666 c->set_pdgid(pid);
667 if (pid == 11)
668 c->add_pdgid(-pid);
669 if (pid == 211)
670 c->add_pdgid(-pid);
671 c->set_eta_min(etaMin / 100.0);
672 c->set_eta_max(etaMax / 100.0);
673 c->set_eta_nominal((etaMin + etaMax) / 200.0);
674
675 GAN.push_back_in_bin(c, i);
676 GAN.set_nr_of_init(i, 1);
677 }
678
679 GAN.Print();
680
681 ATH_MSG_NOCLASS(logger, "Writing GAN to " << outputname);
682 const std::string outname = "FCSGANtest_" + outputname + ".root";
683 TFile *fGAN = TFile::Open(outname.c_str(), "recreate");
684 fGAN->cd();
685 // GAN.Write();
686 fGAN->WriteObjectAny(&GAN, "TFCSEnergyAndHitGANV2", "GAN");
687
688 fGAN->ls();
689 fGAN->Close();
690 delete fGAN;
691
692 ATH_MSG_NOCLASS(logger, "Open " << outname);
693 fGAN = TFile::Open(outname.c_str());
694 TFCSEnergyAndHitGANV2 *GAN2 = (TFCSEnergyAndHitGANV2 *)(fGAN->Get("GAN"));
695 GAN2->setLevel(MSG::INFO);
696 GAN2->Print();
697
698 ATH_MSG_NOCLASS(logger, "Before running GAN2->simulate()");
699 GAN2->simulate(*simulstate, truth, extrapol);
700 simulstate->Print();
701 delete fGAN;
702}
703
705 if (bins < 4)
706 return 4;
707 else if (bins < 8)
708 return 8;
709 else if (bins < 16)
710 return 16;
711 else
712 return 32;
713}
714
716 int yBinNum) const {
717 double binsInAlphaInRBin = yBinNum;
718 if (yBinNum == 32) {
719 ATH_MSG_DEBUG("yBinNum is special value 32");
720 const double widthX = x->GetBinWidth(ix);
721 const double radious = x->GetBinCenter(ix);
722 double circumference = radious * 2. * TMath::Pi();
723 if (m_param.IsSymmetrisedAlpha()) {
724 circumference = radious * TMath::Pi();
725 }
726
727 const double bins = circumference / widthX;
728 binsInAlphaInRBin = GetBinsInFours(bins);
729 ATH_MSG_DEBUG("Bin in alpha: " << binsInAlphaInRBin << " for r bin: " << ix
730 << " (" << x->GetBinLowEdge(ix) << "-"
731 << x->GetBinUpEdge(ix) << ")");
732 }
733 return binsInAlphaInRBin;
734}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t a
#define ATH_MSG_NOCLASS(logger_name, x)
Definition MLogging.h:52
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)
#define y
#define x
Header file for AthHistogramAlgorithm.
Cut down AthMessaging.
Definition MLogging.h:176
bool msgLvl(const MSG::Level lvl) const
Check whether the logging system is active at the provided verbosity level.
Definition MLogging.h:222
virtual void setLevel(MSG::Level lvl)
Update outputlevel.
Definition MLogging.cxx:105
std::vector< int > m_bin_ninit
bool initializeNetwork(int const &pid, int const &etaMin, const std::string &FastCaloGANInputFolderName)
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)
virtual void Print(Option_t *option="") const 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
void Print(Option_t *option="") const
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.
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)
void Print(Option_t *option="") const
int pdgid() const
double Ekin() const
int ir
counter of the current depth
Definition fastadd.cxx:49
int r
Definition globals.cxx:22
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
static Root::TMsgLogger logger("iLumiCalc")
constexpr double chargedPionMassInMeV
the mass of the charged pion (in MeV)