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