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();
73 enum DETECTOR { EMB=100000, EMEC=200000, FCAL1=300000, FCAL2=400000,
74 FCAL3=500000, HECLOC=600000, HEC=700000 };
88 throw std::runtime_error(
"LArFastShower: no pointer to IFastSimDedicatedSD!");
97 SmartIF<ILArG4ShowerLibSvc> smartShowerLibSvc{Gaudi::svcLocator()->service(
m_configuration.m_showerLibSvcName)};
98 if ( smartShowerLibSvc ) {
m_showerLibSvc = smartShowerLibSvc.get(); }
100 throw std::runtime_error(
"LArFastShower: cannot retrieve LArG4ShowerLibSvc");
110 G4cout <<
"LArFastShower::IsApplicable" << G4endl;
140 G4cout <<
"LArFastShower::commonTrigger" << G4endl;
146 G4double particleEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
147 const G4ParticleDefinition&
particleType = *(fastTrack.GetPrimaryTrack()->GetDefinition());
154 G4cout <<
"Particle has energy (" << particleEnergy <<
") for shower lib and shower lib is on! Accept particle!" << G4endl;
159 G4cout <<
"Particle has energy (" << particleEnergy <<
") outside killing, shower lib and parametrisation "
160 <<
"or some features are switched off ... returning it to Geant " << G4endl;
171 G4cout <<
"LArFastShower::ModelTrigger() particle failed CheckContainment()... will not be parameterised: " << G4endl;
177 G4cout <<
"LArFastShower::ModelTrigger() direction: " << fastTrack.GetPrimaryTrackLocalDirection() << G4endl;
178 G4cout <<
"LArFastShower::ModelTrigger() mom dir: " << fastTrack.GetPrimaryTrack()->GetMomentumDirection() << G4endl;
188 G4cout <<
"LArFastShower::Doit()" << G4endl;
192 if (CLHEP::RandFlat::shoot(G4Random::getTheEngine()) <=
m_configuration.m_generated_starting_points_ratio) {
193 std::unique_ptr<const HepMC::GenEvent> ge =
GetGenEvent(fastTrack);
202 G4cout <<
"LArFastShower::Doit() done" << G4endl;
215 G4cout <<
"Low energy particle is being killed: " << fastTrack.GetPrimaryTrack()->GetKineticEnergy() << G4endl;
219 fastStep.KillPrimaryTrack();
220 fastStep.ProposePrimaryTrackPathLength(0.0);
229 G4cout <<
"LArFastShower::UseShowerLib()" << G4endl;
238 const std::vector<EnergySpot> shower =
242 G4cout <<
"Got shower (" << shower.size() <<
") from shower lib" << G4endl;
244 const double weight = (
m_configuration.m_applyRRWeights) ? fastTrack.GetPrimaryTrack()->GetWeight() : 1.0;
246 for (
const auto& a_spot : shower) {
249 G4cout <<
"Make Spot: " << a_spot.GetPosition().x() <<
" "
250 << a_spot.GetPosition().y() <<
" " << a_spot.GetPosition().z()
251 <<
" " << a_spot.GetEnergy() <<
" " << a_spot.GetTime() << G4endl;
256 G4cout <<
"Made Spot" << G4endl;
262 G4cout <<
"LArFastShower::UseShowerLib() Done" << G4endl;
269 catch (
const std::exception & e) {
270 G4cout <<
"FastShower::UseShowerLib ERROR Handling an exception in LArFastShower::" << e.what() << G4endl;
279 G4ThreeVector showerDirection = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
280 G4ThreeVector initialShowerPosition = fastTrack.GetPrimaryTrack()->GetPosition();
281 G4ThreeVector orthoShower = showerDirection.orthogonal();
282 G4ThreeVector crossShower = showerDirection.cross(orthoShower);
285 G4cout <<
"LArFastShower::CheckContainment() orthoShower: " << orthoShower << G4endl;
286 G4cout <<
"LArFastShower::CheckContainment() crossShower: " << crossShower << G4endl;
306 if (Z == 0.0 && R == 0.0) {
313 G4double Zmx = Z / 3;
315 G4int cosPhi[4] = {1,0,-1,0};
316 G4int sinPhi[4] = {0,1,0,-1};
319 G4cout <<
"LArFastShower::CheckContainment() R = " << R << G4endl;
320 G4cout <<
"LArFastShower::CheckContainment() Z = " << Z << G4endl;
323 G4ThreeVector position;
325 G4VSolid* caloSolid = fastTrack.GetEnvelopeSolid();
326 const G4AffineTransform* affineTransformation = fastTrack.GetAffineTransformation();
329 position = initialShowerPosition;
330 affineTransformation->ApplyPointTransform(position);
331 if(caloSolid->Inside(position) == kOutside)
335 position = initialShowerPosition + Z*showerDirection;
336 affineTransformation->ApplyPointTransform(position);
337 if(caloSolid->Inside(position) == kOutside)
341 for(
int i=0; i<4 ;i++)
343 position = initialShowerPosition + Zmx*showerDirection +
344 R*cosPhi[i]*orthoShower + R*sinPhi[i]*crossShower;
345 affineTransformation->ApplyPointTransform(position);
346 if(caloSolid->Inside(position) == kOutside)
351 G4cout <<
"LArFastShower::CheckContainment() Shower is contained " << G4endl;
360 const G4ThreeVector showerPos = fastTrack.GetPrimaryTrack()->GetPosition();
361 const G4ThreeVector showerMom = fastTrack.GetPrimaryTrack()->GetMomentum();
362 const G4double energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
364 G4int pdgcode = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGEncoding();
365 if (pdgcode < 0) pdgcode = -pdgcode;
368 HepMC3::Units::MomentumUnit momentumUnit = HepMC3::Units::MEV;
369 HepMC3::Units::LengthUnit lengthUnit = HepMC3::Units::MM;
371 HepMC::Units::MomentumUnit momentumUnit = HepMC::Units::MEV;
372 HepMC::Units::LengthUnit lengthUnit = HepMC::Units::MM;
375 std::unique_ptr<HepMC::GenEvent> ge = std::make_unique<HepMC::GenEvent>(momentumUnit,lengthUnit);
381 HepMC::FourVector(showerPos.x(), showerPos.y(), showerPos.z(), 0) );
387 HepMC::FourVector(0.,0.,0.,0.),
389 gv->add_particle_in(std::move(gpi));
393 HepMC::FourVector(showerMom.x(), showerMom.y(), showerMom.z(), energy),
395 gv->add_particle_out(std::move(gpo));
404 if ( &
particleType == G4Electron::ElectronDefinition() ||
407 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
409 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
411 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
419 if ( &
particleType == G4Electron::ElectronDefinition() ||
422 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
424 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
426 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
435 if ( &
particleType == G4Electron::ElectronDefinition() ||
438 }
else if ( &
particleType == G4Gamma::GammaDefinition() ) {
440 }
else if ( &
particleType == G4Neutron::NeutronDefinition() ) {
442 }
else if ( &
particleType == G4PionPlus::PionPlusDefinition() ||
461 G4ThreeVector initialShowerPosition = fastTrack.GetPrimaryTrack()->GetPosition();
469 initialShowerPosition.eta()<-
m_configuration.m_absHighEta ) )
return true;
475 initialShowerPosition.eta()>-
m_configuration.m_absCrackEta2 ) ) )
return true;
479 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.
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)
std::shared_ptr< HepMC::IO_GenEvent > m_starting_points_file
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.
HepMC::GenVertex * GenVertexPtr
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
GenParticle * GenParticlePtr