24 #include "CLHEP/Units/SystemOfUnits.h"
25 #include "CLHEP/Units/PhysicalConstants.h"
26 #include "CLHEP/Random/RandFlat.h"
47 m_rndGenSvc(
"AtDSFMTGenSvc",
n),
48 m_randomEngine(nullptr),
49 m_randomEngineName(
"FatrasRnd"),
50 m_validationOutput(false),
52 m_particleDecayHelper(
""),
53 m_simHitCreatorID(
""),
54 m_simHitCreatorMS(
""),
57 m_neutralHadronFilter(
""),
59 m_iparticleHelper(
""),
61 m_errorPropagation(false),
93 delete m_randomEngine;
107 if (retrieveTool<iFatras::ISimHitCreator>(m_simHitCreatorID).isFailure())
108 return StatusCode::FAILURE;
109 if (retrieveTool<iFatras::ISimHitCreator>(m_simHitCreatorMS).isFailure())
110 return StatusCode::FAILURE;
111 if (retrieveTool<Trk::ITimedExtrapolator>(m_extrapolator).isFailure())
112 return StatusCode::FAILURE;
113 if (retrieveTool<iFatras::IParticleDecayHelper>(m_particleDecayHelper).isFailure())
114 return StatusCode::FAILURE;
115 if (retrieveTool<ISF::IParticleFilter>(m_trackFilter).isFailure())
116 return StatusCode::FAILURE;
117 if (retrieveTool<ISF::IParticleFilter>(m_photonFilter).isFailure())
118 return StatusCode::FAILURE;
119 if (retrieveTool<ISF::IParticleFilter>(m_neutralHadronFilter).isFailure())
120 return StatusCode::FAILURE;
121 if (retrieveTool<ISF::IParticleHelper>(m_iparticleHelper).isFailure())
122 return StatusCode::FAILURE;
123 if (retrieveTool<iFatras::IProcessSamplingTool>(m_samplingTool).isFailure())
124 return StatusCode::FAILURE;
125 ATH_CHECK( m_validationTool.retrieve( DisableTool{ m_validationTool.empty() || !m_validationOutput } ) );
127 if ( m_rndGenSvc.retrieve().isFailure() ){
129 return StatusCode::FAILURE;
132 m_randomEngine = m_rndGenSvc->GetEngine(m_randomEngineName);
133 if (!m_randomEngine) {
134 ATH_MSG_FATAL(
"Could not get random engine '" << m_randomEngineName <<
"'" );
135 return StatusCode::FAILURE;
138 return StatusCode::SUCCESS;
148 return StatusCode::SUCCESS;
170 std::vector<Trk::HitInfo>*
hitVector =
nullptr;
172 int absPdg = abs(isp.
pdgCode());
173 bool photon = (absPdg == 22);
175 bool neutrino = (absPdg == 12) || (absPdg == 14) || (absPdg == 16);
190 ATH_MSG_VERBOSE(
"[ fatras transport ] Photon - use transport tool for photons");
191 filter = m_photonFilter.empty() ? nullptr : &(*m_photonFilter);
192 }
else if ( neutrino ) {
193 ATH_MSG_VERBOSE(
"[ fatras transport ] Particle is neutrino -> particle ignored.");
196 ATH_MSG_VERBOSE(
"[ fatras transport ] Particle not charged - use transport tool for neutrals");
197 filter = m_neutralHadronFilter.empty() ? nullptr : &(*m_neutralHadronFilter);
199 ATH_MSG_VERBOSE(
"[ fatras transport ] Particle is a lepton or charged hadron");
200 filter = m_trackFilter.empty() ? nullptr : &(*m_trackFilter);
204 ATH_MSG_DEBUG(
"[ fatras transport ] Determined processor and filter.");
206 ATH_MSG_DEBUG(
"[ fatras transport ] Determined processor w/o filter.");
209 if ( !processor || (
filter && !
filter->passFilter(isp)) ) {
210 ATH_MSG_VERBOSE(
"[ fatras transport ] Filter not passed, ignore particle.");
214 ATH_MSG_VERBOSE(
"[ fatras transport ] The StackParticle passed filter - starting transport.");
219 double freepath = ( !m_particleDecayHelper.empty()) ? m_particleDecayHelper->freePath(isp) : - 1.;
220 ATH_MSG_VERBOSE(
"[ fatras transport ] Particle free path : " << freepath);
222 double tDec = freepath > 0. ? freepath : -1.;
238 if ( freepath>0. && freepath<0.01 ) {
239 if (!m_particleDecayHelper.empty()) {
240 ATH_MSG_VERBOSE(
"[ fatras transport ] Decay is triggered for input particle.");
245 if ( m_validationOutput && m_validationTool.isEnabled() ) {
246 int endProcess = decayProc;
247 m_validationTool->saveISFParticleInfo(isp,endProcess,&inputPar,timeLim.
time,0.);
259 }
else if (absPdg!=999 && pHypothesis<99) {
260 pathLim = m_samplingTool->sampleProcess(m_randomEngine, isp.
momentum().mag(),isp.
charge(),pHypothesis);
267 std::unique_ptr<const Trk::TrackParameters> eParameters =
nullptr;
270 hitVector = (!m_hitsOff) ?
new std::vector<Trk::HitInfo> :
nullptr;
285 if (m_validationOutput && m_errorPropagation ) {
289 std::unique_ptr<Trk::TrackParameters> measuredInputPar =
291 .createUniqueTrackParameters(inputPar.parameters()[0],
292 inputPar.parameters()[1],
293 inputPar.parameters()[2],
294 inputPar.parameters()[3],
295 inputPar.parameters()[4],
296 std::move(inputCov));
323 if (!m_simHitCreatorID.empty()) m_simHitCreatorID->createHits(isp, *
hitVector);
328 if (!m_simHitCreatorMS.empty()) m_simHitCreatorMS->createHits(isp, *
hitVector);
342 if ( m_validationOutput && m_validationTool.isEnabled() ) {
347 int endProcess = eParameters ? 0 : ( dProc > mProc ? dProc : mProc );
349 m_validationTool->saveISFParticleInfo(isp,endProcess,eParameters.get(),timeLim.
time,pathLim.
x0Collected);
354 ISF::ISFParticle* uisp = eParameters ? m_iparticleHelper->updatedParticle(isp,
363 if (uisp && m_validationOutput) {
376 if (uisp && timeLim.
tMax>0. && timeLim.
time >=timeLim.
tMax ) {
377 if (!m_particleDecayHelper.empty()) {
378 ATH_MSG_VERBOSE(
"[ fatras transport ] Decay is triggered for input particle.");
384 ATH_MSG_VERBOSE(
"[ fatras transport ] Particle transported to detector boundary, return to stack, timing:" << uisp->
timeStamp());