G4FastStep.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 //---------------------------------------------------------------
00030 //
00031 //  G4FastStep.cc
00032 //
00033 //  Description:
00034 //    Encapsulates a G4ParticleChange and insure friendly interface
00035 //    methods to manage the primary/secondaries final state for 
00036 //    Fast Simulation Models.
00037 //
00038 //  History:
00039 //    Oct 97: Verderi && MoraDeFreitas - First Implementation.
00040 //    Apr 98: MoraDeFreitas - G4FastStep becomes the G4ParticleChange
00041 //                      for the Fast Simulation Process.
00042 //
00043 //---------------------------------------------------------------
00044 
00045 #include "G4FastStep.hh"
00046 
00047 #include "G4SystemOfUnits.hh"
00048 #include "G4Track.hh"
00049 #include "G4Step.hh"
00050 #include "G4TrackFastVector.hh"
00051 #include "G4DynamicParticle.hh"
00052 
00053 void G4FastStep::Initialize(const G4FastTrack& fastTrack)
00054 {
00055   // keeps the fastTrack reference
00056   fFastTrack=&fastTrack;
00057 
00058   // currentTrack will be used to Initialize the other data members
00059   const G4Track& currentTrack = *(fFastTrack->GetPrimaryTrack());
00060 
00061   // use base class's method at first
00062   G4VParticleChange::Initialize(currentTrack);
00063 
00064   // set Energy/Momentum etc. equal to those of the parent particle
00065   const G4DynamicParticle*  pParticle = currentTrack.GetDynamicParticle();
00066   theEnergyChange          = pParticle->GetKineticEnergy();
00067   theMomentumChange        = pParticle->GetMomentumDirection();
00068   thePolarizationChange    = pParticle->GetPolarization();
00069   theProperTimeChange      = pParticle->GetProperTime();
00070 
00071   // set Position/Time etc. equal to those of the parent track
00072   thePositionChange      = currentTrack.GetPosition();
00073   theTimeChange          = currentTrack.GetGlobalTime();
00074 
00075   // switch off stepping hit invokation by default:
00076   theSteppingControlFlag = AvoidHitInvocation;
00077 
00078   // event biasing weigth:
00079   theWeightChange        = currentTrack.GetWeight();
00080 }  
00081 
00082 //----------------------------------------
00083 // -- Set the StopAndKilled signal
00084 // -- and put kinetic energy to 0.0. in the
00085 // -- G4ParticleChange.
00086 //----------------------------------------
00087 void G4FastStep::KillPrimaryTrack()
00088 {
00089   SetPrimaryTrackFinalKineticEnergy(0.) ;
00090   ProposeTrackStatus(fStopAndKill) ;
00091 }
00092 
00093 //--------------------
00094 //
00095 //--------------------
00096 void 
00097 G4FastStep::
00098 ProposePrimaryTrackFinalPosition(const G4ThreeVector &position,
00099                                  G4bool localCoordinates)
00100 {
00101   // Compute the position coordinate in global
00102   // reference system if needed ...
00103   G4ThreeVector globalPosition = position;
00104   if (localCoordinates) 
00105     globalPosition = fFastTrack->GetInverseAffineTransformation()->
00106       TransformPoint(position);
00107   // ...and feed the globalPosition:
00108   thePositionChange = globalPosition;
00109 }
00110 
00111 void 
00112 G4FastStep::
00113 SetPrimaryTrackFinalPosition(const G4ThreeVector &position,
00114                              G4bool localCoordinates)
00115 {
00116   ProposePrimaryTrackFinalPosition(position, localCoordinates);
00117 }
00118 
00119 //--------------------
00120 //
00121 //--------------------
00122 void 
00123 G4FastStep::
00124 ProposePrimaryTrackFinalMomentumDirection(const G4ThreeVector &momentum,
00125                                           G4bool localCoordinates)
00126 {
00127   // Compute the momentum in global reference
00128   // system if needed ...
00129   G4ThreeVector globalMomentum = momentum;
00130   if (localCoordinates)
00131     globalMomentum = fFastTrack->GetInverseAffineTransformation()->
00132       TransformAxis(momentum);
00133   // ...and feed the globalMomentum (ensuring unitarity)
00134   SetMomentumChange(globalMomentum.unit());
00135 }
00136 
00137 void 
00138 G4FastStep::
00139 SetPrimaryTrackFinalMomentum(const G4ThreeVector &momentum,
00140                              G4bool localCoordinates)
00141 {
00142   ProposePrimaryTrackFinalMomentumDirection(momentum, localCoordinates);
00143 }
00144 
00145 //--------------------
00146 //
00147 //--------------------
00148 void 
00149 G4FastStep::
00150 ProposePrimaryTrackFinalKineticEnergyAndDirection(G4double kineticEnergy,
00151                                                   const G4ThreeVector &direction,
00152                                                   G4bool localCoordinates)
00153 {
00154   // Compute global direction if needed...
00155   G4ThreeVector globalDirection = direction;
00156   if (localCoordinates)
00157     globalDirection =fFastTrack->GetInverseAffineTransformation()-> 
00158       TransformAxis(direction);
00159   // ...and feed the globalMomentum (ensuring unitarity)
00160   SetMomentumChange(globalDirection.unit());
00161   SetPrimaryTrackFinalKineticEnergy(kineticEnergy);
00162 }
00163 
00164 void 
00165 G4FastStep::
00166 SetPrimaryTrackFinalKineticEnergyAndDirection(G4double kineticEnergy,
00167                                               const G4ThreeVector &direction,
00168                                               G4bool localCoordinates)
00169 {
00170   ProposePrimaryTrackFinalKineticEnergyAndDirection(kineticEnergy, direction, localCoordinates);
00171 }
00172 
00173 //--------------------
00174 //
00175 //--------------------
00176 void 
00177 G4FastStep::
00178 ProposePrimaryTrackFinalPolarization(const G4ThreeVector &polarization,
00179                                      G4bool localCoordinates)
00180 {
00181   // Compute polarization in global system if needed:
00182   G4ThreeVector globalPolarization(polarization);
00183   if (localCoordinates)
00184     globalPolarization = fFastTrack->GetInverseAffineTransformation()->
00185       TransformAxis(globalPolarization);  
00186   // Feed the particle globalPolarization:
00187   thePolarizationChange = globalPolarization;
00188 }
00189 
00190 void 
00191 G4FastStep::
00192 SetPrimaryTrackFinalPolarization(const G4ThreeVector &polarization,
00193                                  G4bool localCoordinates)
00194 {
00195   ProposePrimaryTrackFinalPolarization(polarization, localCoordinates);
00196 }
00197 
00198 //--------------------
00199 //
00200 //--------------------
00201 G4Track* G4FastStep::
00202 CreateSecondaryTrack(const G4DynamicParticle& dynamics,
00203                      G4ThreeVector polarization,
00204                      G4ThreeVector position,
00205                      G4double time,
00206                      G4bool localCoordinates     )
00207 {
00208   G4DynamicParticle dummyDynamics(dynamics);
00209   
00210   // ------------------------------------------
00211   // Add the polarization to the dummyDynamics:
00212   // ------------------------------------------
00213   dummyDynamics.SetPolarization(polarization.x(),
00214                                 polarization.y(),
00215                                 polarization.z());
00216   
00217   return CreateSecondaryTrack(dummyDynamics, position, time, localCoordinates);
00218 }
00219 
00220 //--------------------
00221 //
00222 //--------------------
00223 G4Track* G4FastStep::
00224 CreateSecondaryTrack(const G4DynamicParticle& dynamics,
00225                      G4ThreeVector position,
00226                      G4double time,
00227                      G4bool localCoordinates     )
00228 {
00229   // ----------------------------------------
00230   // Quantities in global coordinates system.
00231   //  
00232   // The allocated globalDynamics is deleted
00233   // by the destructor of the G4Track.
00234   // ----------------------------------------
00235   G4DynamicParticle* globalDynamics =
00236     new G4DynamicParticle(dynamics);
00237   G4ThreeVector globalPosition(position);
00238   
00239   // -----------------------------------
00240   // Convert to global system if needed:
00241   // -----------------------------------
00242   if (localCoordinates)
00243     {
00244       // -- Momentum Direction:
00245       globalDynamics->SetMomentumDirection(fFastTrack->
00246                                            GetInverseAffineTransformation()->
00247                                            TransformAxis(globalDynamics->
00248                                                          GetMomentumDirection()));
00249       // -- Polarization:
00250       G4ThreeVector globalPolarization;
00251       globalPolarization = fFastTrack->GetInverseAffineTransformation()->
00252         TransformAxis(globalDynamics->GetPolarization());
00253       globalDynamics->SetPolarization(
00254                                       globalPolarization.x(),
00255                                       globalPolarization.y(),
00256                                       globalPolarization.z()
00257                                       );
00258       
00259       // -- Position:
00260       globalPosition = fFastTrack->GetInverseAffineTransformation()->
00261         TransformPoint(globalPosition);
00262     }
00263   
00264   //-------------------------------------
00265   // Create the G4Track of the secondary:
00266   //-------------------------------------
00267   G4Track* secondary = new G4Track(
00268                                    globalDynamics,
00269                                    time,
00270                                    globalPosition
00271                                    );
00272   
00273   //-------------------------------
00274   // and feed the changes:
00275   //-------------------------------
00276   AddSecondary(secondary);
00277   
00278   //--------------------------------------
00279   // returns the pointer on the secondary:
00280   //--------------------------------------
00281   return secondary;
00282 }
00283 
00284 // G4FastStep should never be Initialized in this way
00285 // but we must define it to avoid warnings.
00286 void G4FastStep::Initialize(const G4Track&)
00287 {
00288   G4ExceptionDescription  tellWhatIsWrong;
00289   tellWhatIsWrong << "G4FastStep can be initialised only through G4FastTrack."
00290                   << G4endl;
00291   G4Exception("G4FastStep::Initialize(const G4Track&)",
00292               "FastSim005",
00293               FatalException,
00294               tellWhatIsWrong);
00295 }
00296 
00297 G4FastStep::G4FastStep()
00298   : G4VParticleChange()
00299 {
00300   if (verboseLevel>2)
00301   {
00302     G4cerr << "G4FastStep::G4FastStep() " << G4endl;
00303   }
00304 }
00305 
00306 G4FastStep::~G4FastStep() 
00307 {
00308   if (verboseLevel>2)
00309   {
00310     G4cerr << "G4FastStep::~G4FastStep() " << G4endl;
00311   }
00312 }
00313 
00314 // copy and assignment operators are implemented as "shallow copy"
00315 G4FastStep::G4FastStep(const G4FastStep &right)
00316   : G4VParticleChange()
00317 {
00318    *this = right;
00319 }
00320 
00321 
00322 G4FastStep & G4FastStep::operator=(const G4FastStep &right)
00323 {
00324    if (this != &right)
00325    {
00326      G4VParticleChange::operator=(right);
00327      theListOfSecondaries          = right.theListOfSecondaries;
00328      theSizeOftheListOfSecondaries = right.theSizeOftheListOfSecondaries;
00329      theNumberOfSecondaries        = right.theNumberOfSecondaries;
00330      theStatusChange               = right.theStatusChange;
00331      theMomentumChange             = right.theMomentumChange;
00332      thePolarizationChange         = right.thePolarizationChange;
00333      thePositionChange             = right.thePositionChange;
00334      theTimeChange                 = right.theTimeChange;
00335      theEnergyChange               = right.theEnergyChange;
00336      theTrueStepLength             = right.theTrueStepLength;
00337      theLocalEnergyDeposit         = right.theLocalEnergyDeposit;
00338      theSteppingControlFlag        = right.theSteppingControlFlag;
00339      theWeightChange               = right.theWeightChange;
00340    }
00341    return *this;
00342 }
00343 
00344 
00345 
00346 
00347 
00348 G4bool G4FastStep::operator==(const G4FastStep &right) const
00349 {
00350    return ((G4VParticleChange *)this == (G4VParticleChange *) &right);
00351 }
00352 
00353 G4bool G4FastStep::operator!=(const G4FastStep &right) const
00354 {
00355    return ((G4VParticleChange *)this != (G4VParticleChange *) &right);
00356 }
00357 
00358 //----------------------------------------------------------------
00359 // methods for updating G4Step 
00360 //
00361 
00362 G4Step* G4FastStep::UpdateStepForPostStep(G4Step* pStep)
00363 { 
00364   // A physics process always calculates the final state of the particle
00365 
00366   // Take note that the return type of GetMomentumChange is a
00367   // pointer to G4ParticleMometum. Also it is a normalized 
00368   // momentum vector.
00369 
00370   //  G4StepPoint* pPreStepPoint  = pStep->GetPreStepPoint(); 
00371   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00372   G4Track*     aTrack  = pStep->GetTrack();
00373   //  G4double     mass = aTrack->GetDynamicParticle()->GetMass();
00374  
00375   // update kinetic energy and momentum direction
00376   pPostStepPoint->SetMomentumDirection(theMomentumChange);
00377   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00378 
00379    // update polarization
00380   pPostStepPoint->SetPolarization( thePolarizationChange );
00381       
00382   // update position and time
00383   pPostStepPoint->SetPosition( thePositionChange  );
00384   pPostStepPoint->SetGlobalTime( theTimeChange  );
00385   pPostStepPoint->AddLocalTime( theTimeChange 
00386                                  - aTrack->GetGlobalTime());
00387   pPostStepPoint->SetProperTime( theProperTimeChange  );
00388 
00389   // update weight
00390   pPostStepPoint->SetWeight( theWeightChange );
00391 
00392   if (debugFlag) CheckIt(*aTrack);
00393 
00394   
00395   //  Update the G4Step specific attributes 
00396   return UpdateStepInfo(pStep);
00397 }
00398 
00399 G4Step* G4FastStep::UpdateStepForAtRest(G4Step* pStep)
00400 { 
00401   // A physics process always calculates the final state of the particle
00402 
00403   // G4StepPoint* pPreStepPoint  = pStep->GetPreStepPoint(); 
00404   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00405   G4Track*     aTrack  = pStep->GetTrack();
00406   // G4double     mass = aTrack->GetDynamicParticle()->GetMass();
00407  
00408   // update kinetic energy and momentum direction
00409   pPostStepPoint->SetMomentumDirection(theMomentumChange);
00410   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00411 
00412   // update polarization
00413   pPostStepPoint->SetPolarization( thePolarizationChange );
00414       
00415   // update position and time
00416   pPostStepPoint->SetPosition( thePositionChange  );
00417   pPostStepPoint->SetGlobalTime( theTimeChange  );
00418   pPostStepPoint->AddLocalTime( theTimeChange 
00419                                  - aTrack->GetGlobalTime());
00420   pPostStepPoint->SetProperTime( theProperTimeChange  );
00421 
00422   // update weight
00423   pPostStepPoint->SetWeight( theWeightChange );
00424 
00425   if (debugFlag) CheckIt(*aTrack);
00426 
00427   //  Update the G4Step specific attributes 
00428   return UpdateStepInfo(pStep);
00429 }
00430 
00431 //----------------------------------------------------------------
00432 // methods for printing messages  
00433 //
00434 
00435 void G4FastStep::DumpInfo() const
00436 {
00437 // use base-class DumpInfo
00438   G4VParticleChange::DumpInfo();
00439 
00440   G4cout.precision(3);
00441   G4cout << "        Position - x (mm)   : " 
00442        << std::setw(20) << thePositionChange.x()/mm
00443        << G4endl; 
00444   G4cout << "        Position - y (mm)   : " 
00445        << std::setw(20) << thePositionChange.y()/mm
00446        << G4endl; 
00447   G4cout << "        Position - z (mm)   : " 
00448        << std::setw(20) << thePositionChange.z()/mm
00449        << G4endl;
00450   G4cout << "        Time (ns)           : " 
00451        << std::setw(20) << theTimeChange/ns
00452        << G4endl;
00453   G4cout << "        Proper Time (ns)    : " 
00454        << std::setw(20) << theProperTimeChange/ns
00455        << G4endl;
00456   G4cout << "        Momentum Direct - x : " 
00457        << std::setw(20) << theMomentumChange.x()
00458        << G4endl;
00459   G4cout << "        Momentum Direct - y : " 
00460        << std::setw(20) << theMomentumChange.y()
00461        << G4endl;
00462   G4cout << "        Momentum Direct - z : " 
00463        << std::setw(20) << theMomentumChange.z()
00464        << G4endl;
00465   G4cout << "        Kinetic Energy (MeV): " 
00466        << std::setw(20) << theEnergyChange/MeV
00467        << G4endl;
00468   G4cout << "        Polarization - x    : " 
00469        << std::setw(20) << thePolarizationChange.x()
00470        << G4endl;
00471   G4cout << "        Polarization - y    : " 
00472        << std::setw(20) << thePolarizationChange.y()
00473        << G4endl;
00474   G4cout << "        Polarization - z    : " 
00475        << std::setw(20) <<  thePolarizationChange.z()
00476        << G4endl;
00477 }
00478 
00479 G4bool G4FastStep::CheckIt(const G4Track& aTrack)
00480 {
00481   //
00482   //      In the G4FastStep::CheckIt
00483   //      We only check a bit
00484   //      
00485   //      If the user violates the energy,
00486   //      We don't care, we agree.
00487   //
00488   //      But for theMomentumDirectionChange,
00489   //      We do pay attention.
00490   //      And if too large is its range,
00491   //      We issue an Exception.
00492   //
00493   //
00494   // It means, the G4FastStep::CheckIt issues an exception only for the
00495   // theMomentumDirectionChange which should be an unit vector
00496   // and it corrects it because it could cause problems for the ulterior
00497   // tracking.For the rest, only warning are issued.
00498 
00499   G4bool    itsOK = true;
00500   G4bool    exitWithError = false;
00501   G4double  accuracy;
00502   
00503   // Energy should not be larger than the initial value
00504   accuracy = ( theEnergyChange - aTrack.GetKineticEnergy())/MeV;
00505   if (accuracy > GetAccuracyForWarning())
00506     {
00507       G4ExceptionDescription ed;
00508       ed << "The energy becomes larger than the initial value, difference = " <<  accuracy << " MeV" << G4endl;
00509       G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)",
00510                   "FastSim006",
00511                   JustWarning, ed);
00512       itsOK = false;
00513       if (accuracy > GetAccuracyForException())  {exitWithError = true;}
00514     }
00515   
00516   G4bool itsOKforMomentum = true;
00517   if ( theEnergyChange >0.)
00518     {
00519       accuracy = std::abs(theMomentumChange.mag2()-1.0);
00520       if (accuracy > GetAccuracyForWarning())
00521         {
00522           G4ExceptionDescription ed;
00523           ed << "The Momentum Change is not a unit vector, difference = " <<  accuracy << G4endl;
00524           G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)",
00525                       "FastSim007",
00526                       JustWarning, ed);
00527           itsOK = itsOKforMomentum = false;
00528           if (accuracy > GetAccuracyForException())  {exitWithError = true;}
00529         }
00530     }
00531   
00532   accuracy = (aTrack.GetGlobalTime()- theTimeChange)/ns;  
00533   if (accuracy > GetAccuracyForWarning())
00534     {
00535       G4ExceptionDescription ed;
00536       ed << "The global time is getting backward, difference = " <<  accuracy << " ns" << G4endl;
00537       G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)",
00538                   "FastSim008",
00539                   JustWarning, ed);
00540       itsOK = false;
00541     }
00542   
00543   accuracy = (aTrack.GetProperTime() - theProperTimeChange )/ns;
00544   if (accuracy >  GetAccuracyForWarning())
00545     {
00546       G4ExceptionDescription ed;
00547       ed << "The proper time is getting backward, difference = " <<  accuracy << " ns" << G4endl;
00548       G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)",
00549                   "FastSim009",
00550                   JustWarning, ed);
00551       itsOK = false;
00552     }
00553   
00554   if (!itsOK)
00555     { 
00556       G4cout << "ERROR - G4FastStep::CheckIt() " << G4endl;
00557       G4cout << "        Pointer : " << this << G4endl ;
00558       DumpInfo();
00559     }
00560   
00561   // Exit with error
00562   if (exitWithError)
00563     {
00564       G4ExceptionDescription ed;
00565       ed << "An inaccuracy in G4FastStep is beyond tolerance." << G4endl;
00566       G4Exception("G4FastStep::CheckIt(const G4Track& aTrack)",
00567                   "FastSim010",
00568                   FatalException, ed);
00569     }
00570   
00571   //correction for Momentum only.
00572   if (!itsOKforMomentum) {
00573     G4double vmag = theMomentumChange.mag();
00574     theMomentumChange = (1./vmag)*theMomentumChange;
00575   }
00576   
00577   itsOK = (itsOK) && G4VParticleChange::CheckIt(aTrack); 
00578   return itsOK;
00579 }

Generated on Mon May 27 17:48:15 2013 for Geant4 by  doxygen 1.4.7