Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/parameterisation/src/G4FastStep.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 53 void 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
 62   G4VParticleChange::Initialize(currentTrack);
 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:
 76   theSteppingControlFlag = AvoidHitInvocation;
 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 //----------------------------------------
 87 void G4FastStep::KillPrimaryTrack()
 88 {
 89   ProposePrimaryTrackFinalKineticEnergy(0.);
 90   ProposeTrackStatus(fStopAndKill);
 91 }
 92 
 93 //--------------------
 94 //
 95 //--------------------
 96 void G4FastStep::ProposePrimaryTrackFinalPosition(const G4ThreeVector& position,
 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 
108 void G4FastStep::SetPrimaryTrackFinalPosition(const G4ThreeVector& position,
109                                               G4bool localCoordinates)
110 {
111   ProposePrimaryTrackFinalPosition(position, localCoordinates);
112 }
113 
114 //--------------------
115 //
116 //--------------------
117 void G4FastStep::ProposePrimaryTrackFinalMomentumDirection(const G4ThreeVector& momentum,
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 
129 void G4FastStep::SetPrimaryTrackFinalMomentum(const G4ThreeVector& momentum,
130                                               G4bool localCoordinates)
131 {
132   ProposePrimaryTrackFinalMomentumDirection(momentum, localCoordinates);
133 }
134 
135 //--------------------
136 //
137 //--------------------
138 void G4FastStep::ProposePrimaryTrackFinalKineticEnergyAndDirection(G4double kineticEnergy,
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());
148   ProposePrimaryTrackFinalKineticEnergy(kineticEnergy);
149 }
150 
151 void G4FastStep::SetPrimaryTrackFinalKineticEnergyAndDirection(G4double kineticEnergy,
152                                                                const G4ThreeVector& direction,
153                                                                G4bool localCoordinates)
154 {
155   ProposePrimaryTrackFinalKineticEnergyAndDirection(kineticEnergy, direction, localCoordinates);
156 }
157 
158 //--------------------
159 //
160 //--------------------
161 void G4FastStep::ProposePrimaryTrackFinalPolarization(const G4ThreeVector& polarization,
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 
173 void G4FastStep::SetPrimaryTrackFinalPolarization(const G4ThreeVector& polarization,
174                                                   G4bool localCoordinates)
175 {
176   ProposePrimaryTrackFinalPolarization(polarization, localCoordinates);
177 }
178 
179 //--------------------
180 //
181 //--------------------
182 G4Track* G4FastStep::CreateSecondaryTrack(const G4DynamicParticle& dynamics,
183                                           G4ThreeVector polarization, G4ThreeVector position,
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 //--------------------
199 G4Track* G4FastStep::CreateSecondaryTrack(const G4DynamicParticle& dynamics, G4ThreeVector position,
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(
217       fFastTrack->GetInverseAffineTransformation()->TransformAxis(
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.
248 void G4FastStep::Initialize(const G4Track&)
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 
260 G4Step* G4FastStep::UpdateStepForPostStep(G4Step* pStep)
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 
295 G4Step* G4FastStep::UpdateStepForAtRest(G4Step* pStep)
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 
330 void G4FastStep::DumpInfo() const
331 {
332   // use base-class DumpInfo
333   G4VParticleChange::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 
359 G4bool G4FastStep::CheckIt(const G4Track& aTrack)
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()) {
386     G4ExceptionDescription ed;
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()) {
400       G4ExceptionDescription ed;
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()) {
412     G4ExceptionDescription ed;
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()) {
420     G4ExceptionDescription ed;
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) {
434     G4ExceptionDescription ed;
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 }
448