22 #include <unordered_map>
25 #include <G4RunManager.hh>
27 #include <G4StepPoint.hh>
29 #include <G4UnitsTable.hh>
30 #include <G4VPhysicalVolume.hh>
32 class G4PrimaryParticle;
34 #if BOOST_VERSION >= 107800
35 #include <boost/describe.hpp>
37 BOOST_DESCRIBE_ENUM(G4StepStatus, fWorldBoundary, fGeomBoundary,
38 fAtRestDoItProc, fAlongStepDoItProc, fPostStepDoItProc,
39 fUserDefinedLimit, fExclusivelyForcedProc, fUndefined);
41 BOOST_DESCRIBE_ENUM(G4ProcessType, fNotDefined, fTransportation,
42 fElectromagnetic, fOptical, fHadronic, fPhotolepton_hadron,
43 fDecay, fGeneral, fParameterisation, fUserDefined,
44 fParallel, fPhonon, fUCN);
46 BOOST_DESCRIBE_ENUM(G4TrackStatus, fAlive, fStopButAlive, fStopAndKill,
47 fKillTrackAndSecondaries, fSuspend, fPostponeToNextEvent);
53 const G4StepPoint* postStepPoint,
60 G4ThreeVector preStepPosition = convertLength * preStepPoint->GetPosition();
61 G4double preStepTime = convertTime * preStepPoint->GetGlobalTime();
62 G4ThreeVector postStepPosition = convertLength * postStepPoint->GetPosition();
63 G4double postStepTime = convertTime * postStepPoint->GetGlobalTime();
65 G4ThreeVector preStepMomentum = convertEnergy * preStepPoint->GetMomentum();
66 G4double preStepEnergy = convertEnergy * preStepPoint->GetTotalEnergy();
67 G4ThreeVector postStepMomentum = convertEnergy * postStepPoint->GetMomentum();
68 G4double postStepEnergy = convertEnergy * postStepPoint->GetTotalEnergy();
88 return ActsFatras::Hit(geoId, particleId, particlePosition, beforeMomentum,
89 afterMomentum, index);
102 G4Track* track = step->GetTrack();
103 G4PrimaryParticle* primaryParticle =
104 track->GetDynamicParticle()->GetPrimaryParticle();
107 G4double absCharge = std::abs(track->GetParticleDefinition()->GetPDGCharge());
108 if (not
m_cfg.charged and absCharge > 0.) {
113 if (not
m_cfg.neutral and absCharge == 0.) {
118 if (not
m_cfg.primary and primaryParticle !=
nullptr) {
123 if (not
m_cfg.secondary and primaryParticle ==
nullptr) {
128 std::string_view volumeName = track->GetVolume()->GetName();
131 std::string_view::npos) {
137 std::string_view::npos);
140 std::strtoul(volumeName.data(), &
end, 10));
143 if (eventStore().trackIdMapping.find(track->GetTrackID()) ==
144 eventStore().trackIdMapping.end()) {
148 const auto particleId = eventStore().trackIdMapping.at(track->GetTrackID());
150 ACTS_VERBOSE(
"Step of " << particleId <<
" in sensitive volume " << geoId);
153 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
154 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
157 if (eventStore().particleHitCount.find(particleId) ==
158 eventStore().particleHitCount.end()) {
159 eventStore().particleHitCount[particleId] = 0;
163 const bool preOnBoundary = preStepPoint->GetStepStatus() == fGeomBoundary;
164 const bool postOnBoundary = postStepPoint->GetStepStatus() == fGeomBoundary or
165 postStepPoint->GetStepStatus() == fWorldBoundary;
166 const bool particleStopped = (postStepPoint->GetKineticEnergy() == 0.0);
167 const bool particleDecayed =
168 (postStepPoint->GetProcessDefinedStep()->GetProcessType() == fDecay);
171 #if BOOST_VERSION >= 107800
172 return boost::describe::enum_to_string(
s,
"unmatched");
178 <<
print(preStepPoint->GetStepStatus())
179 <<
", post=" <<
print(postStepPoint->GetStepStatus())
180 <<
", post E_kin=" << std::boolalpha
181 << postStepPoint->GetKineticEnergy() <<
", process_type="
183 postStepPoint->GetProcessDefinedStep()->GetProcessType())
185 << track->GetParticleDefinition()->GetParticleName()
187 << postStepPoint->GetProcessDefinedStep()->GetProcessName()
188 <<
", track status=" <<
print(track->GetTrackStatus()));
192 if (preOnBoundary and postOnBoundary) {
194 ++eventStore().particleHitCount[particleId];
195 eventStore().hits.push_back(
196 hitFromStep(preStepPoint, postStepPoint, particleId, geoId,
197 eventStore().particleHitCount.at(particleId) - 1));
199 eventStore().numberGeantSteps += 1ul;
200 eventStore().maxStepsForHit = std::max(eventStore().maxStepsForHit, 1ul);
206 if (postOnBoundary or particleStopped or particleDecayed) {
208 auto&
buffer = eventStore().hitBuffer;
210 hitFromStep(preStepPoint, postStepPoint, particleId, geoId, -1));
213 0.5 * (
buffer.front().fourPosition() +
buffer.back().fourPosition());
215 ++eventStore().particleHitCount[particleId];
216 eventStore().hits.emplace_back(
217 geoId, particleId,
pos4,
buffer.front().momentum4Before(),
218 buffer.back().momentum4After(),
219 eventStore().particleHitCount.at(particleId) - 1);
222 [&](
const auto&
h) {
return h.geometryId() == geoId; }));
224 return h.particleId() == particleId;
227 eventStore().numberGeantSteps +=
buffer.size();
228 eventStore().maxStepsForHit =
229 std::max(eventStore().maxStepsForHit,
buffer.size());
237 if (not postOnBoundary) {
239 eventStore().hitBuffer.push_back(
240 hitFromStep(preStepPoint, postStepPoint, particleId, geoId, -1));
244 assert(
false &&
"should never reach this");