ATLAS Offline Software
ForwardTransportModel.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 // Athena includes
8 #include "ForwardTracker/Point.h"
9 #include "GaudiKernel/ISvcLocator.h"
10 #include "GaudiKernel/Bootstrap.h"
12 
13 #include "G4PrimaryParticle.hh"
14 #include "G4Proton.hh"
15 #include "G4Neutron.hh"
16 #include "G4Gamma.hh"
17 #include "G4Lambda.hh"
18 #include "G4Geantino.hh"
19 #include "G4ChargedGeantino.hh"
20 #include "G4ParticleTable.hh"
21 
22 #include "AtlasHepMC/GenEvent.h"
25 #include "ISF_Event/TruthBinding.h"
26 #include "ISF_Event/ISFParticle.h"
27 
28 ForwardTransportModel::ForwardTransportModel(const std::string& name, const int verboseLevel, const std::string& FwdTrSvcName)
29  : G4VFastSimulationModel(name)
30  , m_verboseLevel(verboseLevel)
31  , m_FwdTrSvcName(FwdTrSvcName)
32 {
33  ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap
34  if (svcLocator->service(FwdTrSvcName,m_fwdSvc).isFailure()) {
35  G4ExceptionDescription description;
36  description << "ForwardTransportModel::ForwardTransportModel Attempt to access ForwardTransportSvc failed.";
37  G4Exception("ForwardTransportModel", "ForwardTransportModel01", FatalException, description);
38  abort(); // to keep Coverity happy
39  }
40 
42 
43  if (m_verboseLevel>5) {
44  G4cout << " transportFlag " << m_fwdSvc->getTransportFlag() << G4endl;
45  G4cout << " etaCut " << m_fwdSvc->getEtaCut() << G4endl;
46  G4cout << " xiCut " << m_fwdSvc->getXiCut() << G4endl;
47  }
48  return;
49 }
50 
51 
53 {
54  const G4Track *track = fastTrack.GetPrimaryTrack();
55  const G4DynamicParticle *dp = track->GetDynamicParticle();
56  if (dp) {
57  const G4PrimaryParticle *pp = dp->GetPrimaryParticle();
58  if (pp) {
59  // Extract the PrimaryParticleInformation
60  return dynamic_cast<PrimaryParticleInformation*>
61  ( pp->GetUserInformation() );
62  }
63  }
64  return nullptr;
65 }
66 
67 
68 void ForwardTransportModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) {
69  // Depending on particle type and kinematics one can decide to kill the track,
70  // modify it or change it into something else (e.g. a parameterised shower).
71  if (m_verboseLevel>4) {
72  G4cout <<"ForwardTransportModel::DoIt" << G4endl;
73  }
74 
75  const int pdgcode = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGEncoding();
76  const G4ThreeVector& initialMomentum = fastTrack.GetPrimaryTrack()->GetMomentum();
77  if (!m_fwdSvc->selectedParticle(initialMomentum, pdgcode)) { // FIXME Move method to this class?
78  KillPrimaryTrack(fastTrack, fastStep);
79  return;
80  }
81 
82  const double charge = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGCharge();
83  const G4ThreeVector& initialPosition = fastTrack.GetPrimaryTrack()->GetPosition();
84  const double time = fastTrack.GetPrimaryTrack()->GetGlobalTime();
85  const double energy = fastTrack.GetPrimaryTrack()->GetTotalEnergy();
86 
87  if (m_verboseLevel>5) {
88  G4cout <<" pdgCode: " << pdgcode << " energy[GeV]: " << energy/CLHEP::GeV << " charge: " << charge << G4endl;
89  }
90  ForwardTracker::Particle fParticle = ForwardTracker::Particle(initialPosition.x()/CLHEP::m,
91  initialPosition.y()/CLHEP::m,
92  initialPosition.z()/CLHEP::m,
93  initialMomentum.x()/CLHEP::GeV,
94  initialMomentum.y()/CLHEP::GeV,
95  initialMomentum.z()/CLHEP::GeV,
96  std::abs(charge)>0);
97  if (m_verboseLevel>5) {
98  G4cout << fParticle << G4endl;
99  }
100 
101  bool isTransported = m_fwdTrack.TrackParticle(fParticle);
102  if (!isTransported) {
103  KillPrimaryTrack(fastTrack, fastStep);
104  return;
105  }
106 
107  if (m_verboseLevel>5) {
108  G4cout << m_fwdTrack.fPar() << G4endl;
109  }
110 
112  G4ThreeVector postTransportPosition(fPos.x()*CLHEP::m, fPos.y()*CLHEP::m, fPos.z()*CLHEP::m);
113 
115  G4ThreeVector postTransportMomentum(fMom.x()*CLHEP::GeV, fMom.y()*CLHEP::GeV, fMom.z()*CLHEP::GeV);
116 
119  HepMC::GenEvent* gEvent = (part) ? const_cast<HepMC::GenEvent*>(part->parent_event()) : nullptr;
120  if (!gEvent) {
121  G4ExceptionDescription description;
122  description << "ForwardTransportModel::DoIt Cannot get HepMC::GenEvent pointer";
123  G4Exception("ForwardTransportModel", "ForwardTransportModel03", FatalException, description);
124  abort(); // to keep Coverity happy
125  }
126  // Update HepMC::GenEvent
128  HepMC::FourVector(
129  postTransportPosition.x(),
130  postTransportPosition.y(),
131  postTransportPosition.z(),
132  time)); // TODO Update this value?
133  gEvent->add_vertex(gVertex);
134  gVertex->add_particle_in(part);
136  HepMC::FourVector(
137  postTransportMomentum.x(),
138  postTransportMomentum.y(),
139  postTransportMomentum.z(),
140  energy),
141  pdgcode,
142  part->status() + HepMC::SIM_STATUS_INCREMENT);
143  gVertex->add_particle_out(gParticle);
145 
146  // Create secondary on the Geant4 side
147  fastStep.SetNumberOfSecondaryTracks(1);
148 
149  const G4ParticleDefinition *aParticleDefinition{};
151  if (pdgcode == MC::GEANTINOPLUS) {
152  aParticleDefinition = G4ChargedGeantino::Definition();
153  }
154  if (pdgcode == MC::GEANTINO0) {
155  aParticleDefinition = G4Geantino::GeantinoDefinition();
156  }
157  if (!aParticleDefinition) {
159  G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
160  if (ptable) {
161  aParticleDefinition = ptable->FindParticle(pdgcode);
162  }
163  }
164  G4DynamicParticle dp2(aParticleDefinition, energy, postTransportMomentum);
165 
166  // Create UserInformation
167  const ISF::ISFParticle* initialISP = ppi->GetISFParticle();
168  std::unique_ptr<ISF::ISFParticle> postTransportISP{};
169  if (initialISP) {
170  // Create postTransportISP if required.
171  const auto pBarcode = HepMC::barcode(gParticle);
172  const auto particleID = HepMC::uniqueID(gParticle);
173  const int status = gParticle->status();
174  auto tBinding = std::make_unique<ISF::TruthBinding>(gParticle);
175  auto hmpl = std::make_unique<HepMcParticleLink>(pBarcode, gEvent->event_number(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_BARCODE); // FIXME barcode-based
176  const Amg::Vector3D pos(postTransportPosition.x(), postTransportPosition.y(), postTransportPosition.z());
177  const Amg::Vector3D mom(postTransportMomentum.x(), postTransportMomentum.y(), postTransportMomentum.z());
178  postTransportISP = std::make_unique<ISF::ISFParticle>(pos,
179  mom,
180  initialISP->mass(),
181  initialISP->charge(),
182  initialISP->pdgCode(),
183  status,
184  time, // TODO Update??
185  *initialISP,
186  particleID,
187  pBarcode,
188  tBinding.release(),
189  hmpl.release());
190  }
191  std::unique_ptr<PrimaryParticleInformation> ppi2 = std::make_unique<PrimaryParticleInformation>(gParticle,postTransportISP.release());
192  std::unique_ptr<G4PrimaryParticle> pp2 = std::make_unique<G4PrimaryParticle>(
193  aParticleDefinition,
194  postTransportMomentum.x(),
195  postTransportMomentum.y(),
196  postTransportMomentum.z());
197  pp2->SetUserInformation(ppi2.release());
198  dp2.SetPrimaryParticle(pp2.release());
199 
200  G4Track* postTransportTrack =
201  fastStep.CreateSecondaryTrack(
202  dp2,
203  postTransportPosition,
204  time,
205  false); // position in global coordinates
206  if (!postTransportTrack) {
207  G4ExceptionDescription description;
208  description << "ForwardTransportModel::DoIt Failed to create secondary G4Track.";
209  G4Exception("ForwardTransportModel", "ForwardTransportModel04", FatalException, description);
210  abort(); // to keep Coverity happy
211  }
212  fastStep.ProposePrimaryTrackFinalPosition(postTransportPosition, false); // position in global coordinates
213  fastStep.SetPrimaryTrackFinalMomentum(postTransportMomentum, false);
214  fastStep.KillPrimaryTrack();
215 }
216 
217 
218 void ForwardTransportModel::KillPrimaryTrack(const G4FastTrack& fastTrack, G4FastStep& fastStep) {
221  HepMC::GenEvent* gEvent = (part) ? const_cast<HepMC::GenEvent*>(part->parent_event()) : nullptr;
222  if (!gEvent) {
223  G4ExceptionDescription description;
224  description << "ForwardTransportModel::KillPrimaryTrack Cannot get HepMC::GenEvent pointer";
225  G4Exception("ForwardTransportModel", "ForwardTransportModel02", FatalException, description);
226  abort(); // to keep Coverity happy
227  }
228  const G4ThreeVector& initialPosition = fastTrack.GetPrimaryTrack()->GetPosition();
229  // Add dummy end vertex in Truth
231  HepMC::FourVector(
232  initialPosition.x(),
233  initialPosition.y(),
234  initialPosition.z(),
235  fastTrack.GetPrimaryTrack()->GetGlobalTime()));
236  // Flag the fact that Forward Transport has occurred using the vertex status
237 #ifdef HEPMC3
239 #else
241 #endif
242  gEvent->add_vertex(gVertex);
243  gVertex->add_particle_in(part);
244  // Kill track and deposit all energy in the current volume
245  fastStep.KillPrimaryTrack();
246  fastStep.ProposePrimaryTrackPathLength(0.0);
247  fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetTotalEnergy());
248 }
HepMC::GenVertexPtr
HepMC::GenVertex * GenVertexPtr
Definition: GenVertex.h:59
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
HepMC::suggest_barcode
bool suggest_barcode(T &p, int i)
Definition: GenEvent.h:548
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:840
GenEvent.h
ForwardTransportModel::getPrimaryParticleInformation
PrimaryParticleInformation * getPrimaryParticleInformation(const G4FastTrack &fastTrack) const
Definition: ForwardTransportModel.cxx:52
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
IForwardTransportSvc::getTransportFlag
virtual bool getTransportFlag() const =0
ForwardTracker::Point::y
double y() const
Definition: ForwardTracker/ForwardTracker/Point.h:23
HepMC::SIM_STATUS_INCREMENT
constexpr int SIM_STATUS_INCREMENT
Constant defining the barcode threshold for regenerated particles, i.e. particles surviving an intera...
Definition: MagicNumbers.h:35
HepMC::GenParticlePtr
GenParticle * GenParticlePtr
Definition: GenParticle.h:37
ISF::ISFParticle
Definition: ISFParticle.h:42
ISF::ISFParticle::pdgCode
int pdgCode() const
PDG value.
ForwardTrack::fPar
const ForwardTracker::Particle & fPar()
Definition: ForwardTrack.h:25
ForwardTransportModel::DoIt
void DoIt(const G4FastTrack &, G4FastStep &) override final
Definition: ForwardTransportModel.cxx:68
ForwardTracker::Point
Definition: ForwardTracker/ForwardTracker/Point.h:15
xAOD::Particle
Particle_v1 Particle
Define the latest version of the particle class.
Definition: Event/xAOD/xAODParticleEvent/xAODParticleEvent/Particle.h:17
TruthBinding.h
ISFParticle.h
ForwardTracker::Point::z
double z() const
Definition: ForwardTracker/ForwardTracker/Point.h:24
ParticleGun_EoverP_Config.mom
mom
Definition: ParticleGun_EoverP_Config.py:63
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
HepMC::newGenVertexPtr
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
Definition: GenVertex.h:64
ForwardTransportModel::KillPrimaryTrack
void KillPrimaryTrack(const G4FastTrack &, G4FastStep &)
Definition: ForwardTransportModel.cxx:218
PrimaryParticleInformation::GetISFParticle
const ISF::ISFParticle * GetISFParticle() const
return a pointer to the ISFParticle used to create the G4PrimaryParticle
Definition: PrimaryParticleInformation.h:66
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
HepMC::uniqueID
int uniqueID(const T &p)
Definition: MagicNumbers.h:113
ForwardTransportModel::m_verboseLevel
const int m_verboseLevel
Definition: ForwardTransportModel.h:32
ForwardTrack::TrackParticle
bool TrackParticle(ForwardTracker::Particle)
Definition: ForwardTrack.cxx:23
IForwardTransportSvc::getEtaCut
virtual double getEtaCut() const =0
HepMC::FORWARDTRANSPORTMODELSTATUS
constexpr int FORWARDTRANSPORTMODELSTATUS
Definition: MagicNumbers.h:46
ForwardTransportModel::m_fwdTrack
ForwardTrack m_fwdTrack
Definition: ForwardTransportModel.h:30
ForwardTrack::initialize
void initialize(const ForwardTracker::ConfigData &)
Definition: ForwardTrack.cxx:14
ForwardTransportModel::m_fwdSvc
IForwardTransportSvc * m_fwdSvc
Definition: ForwardTransportModel.h:29
HepMC::SIM_REGENERATION_INCREMENT
constexpr int SIM_REGENERATION_INCREMENT
Constant defining the barcode threshold for regenerated particles, i.e. particles surviving an intera...
Definition: MagicNumbers.h:32
ForwardTrack::fMom
const ForwardTracker::Point & fMom()
Definition: ForwardTrack.h:24
HepMC::SIM_STATUS_THRESHOLD
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
Definition: MagicNumbers.h:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
charge
double charge(const T &p)
Definition: AtlasPID.h:494
ForwardTracker::Point::x
double x() const
Definition: ForwardTracker/ForwardTracker/Point.h:22
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ISF::ISFParticle::charge
double charge() const
charge of the particle
ForwardTransportModel::ForwardTransportModel
ForwardTransportModel(const std::string &name, const int verboseLevel, const std::string &FwdTrSvcName)
Definition: ForwardTransportModel.cxx:28
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
ForwardTracker::Particle
Definition: ForwardDetectors/ForwardTracker/ForwardTracker/Particle.h:17
ForwardTransportModel.h
PrimaryParticleInformation::GetHepMCParticle
HepMC::ConstGenParticlePtr GetHepMCParticle() const
return a pointer to the GenParticle used to create the G4PrimaryParticle
Definition: PrimaryParticleInformation.h:47
PrimaryParticleInformation
This class is attached to G4PrimaryParticle objects as UserInformation. The member variable m_thePart...
Definition: PrimaryParticleInformation.h:39
HepMC::newGenParticlePtr
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
Definition: GenParticle.h:39
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
IForwardTransportSvc::getXiCut
virtual double getXiCut() const =0
PrimaryParticleInformation.h
ForwardTrack::fPos
const ForwardTracker::Point & fPos()
Definition: ForwardTrack.h:23
merge.status
status
Definition: merge.py:17
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
IForwardTransportSvc::getConfigData
virtual ForwardTracker::ConfigData getConfigData() const =0
Point.h
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
HepMCHelpers.h
description
std::string description
glabal timer - how long have I taken so far?
Definition: hcg.cxx:88
ISF::ISFParticle::mass
double mass() const
mass of the particle
IForwardTransportSvc::selectedParticle
virtual bool selectedParticle(G4ThreeVector mom, int pid)=0