ATLAS Offline Software
FastCaloSimV2Tool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // class header include
6 #include "FastCaloSimV2Tool.h"
7 
8 
9 // FastCaloSim includes
15 
17 
22 #include "CaloIdentifier/TileID.h"
24 
25 // StoreGate
26 #include "StoreGate/StoreGateSvc.h"
27 
29 
31 #include "CaloDetDescr/CaloDetDescrElement.h"
34 
36 
37 #include "CLHEP/Units/SystemOfUnits.h"
38 
39 #include "TFile.h"
40 #include <fstream>
41 
42 using std::abs;
43 using std::atan2;
44 
46 ISF::FastCaloSimV2Tool::FastCaloSimV2Tool( const std::string& type, const std::string& name, const IInterface* parent)
48 {
49 }
50 
53 {
55 
56  ATH_CHECK( m_caloCellMakerToolsSetup.retrieve() );
57  ATH_MSG_DEBUG( "Successfully retrieve CaloCellMakerTools: " << m_caloCellMakerToolsSetup );
58  ATH_CHECK( m_caloCellMakerToolsRelease.retrieve() );
59 
60  ATH_CHECK(m_rndmGenSvc.retrieve());
61 
62  ATH_CHECK(m_paramSvc.retrieve());
63 
64  m_doPunchThrough = not m_punchThroughTool.empty();
65  if (m_doPunchThrough) {
66  ATH_CHECK(m_punchThroughTool.retrieve());
67  }
68 
69  ATH_CHECK(m_truthRecordSvc.retrieve());
70 
71  // Get FastCaloSimCaloExtrapolation
72  ATH_CHECK(m_FastCaloSimCaloExtrapolation.retrieve());
73 
74  // Output data handle
75  ATH_CHECK( m_caloCellKey.initialize() );
76 
77  return StatusCode::SUCCESS;
78 }
79 
81 {
82  ATH_MSG_DEBUG ("setupEventST");
83 
84  m_theContainer = std::make_unique<CaloCellContainer>(SG::VIEW_ELEMENTS);
85  m_theContainerPtr = m_theContainer.get();
86  ATH_CHECK(evtStore()->record(std::move(m_theContainer), m_caloCellsOutputName));
87  // NB: m_theContainer is now nullptr
88  const EventContext& ctx = Gaudi::Hive::currentContext();
89  return this->commonSetup(ctx);
90 }
91 
93 {
94  ATH_MSG_DEBUG ("setupEvent");
95 
96  m_theContainer = std::make_unique<CaloCellContainer>(SG::VIEW_ELEMENTS);
97  m_theContainerPtr = m_theContainer.get();
98  return this->commonSetup(ctx);
99 }
100 
102 {
103  // Set the RNGs to use for this event. We need to reset it for MT jobs
104  // because of the mismatch between Gaudi slot-local and G4 thread-local RNG.
105  ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this, m_randomEngineName);
106  rngWrapper->setSeed( m_randomEngineName, ctx );
107 
108  for (const ToolHandle<ICaloCellMakerTool>& tool : m_caloCellMakerToolsSetup)
109  {
110  std::string chronoName=this->name()+"_"+ tool.name();
111  if (m_chrono) m_chrono->chronoStart(chronoName);
112  StatusCode sc = tool->process(m_theContainerPtr, ctx);
113  if (m_chrono) {
114  m_chrono->chronoStop(chronoName);
115  ATH_MSG_DEBUG( "Chrono stop : delta " << m_chrono->chronoDelta (chronoName,IChronoStatSvc::USER) * CLHEP::microsecond / CLHEP::second << " second " );
116  }
117 
118  if (sc.isFailure())
119  {
120  ATH_MSG_ERROR( "Error executing tool " << tool.name() );
121  return StatusCode::FAILURE;
122  }
123  }
124 
125  return StatusCode::SUCCESS;
126 }
127 
129 {
130  ATH_MSG_VERBOSE( "FastCaloSimV2Tool " << name() << " releaseEvent() " );
131  // Run the version of releaseEvent that returns the output collection
132  // Run the normal method
133  ATH_CHECK(this->releaseEventST());
134  if ( m_theContainer ) {
135 
136  // Record with WriteHandle
137  SG::WriteHandle< CaloCellContainer > caloCellHandle( m_caloCellKey, ctx );
138  ATH_CHECK( caloCellHandle.record( std::move( m_theContainer ) ) );
139  return StatusCode::SUCCESS;
140  }
141  return StatusCode::FAILURE;
142 }
143 
145 {
146  ATH_MSG_VERBOSE("release Event");
147  const EventContext& ctx = Gaudi::Hive::currentContext();
148 
149  //run release tools in a loop
150  for (const ToolHandle<ICaloCellMakerTool>& tool : m_caloCellMakerToolsRelease)
151  {
152  ATH_MSG_VERBOSE( "Calling tool " << tool.name() );
153 
154  ATH_CHECK(tool->process(m_theContainerPtr, ctx));
155  }
156 
157  return StatusCode::SUCCESS;
158 
159 }
160 
163 {
164 
165  ATH_MSG_VERBOSE("NEW PARTICLE! FastCaloSimV2Tool called with ISFParticle: " << isfp);
166 
167  Amg::Vector3D particle_position = isfp.position();
168  Amg::Vector3D particle_direction(isfp.momentum().x(),isfp.momentum().y(),isfp.momentum().z());
169 
170  ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this, m_randomEngineName);
171 
172  //Don't simulate particles with total energy below 10 MeV
173  if(isfp.ekin() < 10) {
174  ATH_MSG_VERBOSE("Skipping particle with Ekin: " << isfp.ekin() <<" MeV. Below the 10 MeV threshold.");
175  return StatusCode::SUCCESS;
176  }
177 
178  TFCSTruthState truth;
179  truth.SetPtEtaPhiM(particle_direction.perp(), particle_direction.eta(), particle_direction.phi(), isfp.mass());
180  truth.set_pdgid(isfp.pdgCode());
181  truth.set_vertex(particle_position[Amg::x], particle_position[Amg::y], particle_position[Amg::z]);
182 
186  if(isfp.pdgCode() == -2212 || isfp.pdgCode() == -2112) {
187  truth.set_Ekin_off(2*isfp.mass());
188  ATH_MSG_VERBOSE("Found anti-proton/neutron, setting Ekin offset in TFCSTruthState.");
189  }
190 
192  m_FastCaloSimCaloExtrapolation->extrapolate(extrapol, &truth);
193 
194  ATH_MSG_DEBUG(" particle: " << isfp.pdgCode() << " Ekin: " << isfp.ekin() << " position eta: " << particle_position.eta() << " direction eta: " << particle_direction.eta() << " position phi: " << particle_position.phi() << " direction phi: " << particle_direction.phi());
195 
196  //only simulate if extrapolation to calo surface succeeded
197  if(extrapol.IDCaloBoundary_eta() != -999){
198  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
199  TFCSSimulationState simulstate(rndmEngine);
200 
201  ATH_CHECK(m_paramSvc->simulate(simulstate, &truth, &extrapol));
202 
203  ATH_MSG_DEBUG("Energy returned: " << simulstate.E());
204  ATH_MSG_VERBOSE("Energy fraction for layer: ");
205  for (int s = 0; s < CaloCell_ID_FCS::MaxSample; s++)
206  ATH_MSG_VERBOSE(" Sampling " << s << " energy " << simulstate.E(s));
207 
208  //Now deposit all cell energies into the CaloCellContainer
209  for(const auto& iter : simulstate.cells()) {
210  CaloCell* theCell = (CaloCell*)m_theContainerPtr->findCell(iter.first->calo_hash());
211  theCell->addEnergy(iter.second);
212  }
213 
214  //now perform punch through
215  if (m_doPunchThrough) {
216  int process = 201;
217  // call punch-through simulation
218  const ISF::ISFParticleVector *someSecondaries = m_punchThroughTool->computePunchThroughParticles(isfp, simulstate, rndmEngine);
219 
220  if (someSecondaries && !someSecondaries->empty()) {
221  //Record truth incident for created punch through particles
222  ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(isfp),
223  *someSecondaries,
224  process,
225  isfp.nextGeoID(), // inherits from the parent
227 
228  m_truthRecordSvc->registerTruthIncident( truth, true );
229  // At this point we need to update the properties of the
230  // ISFParticles produced in the interaction
232 
233  for (auto *secondary : *someSecondaries) {
234  if (secondary->getTruthBinding()) {
235  secondaries.push_back(secondary);
236  }
237  else {
238  ATH_MSG_WARNING("Secondary particle created by PunchThroughTool not written out to truth.\n Parent (" << isfp << ")\n Secondary (" << *secondary <<")");
239  delete secondary;
240  }
241  }
242  delete someSecondaries;
243  }
244  }
245  simulstate.DoAuxInfoCleanup();
246  }
247  else ATH_MSG_DEBUG("Skipping simulation as extrapolation to ID-Calo boundary failed.");
248 
249 
250  return StatusCode::SUCCESS;
251 
252 }
ISF::ISFParticleContainer
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
Definition: ISFParticleContainer.h:23
ISF::ISFParticle::ekin
double ekin() const
Kinetic energy.
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
ISF::ISFTruthIncident::updateChildParticleProperties
void updateChildParticleProperties()
Update the id and particleLink properties of the child particles (to be called after registerTruthInc...
Definition: ISFTruthIncident.cxx:239
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
LArEM_ID.h
TFCSSimulationState::DoAuxInfoCleanup
void DoAuxInfoCleanup()
Definition: TFCSSimulationState.cxx:79
ISF::FastCaloSimV2Tool::setupEventST
virtual StatusCode setupEventST() override final
Setup Event chain - in case of a begin-of event action is needed (called by ISimulationSvc)
Definition: FastCaloSimV2Tool.cxx:80
TFCSTruthState::set_Ekin_off
void set_Ekin_off(double val)
Definition: TFCSTruthState.h:23
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
TFCSSimulationState::cells
Cellmap_t & cells()
Definition: TFCSSimulationState.h:72
ISF::FastCaloSimV2Tool::commonSetup
StatusCode commonSetup(const EventContext &ctx)
Definition: FastCaloSimV2Tool.cxx:101
FCALDetectorManager.h
Amg::y
@ y
Definition: GeoPrimitives.h:35
ISF::ISFParticle
Definition: ISFParticle.h:42
ISF::FastCaloSimV2Tool::releaseEventST
virtual StatusCode releaseEventST() override final
Release Event chain - in case of an end-of event action is needed (called by ISimulationSvc)
Definition: FastCaloSimV2Tool.cxx:144
python.SystemOfUnits.microsecond
int microsecond
Definition: SystemOfUnits.py:122
ISFTruthIncident.h
ISF::ISFParticle::pdgCode
int pdgCode() const
PDG value.
TFCSExtrapolationState
Definition: TFCSExtrapolationState.h:13
RunActsMaterialValidation.extrapol
extrapol
Definition: RunActsMaterialValidation.py:91
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SUSY_SimplifiedModel_PostInclude.process
string process
Definition: SUSY_SimplifiedModel_PostInclude.py:42
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
TileID.h
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
ISF::ISFParticle::position
const Amg::Vector3D & position() const
The current position of the ISFParticle.
TFCSParametrizationBase.h
ISF::FastCaloSimV2Tool::simulate
virtual StatusCode simulate(const EventContext &ctx, ISFParticle &isp, ISFParticleContainer &, McEventCollection *mcEventCollection) override final
Simulation Call.
Definition: FastCaloSimV2Tool.cxx:162
AtlasDetectorID.h
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
CaloGeometryFromCaloDDM.h
Amg::z
@ z
Definition: GeoPrimitives.h:36
CaloCell_ID_FCS::MaxSample
@ MaxSample
Definition: FastCaloSim_CaloCell_ID.h:47
IdDictParser.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ISF::ISFParticle::nextGeoID
AtlasDetDescr::AtlasRegion nextGeoID() const
next geoID the particle will be simulated in
ISF::ISFTruthIncident
Definition: ISFTruthIncident.h:35
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::x
@ x
Definition: GeoPrimitives.h:34
ISF::ISFParticleVector
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.
Definition: ISFParticleContainer.h:26
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
ISF::FastCaloSimV2Tool::releaseEvent
virtual StatusCode releaseEvent(const EventContext &) override final
Release Event chain - in case of an end-of event action is needed.
Definition: FastCaloSimV2Tool.cxx:128
FastCaloSimV2Tool.h
PathResolver.h
ISF::BaseSimulatorTool
Definition: BaseSimulatorTool.h:36
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
ISF::ISFParticle::momentum
const Amg::Vector3D & momentum() const
The current momentum vector of the ISFParticle.
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
CaloCellContainer.h
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
RNGWrapper.h
ISF::BaseSimulatorTool::initialize
virtual StatusCode initialize() override
Definition: BaseSimulatorTool.h:57
SG::WriteHandle< CaloCellContainer >
ISF::FastCaloSimV2Tool::setupEvent
virtual StatusCode setupEvent(const EventContext &) override final
Setup Event chain - in case of a begin-of event action is needed.
Definition: FastCaloSimV2Tool.cxx:92
TFCSTruthState.h
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TFCSExtrapolationState.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TFCSTruthState::set_vertex
void set_vertex(const TLorentzVector &val)
Definition: TFCSTruthState.h:19
TFCSSimulationState::E
double E() const
Definition: TFCSSimulationState.h:42
ISF::FastCaloSimV2Tool::FastCaloSimV2Tool
FastCaloSimV2Tool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters.
Definition: FastCaloSimV2Tool.cxx:46
TFCSSimulationState.h
CaloCell::addEnergy
virtual void addEnergy(float energy)
add energy
Definition: CaloCell.cxx:141
ISF::FastCaloSimV2Tool::initialize
virtual StatusCode initialize() override final
Athena algorithm's interface methods.
Definition: FastCaloSimV2Tool.cxx:52
TFCSTruthState
Definition: TFCSTruthState.h:13
StoreGateSvc.h
TFCSSimulationState
Definition: TFCSSimulationState.h:32
TFCSTruthState::set_pdgid
void set_pdgid(int val)
Definition: TFCSTruthState.h:18
ISF::fKillsPrimary
@ fKillsPrimary
Definition: ISFTruthIncident.h:25
ISF::ISFParticle::mass
double mass() const
mass of the particle