BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSSDSamplerLink.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSDebug.hh"
19#include "BDSHitSamplerLink.hh"
20#include "BDSLinkRegistry.hh"
21#include "BDSParticleCoordsFull.hh"
22#include "BDSPhysicsUtilities.hh"
23#include "BDSSDSamplerLink.hh"
24
25#include "G4DynamicParticle.hh"
26#include "G4ParticleDefinition.hh"
27#include "G4SDManager.hh"
28#include "G4Step.hh"
29#include "G4StepPoint.hh"
30#include "G4ThreeVector.hh"
31#include "G4TouchableHistory.hh"
32#include "G4Track.hh"
33#include "G4Types.hh"
34
35#include "CLHEP/Geometry/Point3D.h"
36#include "CLHEP/Geometry/Vector3D.h"
37
38#include <vector>
39
41 BDSSensitiveDetector("samplerlink/" + name),
42 samplerLinkCollection(nullptr),
43 itsCollectionName(name),
44 itsHCID(-1),
45 registry(nullptr),
46 minimumEK(0),
47 protonsAndIonsOnly(true)
48{
49 collectionName.insert(name);
50}
51
52BDSSDSamplerLink::~BDSSDSamplerLink()
53{;}
54
55void BDSSDSamplerLink::Initialize(G4HCofThisEvent* HCE)
56{
57 // Create SamplerLink hits collection
59
60 // Record id for use in EventAction to save time - slow string lookup by collection name
61 if (itsHCID < 0)
62 {itsHCID = G4SDManager::GetSDMpointer()->GetCollectionID(samplerLinkCollection);}
63 HCE->AddHitsCollection(itsHCID,samplerLinkCollection);
64}
65
66G4bool BDSSDSamplerLink::ProcessHits(G4Step* aStep, G4TouchableHistory* /*readOutTH*/)
67{
68 // Do not store hit if the particle pre step point is not on the boundary
69 G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
70 if (postStepPoint->GetStepStatus() != fGeomBoundary)
71 {return false;} // this step was not stored
72
73 G4Track* track = aStep->GetTrack();
74 const G4DynamicParticle* dp = track->GetDynamicParticle();
75 G4double charge = dp->GetCharge(); // dynamic effective charge
76 auto pd = dp->GetParticleDefinition();
77
78 // check against various filters
79 G4double ek = track->GetKineticEnergy();
80 if (ek < minimumEK)
81 {return false;}
82
83 G4int PDGtype = pd->GetPDGEncoding();
85 {
86 if (!BDS::IsIon(dp) && PDGtype != 2212)
87 {return false;}
88 }
89
90 G4int trackID = track->GetTrackID(); // unique ID of track
91 G4int parentID = track->GetParentID(); // unique ID of track's mother
92 G4double T = track->GetGlobalTime(); // time since beginning of event
93 G4double energy = track->GetTotalEnergy(); // total track energy
94
95 const G4ThreeVector& pos = track->GetPosition(); // current particle position (global)
96 const G4ThreeVector& mom = track->GetMomentumDirection(); // current particle direction (global) (unit)
97 G4double weight = track->GetWeight(); // weighting
98 G4int nElectrons = dp->GetTotalOccupancy();
99 G4double mass = dp->GetMass();
100 G4double momentum = dp->GetTotalMomentum();
101
102 G4int z = pd->GetAtomicNumber();
103 G4int a = pd->GetAtomicMass();
104
105 // The copy number from the physical volume is used as our unique sampler ID
106 G4int samplerID = track->GetVolume()->GetCopyNo();
107 //G4cout << "samplerID " << samplerID << G4endl;
108
109 // Initialize variables for the local position and direction
110 G4ThreeVector localPosition;
111 G4ThreeVector localDirection;
112
113 // Get coordinate transform and prepare local coordinates
114 G4Transform3D globalToLocal = G4Transform3D::Identity;
115 G4ThreeVector globalToLocalOffset = G4ThreeVector();
116 G4bool noRotation = true;
117 if (registry)
118 {
119 noRotation = registry->NoRotation(samplerID);
120 globalToLocal = registry->TransformInverse(samplerID);
121 globalToLocalOffset = globalToLocal.getTranslation();
122 }
123 if (noRotation)
124 {
125 localPosition = pos + globalToLocalOffset;
126 localDirection = mom;
127 }
128 else if (globalToLocal != G4Transform3D::Identity)
129 {
130 // The global to local transform is defined in the registry.
131 // Cast 3 vector to 'point' to transform position (required to be explicit for * operator)
132 localPosition = globalToLocal * (HepGeom::Point3D<G4double>)pos;
133 // Now, if the sampler is infinitely thin, the local z should be 0, but it's finite.
134 // Account for this by purposively setting local z to be 0.
135 localPosition.setZ(0.0);
136 // Cast 3 vector to 3 vector to transform vector (required to be explicit for * operator)
137 localDirection = globalToLocal * (HepGeom::Vector3D<G4double>)mom;
138 }
139
140 BDSParticleCoordsFull coords(localPosition.x(),
141 localPosition.y(),
142 localPosition.z(),
143 localDirection.x(),
144 localDirection.y(),
145 localDirection.z(),
146 T,
147 localPosition.z(), // s = z here
148 energy,
149 weight);
150
151 BDSHitSamplerLink* smpHit = new BDSHitSamplerLink(samplerID,
152 coords,
153 momentum,
154 mass,
155 z,
156 a,
157 charge,
158 PDGtype,
159 parentID,
160 trackID,
161 nElectrons);
162
163 samplerLinkCollection->insert(smpHit);
164 return true; // the hit was stored
165}
166
168{
169 BDSHitSamplerLink* lastHit = samplerLinkCollection->GetVector()->back();
170 return dynamic_cast<G4VHit*>(lastHit);
171}
A set of particle coordinates including energy and weight.
Virtual class to define interface for ordered multi-sensitive detector.
G4bool IsIon(const G4ParticleDefinition *particle)
Whether a particle is an ion. A proton is counted NOT as an ion.