7#include "GaudiKernel/Bootstrap.h"
8#include "GaudiKernel/ISvcLocator.h"
15#include "CLHEP/Random/RandFlat.h"
19#include "G4Electron.hh"
21#include "G4Positron.hh"
22#include "G4Neutron.hh"
23#include "G4PionPlus.hh"
24#include "G4PionMinus.hh"
25#include "G4VSensitiveDetector.hh"
26#include "G4EventManager.hh"
30#include "GaudiKernel/ConcurrencyFlags.h"
34#undef _TRACE_POSITION_
40 G4VFastSimulationModel(name, region),
55 std::string hepmcFileName =
m_configuration.m_generated_starting_points_file;
59 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1)
61 auto threadId = std::this_thread::get_id();
64 hepmcFileName +=
"."+
ss.str();
69 enum DETECTOR { EMB=100000, EMEC=200000, FCAL1=300000, FCAL2=400000,
70 FCAL3=500000, HECLOC=600000, HEC=700000 };
84 throw std::runtime_error(
"LArFastShower: no pointer to IFastSimDedicatedSD!");
93 SmartIF<ILArG4ShowerLibSvc> smartShowerLibSvc{Gaudi::svcLocator()->service(
m_configuration.m_showerLibSvcName)};
94 if ( smartShowerLibSvc ) {
m_showerLibSvc = smartShowerLibSvc.get(); }
96 throw std::runtime_error(
"LArFastShower: cannot retrieve LArG4ShowerLibSvc");
106 G4cout <<
"LArFastShower::IsApplicable" << G4endl;
136 G4cout <<
"LArFastShower::commonTrigger" << G4endl;
142 G4double particleEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
143 const G4ParticleDefinition&
particleType = *(fastTrack.GetPrimaryTrack()->GetDefinition());
150 G4cout <<
"Particle has energy (" << particleEnergy <<
") for shower lib and shower lib is on! Accept particle!" << G4endl;
155 G4cout <<
"Particle has energy (" << particleEnergy <<
") outside killing, shower lib and parametrisation "
156 <<
"or some features are switched off ... returning it to Geant " << G4endl;
167 G4cout <<
"LArFastShower::ModelTrigger() particle failed CheckContainment()... will not be parameterised: " << G4endl;
173 G4cout <<
"LArFastShower::ModelTrigger() direction: " << fastTrack.GetPrimaryTrackLocalDirection() << G4endl;
174 G4cout <<
"LArFastShower::ModelTrigger() mom dir: " << fastTrack.GetPrimaryTrack()->GetMomentumDirection() << G4endl;
184 G4cout <<
"LArFastShower::Doit()" << G4endl;
188 if (CLHEP::RandFlat::shoot(G4Random::getTheEngine()) <=
m_configuration.m_generated_starting_points_ratio) {
189 std::unique_ptr<const HepMC::GenEvent> ge =
GetGenEvent(fastTrack);
198 G4cout <<
"LArFastShower::Doit() done" << G4endl;
211 G4cout <<
"Low energy particle is being killed: " << fastTrack.GetPrimaryTrack()->GetKineticEnergy() << G4endl;
215 fastStep.KillPrimaryTrack();
216 fastStep.ProposePrimaryTrackPathLength(0.0);
225 G4cout <<
"LArFastShower::UseShowerLib()" << G4endl;
234 const std::vector<EnergySpot> shower =
238 G4cout <<
"Got shower (" << shower.size() <<
") from shower lib" << G4endl;
240 const double weight = (
m_configuration.m_applyRRWeights) ? fastTrack.GetPrimaryTrack()->GetWeight() : 1.0;
242 for (
const auto& a_spot : shower) {
245 G4cout <<
"Make Spot: " << a_spot.GetPosition().x() <<
" "
246 << a_spot.GetPosition().y() <<
" " << a_spot.GetPosition().z()
247 <<
" " << a_spot.GetEnergy() <<
" " << a_spot.GetTime() << G4endl;
252 G4cout <<
"Made Spot" << G4endl;
258 G4cout <<
"LArFastShower::UseShowerLib() Done" << G4endl;
265 catch (
const std::exception & e) {
266 G4cout <<
"FastShower::UseShowerLib ERROR Handling an exception in LArFastShower::" << e.what() << G4endl;
275 G4ThreeVector showerDirection = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
276 G4ThreeVector initialShowerPosition = fastTrack.GetPrimaryTrack()->GetPosition();
277 G4ThreeVector orthoShower = showerDirection.orthogonal();
278 G4ThreeVector crossShower = showerDirection.cross(orthoShower);
281 G4cout <<
"LArFastShower::CheckContainment() orthoShower: " << orthoShower << G4endl;
282 G4cout <<
"LArFastShower::CheckContainment() crossShower: " << crossShower << G4endl;
302 if (Z == 0.0 && R == 0.0) {
309 G4double Zmx = Z / 3;
311 G4int cosPhi[4] = {1,0,-1,0};
312 G4int sinPhi[4] = {0,1,0,-1};
315 G4cout <<
"LArFastShower::CheckContainment() R = " << R << G4endl;
316 G4cout <<
"LArFastShower::CheckContainment() Z = " << Z << G4endl;
319 G4ThreeVector position;
321 G4VSolid* caloSolid = fastTrack.GetEnvelopeSolid();
322 const G4AffineTransform* affineTransformation = fastTrack.GetAffineTransformation();
325 position = initialShowerPosition;
326 affineTransformation->ApplyPointTransform(position);
327 if(caloSolid->Inside(position) == kOutside)
331 position = initialShowerPosition + Z*showerDirection;
332 affineTransformation->ApplyPointTransform(position);
333 if(caloSolid->Inside(position) == kOutside)
337 for(
int i=0; i<4 ;i++)
339 position = initialShowerPosition + Zmx*showerDirection +
340 R*cosPhi[i]*orthoShower + R*sinPhi[i]*crossShower;
341 affineTransformation->ApplyPointTransform(position);
342 if(caloSolid->Inside(position) == kOutside)
347 G4cout <<
"LArFastShower::CheckContainment() Shower is contained " << G4endl;
356 const G4ThreeVector showerPos = fastTrack.GetPrimaryTrack()->GetPosition();
357 const G4ThreeVector showerMom = fastTrack.GetPrimaryTrack()->GetMomentum();
358 const G4double energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
360 G4int pdgcode = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGEncoding();
361 if (pdgcode < 0) pdgcode = -pdgcode;
363 HepMC3::Units::MomentumUnit momentumUnit = HepMC3::Units::MEV;
364 HepMC3::Units::LengthUnit lengthUnit = HepMC3::Units::MM;
366 std::unique_ptr<HepMC::GenEvent> ge = std::make_unique<HepMC::GenEvent>(momentumUnit,lengthUnit);
380 gv->add_particle_in(std::move(gpi));
386 gv->add_particle_out(std::move(gpo));
395 if ( &
particleType == G4Electron::ElectronDefinition() ||
398 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
400 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
402 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
410 if ( &
particleType == G4Electron::ElectronDefinition() ||
413 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
415 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
417 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
426 if ( &
particleType == G4Electron::ElectronDefinition() ||
429 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
431 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
433 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
448 G4ThreeVector initialShowerPosition = fastTrack.GetPrimaryTrack()->GetPosition();
456 initialShowerPosition.eta()<-
m_configuration.m_absHighEta ) )
return true;
462 initialShowerPosition.eta()>-
m_configuration.m_absCrackEta2 ) ) )
return true;
466 initialShowerPosition.eta()>-
m_configuration.m_absLowEta ) )
return true;
This is the interface for the fast simulation dedicated sensitive detector.
virtual void ProcessSpot(const EnergySpot &spot, double weight)=0
ProcessHitsMethod.
virtual double getContainmentZ(const G4FastTrack &, int)=0
virtual std::vector< EnergySpot > getShower(const G4FastTrack &, int) const =0
virtual double getContainmentR(const G4FastTrack &, int)=0
ILArG4ShowerLibSvc * showerLibSvc()
void KillParticle(const G4FastTrack &, G4FastStep &)
Method to kill a particle and deposit its energy using exponential decay function.
ILArG4ShowerLibSvc * m_showerLibSvc
Pointer to the shower library service.
IFastSimDedicatedSD * fastShowerSD()
virtual G4bool ForcedAccept(const G4FastTrack &)
If it returns true, the particle will be parameterized without further checks.
std::shared_ptr< HepMC3::WriterAscii > m_starting_points_file
void UseShowerLib(const G4FastTrack &, G4FastStep &)
Function for the application of shower library.
LArFastShower(const std::string &name, G4Region *region, const FastShowerConfigStruct &config, IFastSimDedicatedSD *fastSimDedicatedSD)
Constructor.
virtual G4bool ForcedDeny(const G4FastTrack &)
If it returns true, the particle will be returned to G4 without further checks.
bool generateFSStartingPoint(std::unique_ptr< const HepMC::GenEvent > &ge) const
bool flagToShowerLib(const G4ParticleDefinition &particleType) const
get switch for frozen showers
double minEneToShowerLib(const G4ParticleDefinition &particleType) const
get upper energy limit for frozen showers
double maxEneToShowerLib(const G4ParticleDefinition &particleType) const
get lower energy limit for frozen showers
std::map< int, bool > m_applicableMap
virtual G4bool ModelTrigger(const G4FastTrack &) override
Determines the applicability of the fast sim model to this particular track.
std::unique_ptr< const HepMC::GenEvent > GetGenEvent(const G4FastTrack &fastTrack)
bool m_generate_starting_points
G4bool IsApplicable(const G4ParticleDefinition &) override
Determines the applicability of the fast sim model to this particle type Called once for each track p...
const FastShowerConfigStruct m_configuration
void DoIt(const G4FastTrack &, G4FastStep &) override
Assigns the track to the appropriate method for application of the fast simulation.
virtual G4bool CheckContainment(const G4FastTrack &fastTrack)
Function to check the containment of a shower within a regular detector region.
std::map< std::string, int > m_detmap
IFastSimDedicatedSD * m_fastSimDedicatedSD
Shower library sensitive detector for this shower.
HepMC3::FourVector FourVector
GenParticlePtr newGenParticlePtr(const HepMC3::FourVector &mom=HepMC3::FourVector::ZERO_VECTOR(), int pid=0, int status=0)
HepMC3::GenParticlePtr GenParticlePtr
GenVertexPtr newGenVertexPtr(const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
HepMC3::GenVertexPtr GenVertexPtr