Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4FastStep.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28//---------------------------------------------------------------
29//
30// G4FastStep.cc
31//
32// Description:
33// Encapsulates a G4ParticleChange and insure friendly interface
34// methods to manage the primary/secondaries final state for
35// Fast Simulation Models.
36//
37// History:
38// Oct 97: Verderi && MoraDeFreitas - First Implementation.
39// Apr 98: MoraDeFreitas - G4FastStep becomes the G4ParticleChange
40// for the Fast Simulation Process.
41//
42//---------------------------------------------------------------
43
44#include "G4FastStep.hh"
45
46#include "G4DynamicParticle.hh"
47#include "G4Step.hh"
48#include "G4SystemOfUnits.hh"
49#include "G4Track.hh"
50#include "G4TrackFastVector.hh"
51#include "G4UnitsTable.hh"
52
53void G4FastStep::Initialize(const G4FastTrack& fastTrack)
54{
55 // keeps the fastTrack reference
56 fFastTrack = &fastTrack;
57
58 // currentTrack will be used to Initialize the other data members
59 const G4Track& currentTrack = *(fFastTrack->GetPrimaryTrack());
60
61 // use base class's method at first
63
64 // set Energy/Momentum etc. equal to those of the parent particle
65 const G4DynamicParticle* pParticle = currentTrack.GetDynamicParticle();
66 theEnergyChange = pParticle->GetKineticEnergy();
67 theMomentumChange = pParticle->GetMomentumDirection();
68 thePolarizationChange = pParticle->GetPolarization();
69 theProperTimeChange = pParticle->GetProperTime();
70
71 // set Position/Time etc. equal to those of the parent track
72 thePositionChange = currentTrack.GetPosition();
73 theTimeChange = currentTrack.GetGlobalTime();
74
75 // switch off stepping hit invokation by default:
77
78 // event biasing weigth:
79 theWeightChange = currentTrack.GetWeight();
80}
81
82//----------------------------------------
83// -- Set the StopAndKilled signal
84// -- and put kinetic energy to 0.0. in the
85// -- G4ParticleChange.
86//----------------------------------------
92
93//--------------------
94//
95//--------------------
97 G4bool localCoordinates)
98{
99 // Compute the position coordinate in global
100 // reference system if needed ...
101 G4ThreeVector globalPosition = position;
102 if (localCoordinates)
103 globalPosition = fFastTrack->GetInverseAffineTransformation()->TransformPoint(position);
104 // ...and feed the globalPosition:
105 thePositionChange = globalPosition;
106}
107
109 G4bool localCoordinates)
110{
112}
113
114//--------------------
115//
116//--------------------
118 G4bool localCoordinates)
119{
120 // Compute the momentum in global reference
121 // system if needed ...
122 G4ThreeVector globalMomentum = momentum;
123 if (localCoordinates)
124 globalMomentum = fFastTrack->GetInverseAffineTransformation()->TransformAxis(momentum);
125 // ...and feed the globalMomentum (ensuring unitarity)
126 SetMomentumChange(globalMomentum.unit());
127}
128
130 G4bool localCoordinates)
131{
132 ProposePrimaryTrackFinalMomentumDirection(momentum, localCoordinates);
133}
134
135//--------------------
136//
137//--------------------
139 const G4ThreeVector& direction,
140 G4bool localCoordinates)
141{
142 // Compute global direction if needed...
143 G4ThreeVector globalDirection = direction;
144 if (localCoordinates)
145 globalDirection = fFastTrack->GetInverseAffineTransformation()->TransformAxis(direction);
146 // ...and feed the globalMomentum (ensuring unitarity)
147 SetMomentumChange(globalDirection.unit());
149}
150
152 const G4ThreeVector& direction,
153 G4bool localCoordinates)
154{
155 ProposePrimaryTrackFinalKineticEnergyAndDirection(kineticEnergy, direction, localCoordinates);
156}
157
158//--------------------
159//
160//--------------------
162 G4bool localCoordinates)
163{
164 // Compute polarization in global system if needed:
165 G4ThreeVector globalPolarization(polarization);
166 if (localCoordinates)
167 globalPolarization =
168 fFastTrack->GetInverseAffineTransformation()->TransformAxis(globalPolarization);
169 // Feed the particle globalPolarization:
170 thePolarizationChange = globalPolarization;
171}
172
174 G4bool localCoordinates)
175{
176 ProposePrimaryTrackFinalPolarization(polarization, localCoordinates);
177}
178
179//--------------------
180//
181//--------------------
184 G4double time, G4bool localCoordinates)
185{
186 G4DynamicParticle dummyDynamics(dynamics);
187
188 // ------------------------------------------
189 // Add the polarization to the dummyDynamics:
190 // ------------------------------------------
191 dummyDynamics.SetPolarization(polarization.x(), polarization.y(), polarization.z());
192
193 return CreateSecondaryTrack(dummyDynamics, position, time, localCoordinates);
194}
195
196//--------------------
197//
198//--------------------
200 G4double time, G4bool localCoordinates)
201{
202 // ----------------------------------------
203 // Quantities in global coordinates system.
204 //
205 // The allocated globalDynamics is deleted
206 // by the destructor of the G4Track.
207 // ----------------------------------------
208 auto globalDynamics = new G4DynamicParticle(dynamics);
209 G4ThreeVector globalPosition(position);
210
211 // -----------------------------------
212 // Convert to global system if needed:
213 // -----------------------------------
214 if (localCoordinates) {
215 // -- Momentum Direction:
216 globalDynamics->SetMomentumDirection(
218 globalDynamics->GetMomentumDirection()));
219 // -- Polarization:
220 G4ThreeVector globalPolarization;
221 globalPolarization = fFastTrack->GetInverseAffineTransformation()->TransformAxis(
222 globalDynamics->GetPolarization());
223 globalDynamics->SetPolarization(globalPolarization.x(), globalPolarization.y(),
224 globalPolarization.z());
225
226 // -- Position:
227 globalPosition = fFastTrack->GetInverseAffineTransformation()->TransformPoint(globalPosition);
228 }
229
230 //-------------------------------------
231 // Create the G4Track of the secondary:
232 //-------------------------------------
233 auto secondary = new G4Track(globalDynamics, time, globalPosition);
234
235 //-------------------------------
236 // and feed the changes:
237 //-------------------------------
238 AddSecondary(secondary);
239
240 //--------------------------------------
241 // returns the pointer on the secondary:
242 //--------------------------------------
243 return secondary;
244}
245
246// G4FastStep should never be Initialized in this way
247// but we must define it to avoid warnings.
249{
250 G4ExceptionDescription tellWhatIsWrong;
251 tellWhatIsWrong << "G4FastStep can be initialised only through G4FastTrack." << G4endl;
252 G4Exception("G4FastStep::Initialize(const G4Track&)", "FastSim005", FatalException,
253 tellWhatIsWrong);
254}
255
256//----------------------------------------------------------------
257// methods for updating G4Step
258//
259
261{
262 // A physics process always calculates the final state of the particle
263
264 // Take note that the return type of GetMomentumChange is a
265 // pointer to G4ParticleMometum. Also it is a normalized
266 // momentum vector.
267
268 // G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
269 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
270 G4Track* aTrack = pStep->GetTrack();
271 // G4double mass = aTrack->GetDynamicParticle()->GetMass();
272
273 // update kinetic energy and momentum direction
274 pPostStepPoint->SetMomentumDirection(theMomentumChange);
275 pPostStepPoint->SetKineticEnergy(theEnergyChange);
276
277 // update polarization
278 pPostStepPoint->SetPolarization(thePolarizationChange);
279
280 // update position and time
281 pPostStepPoint->SetPosition(thePositionChange);
282 pPostStepPoint->SetGlobalTime(theTimeChange);
283 pPostStepPoint->AddLocalTime(theTimeChange - aTrack->GetGlobalTime());
284 pPostStepPoint->SetProperTime(theProperTimeChange);
285
286 // update weight
287 pPostStepPoint->SetWeight(theWeightChange);
288
289 if (debugFlag) CheckIt(*aTrack);
290
291 // Update the G4Step specific attributes
292 return UpdateStepInfo(pStep);
293}
294
296{
297 // A physics process always calculates the final state of the particle
298
299 // G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
300 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
301 G4Track* aTrack = pStep->GetTrack();
302 // G4double mass = aTrack->GetDynamicParticle()->GetMass();
303
304 // update kinetic energy and momentum direction
305 pPostStepPoint->SetMomentumDirection(theMomentumChange);
306 pPostStepPoint->SetKineticEnergy(theEnergyChange);
307
308 // update polarization
309 pPostStepPoint->SetPolarization(thePolarizationChange);
310
311 // update position and time
312 pPostStepPoint->SetPosition(thePositionChange);
313 pPostStepPoint->SetGlobalTime(theTimeChange);
314 pPostStepPoint->AddLocalTime(theTimeChange - aTrack->GetGlobalTime());
315 pPostStepPoint->SetProperTime(theProperTimeChange);
316
317 // update weight
318 pPostStepPoint->SetWeight(theWeightChange);
319
320 if (debugFlag) CheckIt(*aTrack);
321
322 // Update the G4Step specific attributes
323 return UpdateStepInfo(pStep);
324}
325
326//----------------------------------------------------------------
327// methods for printing messages
328//
329
331{
332 // use base-class DumpInfo
334
335 G4cout << " Position - x (mm) : " << G4BestUnit(thePositionChange.x(), "Length")
336 << G4endl;
337 G4cout << " Position - y (mm) : " << G4BestUnit(thePositionChange.y(), "Length")
338 << G4endl;
339 G4cout << " Position - z (mm) : " << G4BestUnit(thePositionChange.z(), "Length")
340 << G4endl;
341 G4cout << " Time (ns) : " << G4BestUnit(theTimeChange, "Time") << G4endl;
342 G4cout << " Proper Time (ns) : " << G4BestUnit(theProperTimeChange, "Time") << G4endl;
343 G4long olprc = G4cout.precision(3);
344 G4cout << " Momentum Direct - x : " << std::setw(20) << theMomentumChange.x() << G4endl;
345 G4cout << " Momentum Direct - y : " << std::setw(20) << theMomentumChange.y() << G4endl;
346 G4cout << " Momentum Direct - z : " << std::setw(20) << theMomentumChange.z() << G4endl;
347 G4cout.precision(olprc);
348 G4cout << " Kinetic Energy (MeV): " << G4BestUnit(theEnergyChange, "Energy") << G4endl;
349 G4cout.precision(3);
350 G4cout << " Polarization - x : " << std::setw(20) << thePolarizationChange.x()
351 << G4endl;
352 G4cout << " Polarization - y : " << std::setw(20) << thePolarizationChange.y()
353 << G4endl;
354 G4cout << " Polarization - z : " << std::setw(20) << thePolarizationChange.z()
355 << G4endl;
356 G4cout.precision(olprc);
357}
358
360{
361 //
362 // In the G4FastStep::CheckIt
363 // We only check a bit
364 //
365 // If the user violates the energy,
366 // We don't care, we agree.
367 //
368 // But for theMomentumDirectionChange,
369 // We do pay attention.
370 // And if too large is its range,
371 // We issue an Exception.
372 //
373 //
374 // It means, the G4FastStep::CheckIt issues an exception only for the
375 // theMomentumDirectionChange which should be an unit vector
376 // and it corrects it because it could cause problems for the ulterior
377 // tracking.For the rest, only warning are issued.
378
379 G4bool itsOK = true;
380 G4bool exitWithError = false;
381 G4double accuracy;
382
383 // Energy should not be larger than the initial value
384 accuracy = (theEnergyChange - aTrack.GetKineticEnergy()) / MeV;
385 if (accuracy > GetAccuracyForWarning()) {
387 ed << "The energy becomes larger than the initial value, difference = " << accuracy << " MeV"
388 << G4endl;
389 G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)", "FastSim006", JustWarning, ed);
390 itsOK = false;
391 if (accuracy > GetAccuracyForException()) {
392 exitWithError = true;
393 }
394 }
395
396 G4bool itsOKforMomentum = true;
397 if (theEnergyChange > 0.) {
398 accuracy = std::abs(theMomentumChange.mag2() - 1.0);
399 if (accuracy > GetAccuracyForWarning()) {
401 ed << "The Momentum Change is not a unit vector, difference = " << accuracy << G4endl;
402 G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)", "FastSim007", JustWarning, ed);
403 itsOK = itsOKforMomentum = false;
404 if (accuracy > GetAccuracyForException()) {
405 exitWithError = true;
406 }
407 }
408 }
409
410 accuracy = (aTrack.GetGlobalTime() - theTimeChange) / ns;
411 if (accuracy > GetAccuracyForWarning()) {
413 ed << "The global time is getting backward, difference = " << accuracy << " ns" << G4endl;
414 G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)", "FastSim008", JustWarning, ed);
415 itsOK = false;
416 }
417
418 accuracy = (aTrack.GetProperTime() - theProperTimeChange) / ns;
419 if (accuracy > GetAccuracyForWarning()) {
421 ed << "The proper time is getting backward, difference = " << accuracy << " ns" << G4endl;
422 G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)", "FastSim009", JustWarning, ed);
423 itsOK = false;
424 }
425
426 if (!itsOK) {
427 G4cout << "ERROR - G4FastStep::CheckIt() " << G4endl;
428 G4cout << " Pointer : " << this << G4endl;
429 DumpInfo();
430 }
431
432 // Exit with error
433 if (exitWithError) {
435 ed << "An inaccuracy in G4FastStep is beyond tolerance." << G4endl;
436 G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)", "FastSim010", FatalException, ed);
437 }
438
439 // correction for Momentum only.
440 if (!itsOKforMomentum) {
441 G4double vmag = theMomentumChange.mag();
442 theMomentumChange = (1. / vmag) * theMomentumChange;
443 }
444
445 itsOK = (itsOK) && G4VParticleChange::CheckIt(aTrack);
446 return itsOK;
447}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ AvoidHitInvocation
#define G4BestUnit(a, b)
@ fStopAndKill
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double z() const
Hep3Vector unit() const
double x() const
double mag2() const
double y() const
double mag() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
void SetPolarization(const G4ThreeVector &)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetProperTime() const
const G4ThreeVector & GetPolarization() const
void SetPrimaryTrackFinalKineticEnergyAndDirection(G4double, const G4ThreeVector &, G4bool localCoordinates=true)
void KillPrimaryTrack()
Definition G4FastStep.cc:87
void SetPrimaryTrackFinalPosition(const G4ThreeVector &, G4bool localCoordinates=true)
G4bool CheckIt(const G4Track &) override
void SetPrimaryTrackFinalPolarization(const G4ThreeVector &, G4bool localCoordinates=true)
G4Step * UpdateStepForPostStep(G4Step *Step) override
void ProposePrimaryTrackFinalKineticEnergyAndDirection(G4double, const G4ThreeVector &, G4bool localCoordinates=true)
void DumpInfo() const override
void SetPrimaryTrackFinalMomentum(const G4ThreeVector &, G4bool localCoordinates=true)
void ProposePrimaryTrackFinalPosition(const G4ThreeVector &, G4bool localCoordinates=true)
Definition G4FastStep.cc:96
G4Step * UpdateStepForAtRest(G4Step *Step) override
void ProposePrimaryTrackFinalPolarization(const G4ThreeVector &, G4bool localCoordinates=true)
void ProposePrimaryTrackFinalKineticEnergy(G4double)
void ProposePrimaryTrackFinalMomentumDirection(const G4ThreeVector &, G4bool localCoordinates=true)
G4Track * CreateSecondaryTrack(const G4DynamicParticle &, G4ThreeVector, G4ThreeVector, G4double, G4bool localCoordinates=true)
void Initialize(const G4FastTrack &)
Definition G4FastStep.cc:53
const G4Track * GetPrimaryTrack() const
const G4AffineTransform * GetInverseAffineTransformation() const
void SetKineticEnergy(const G4double aValue)
void SetWeight(G4double aValue)
void SetProperTime(const G4double aValue)
void SetGlobalTime(const G4double aValue)
void SetPosition(const G4ThreeVector &aValue)
void AddLocalTime(const G4double aValue)
void SetMomentumDirection(const G4ThreeVector &aValue)
void SetPolarization(const G4ThreeVector &aValue)
G4Track * GetTrack() const
G4StepPoint * GetPostStepPoint() const
G4double GetWeight() const
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const
G4double GetProperTime() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetKineticEnergy() const
virtual G4bool CheckIt(const G4Track &)
void ProposeTrackStatus(G4TrackStatus status)
G4SteppingControl theSteppingControlFlag
virtual void Initialize(const G4Track &)
G4double GetAccuracyForException() const
void AddSecondary(G4Track *aSecondary)
G4double GetAccuracyForWarning() const
virtual void DumpInfo() const
G4Step * UpdateStepInfo(G4Step *Step)
#define ns(x)
Definition xmltok.c:1649