G4ParticleChange.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: G4ParticleChange.cc 68795 2013-04-05 13:24:46Z gcosmo $
00028 //
00029 // 
00030 // --------------------------------------------------------------
00031 //      GEANT 4 class implementation file 
00032 //
00033 //      
00034 //      
00035 // ------------------------------------------------------------
00036 //   Implemented for the new scheme                 23 Mar. 1998  H.Kurahige
00037 //   Change default debug flag to false             10 May. 1998  H.Kurahige
00038 //   Add Track weight                               12 Nov. 1998  H.Kurashige
00039 //   Activate CheckIt method for VERBOSE mode       14 Dec. 1998 H.Kurashige
00040 //   Modified CheckIt method for time                9 Feb. 1999 H.Kurashige
00041 //   Rename SetXXX methods to ProposeXXX   DynamicCharge  Oct. 2005 H.Kurashige
00042 //   Add get/ProposeMagneticMoment                  Mar 2007 H.Kurashige
00043 // --------------------------------------------------------------
00044 
00045 #include "G4ParticleChange.hh"
00046 #include "G4PhysicalConstants.hh"
00047 #include "G4SystemOfUnits.hh"
00048 #include "G4Track.hh"
00049 #include "G4Step.hh"
00050 #include "G4TrackFastVector.hh"
00051 #include "G4DynamicParticle.hh"
00052 #include "G4ExceptionSeverity.hh"
00053 
00054 G4ParticleChange::G4ParticleChange()
00055   : G4VParticleChange(),  
00056     theMomentumDirectionChange(),
00057     thePolarizationChange(),
00058     theEnergyChange(0.), 
00059     theVelocityChange(0.), isVelocityChanged(false),
00060     thePositionChange(),
00061     theGlobalTime0(0.),    theLocalTime0(0.),
00062     theTimeChange(0.),     theProperTimeChange(0.), 
00063     theMassChange(0.), theChargeChange(0.),
00064     theMagneticMomentChange(0.), theCurrentTrack(0)
00065 {
00066 }
00067 
00068 G4ParticleChange::~G4ParticleChange() 
00069 {
00070 #ifdef G4VERBOSE
00071   if (verboseLevel>2) {
00072     G4cout << "G4ParticleChange::~G4ParticleChange() " << G4endl;
00073   }
00074 #endif
00075 }
00076 
00077 // copy constructor
00078 G4ParticleChange::G4ParticleChange(const G4ParticleChange &right)
00079   : G4VParticleChange(right)
00080 {
00081    if (verboseLevel>1) {
00082     G4cout << "G4ParticleChange::  copy constructor is called " << G4endl;
00083    }
00084    theCurrentTrack = right.theCurrentTrack;
00085 
00086    theMomentumDirectionChange = right.theMomentumDirectionChange;
00087    thePolarizationChange = right.thePolarizationChange;
00088    thePositionChange   = right.thePositionChange;
00089    theGlobalTime0      = right.theGlobalTime0;
00090    theLocalTime0       = right.theLocalTime0;
00091    theTimeChange       = right.theTimeChange;
00092    theProperTimeChange = right.theProperTimeChange;
00093    theEnergyChange     = right.theEnergyChange;
00094    theVelocityChange   = right.theVelocityChange;
00095    isVelocityChanged   = true;
00096    theMassChange       = right.theMassChange;
00097    theChargeChange     = right.theChargeChange;
00098    theMagneticMomentChange = right.theMagneticMomentChange;
00099 }
00100 
00101 // assignemnt operator
00102 G4ParticleChange & G4ParticleChange::operator=(const G4ParticleChange &right)
00103 {
00104 #ifdef G4VERBOSE
00105    if (verboseLevel>1) {
00106     G4cout << "G4ParticleChange:: assignment operator is called " << G4endl;
00107    }
00108 #endif
00109    if (this != &right){
00110      if (theNumberOfSecondaries>0) {
00111 #ifdef G4VERBOSE
00112        if (verboseLevel>0) {
00113          G4cout << "G4ParticleChange: assignment operator Warning  ";
00114          G4cout << "theListOfSecondaries is not empty ";
00115        }
00116 #endif
00117        for (G4int index= 0; index<theNumberOfSecondaries; index++){
00118          if ( (*theListOfSecondaries)[index] ) delete (*theListOfSecondaries)[index] ;
00119        }
00120      }
00121      delete theListOfSecondaries; 
00122      
00123     theListOfSecondaries =  new G4TrackFastVector();
00124     theNumberOfSecondaries = right.theNumberOfSecondaries;
00125     for (G4int index = 0; index<theNumberOfSecondaries; index++){
00126       G4Track* newTrack =  new G4Track(*((*right.theListOfSecondaries)[index] ));
00127       theListOfSecondaries->SetElement(index, newTrack);                            }
00128 
00129      theStatusChange = right.theStatusChange;
00130      theCurrentTrack = right.theCurrentTrack;
00131      
00132      theMomentumDirectionChange = right.theMomentumDirectionChange;
00133      thePolarizationChange = right.thePolarizationChange;
00134      thePositionChange = right.thePositionChange;
00135      theGlobalTime0      = right.theGlobalTime0;
00136      theLocalTime0       = right.theLocalTime0;
00137      theTimeChange       = right.theTimeChange;
00138      theProperTimeChange = right.theProperTimeChange;
00139      theEnergyChange     = right.theEnergyChange;
00140      theVelocityChange   = right.theVelocityChange;
00141      isVelocityChanged   = true;
00142      theMassChange       = right.theMassChange;
00143      theChargeChange     = right.theChargeChange;
00144      theMagneticMomentChange = right.theMagneticMomentChange;
00145      
00146      theTrueStepLength = right.theTrueStepLength;
00147      theLocalEnergyDeposit = right.theLocalEnergyDeposit;
00148      theSteppingControlFlag = right.theSteppingControlFlag;
00149    }
00150    return *this;
00151 }
00152 
00153 G4bool G4ParticleChange::operator==(const G4ParticleChange &right) const
00154 {
00155    return ((G4VParticleChange *)this == (G4VParticleChange *) &right);
00156 }
00157 
00158 G4bool G4ParticleChange::operator!=(const G4ParticleChange &right) const
00159 {
00160    return ((G4VParticleChange *)this != (G4VParticleChange *) &right);
00161 }
00162 
00163 
00164 //----------------------------------------------------------------
00165 // methods for handling secondaries 
00166 //
00167 
00168 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00169                                     G4bool   IsGoodForTracking    )
00170 {
00171   //  create track
00172   G4Track* aTrack = new G4Track(aParticle, GetGlobalTime(), thePositionChange);
00173 
00174   // set IsGoodGorTrackingFlag
00175   if (IsGoodForTracking) aTrack->SetGoodForTrackingFlag();
00176 
00177   //   Touchable handle is copied to keep the pointer
00178   aTrack->SetTouchableHandle(theCurrentTrack->GetTouchableHandle());
00179  
00180  //  add a secondary
00181   G4VParticleChange::AddSecondary(aTrack);
00182 }
00183 
00184 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00185                                     G4ThreeVector      newPosition,
00186                                     G4bool   IsGoodForTracking    )
00187 {
00188   //  create track
00189   G4Track*  aTrack = new G4Track(aParticle, GetGlobalTime(), newPosition);
00190 
00191   // set IsGoodGorTrackingFlag
00192   if (IsGoodForTracking) aTrack->SetGoodForTrackingFlag();
00193 
00194   //   Touchable is a temporary object, so you cannot keep the pointer
00195   aTrack->SetTouchableHandle((G4VTouchable*)0);
00196 
00197   //  add a secondary
00198   G4VParticleChange::AddSecondary(aTrack);
00199 }
00200 
00201 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00202                                     G4double           newTime,
00203                                     G4bool   IsGoodForTracking    )
00204 {
00205   //  create track
00206   G4Track*  aTrack = new G4Track(aParticle, newTime, thePositionChange); 
00207 
00208   // set IsGoodGorTrackingFlag
00209   if (IsGoodForTracking) aTrack->SetGoodForTrackingFlag();
00210  
00211   //   Touchable handle is copied to keep the pointer
00212   aTrack->SetTouchableHandle(theCurrentTrack->GetTouchableHandle());
00213 
00214   //  add a secondary
00215   G4VParticleChange::AddSecondary(aTrack);
00216 }
00217 
00218 void G4ParticleChange::AddSecondary(G4Track* aTrack)
00219 {
00220   //  add a secondary
00221   G4VParticleChange::AddSecondary(aTrack);
00222 }
00223 
00224 //----------------------------------------------------------------
00225 // functions for Initialization
00226 //
00227 
00228 void G4ParticleChange::Initialize(const G4Track& track)
00229 {
00230   // use base class's method at first
00231   G4VParticleChange::Initialize(track);
00232   theCurrentTrack= &track;
00233 
00234   // set Energy/Momentum etc. equal to those of the parent particle
00235   const G4DynamicParticle*  pParticle = track.GetDynamicParticle();
00236   theEnergyChange            = pParticle->GetKineticEnergy();
00237   theVelocityChange          = track.GetVelocity();
00238   isVelocityChanged          = false;
00239   theMomentumDirectionChange = pParticle->GetMomentumDirection();
00240   thePolarizationChange      = pParticle->GetPolarization();
00241   theProperTimeChange        = pParticle->GetProperTime();
00242 
00243   // Set mass/charge/MagneticMoment  of DynamicParticle
00244   theMassChange = pParticle->GetMass();
00245   theChargeChange = pParticle->GetCharge();
00246   theMagneticMomentChange = pParticle->GetMagneticMoment();
00247 
00248   // set Position  equal to those of the parent track
00249   thePositionChange      = track.GetPosition();
00250 
00251   // set TimeChange equal to local time of the parent track
00252   theTimeChange                = track.GetLocalTime();
00253 
00254   // set initial Local/Global time of the parent track
00255   theLocalTime0           = track.GetLocalTime();
00256   theGlobalTime0          = track.GetGlobalTime();
00257 
00258 }
00259 
00260 //----------------------------------------------------------------
00261 // methods for updating G4Step 
00262 //
00263 
00264 G4Step* G4ParticleChange::UpdateStepForAlongStep(G4Step* pStep)
00265 {
00266   // A physics process always calculates the final state of the
00267   // particle relative to the initial state at the beginning
00268   // of the Step, i.e., based on information of G4Track (or
00269   // equivalently the PreStepPoint). 
00270   // So, the differences (delta) between these two states have to be
00271   // calculated and be accumulated in PostStepPoint. 
00272   
00273   // Take note that the return type of GetMomentumDirectionChange is a
00274   // pointer to G4ParticleMometum. Also it is a normalized 
00275   // momentum vector.
00276 
00277   G4StepPoint* pPreStepPoint  = pStep->GetPreStepPoint(); 
00278   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00279   G4Track* pTrack = pStep->GetTrack();
00280   G4double     mass = theMassChange;
00281 
00282   // Set Mass/Charge/MagneticMoment 
00283   pPostStepPoint->SetMass(theMassChange);
00284   pPostStepPoint->SetCharge(theChargeChange);  
00285   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);  
00286  
00287   // calculate new kinetic energy
00288   G4double preEnergy = pPreStepPoint->GetKineticEnergy();
00289   G4double energy = pPostStepPoint->GetKineticEnergy() 
00290                     + (theEnergyChange - preEnergy); 
00291 
00292   // update kinetic energy and momentum direction
00293   if (energy > 0.0) {
00294     // calculate new momentum
00295     G4ThreeVector pMomentum =  pPostStepPoint->GetMomentum() 
00296                 + ( CalcMomentum(theEnergyChange, theMomentumDirectionChange, mass)
00297                     - pPreStepPoint->GetMomentum());
00298     G4double      tMomentum = pMomentum.mag();
00299     G4ThreeVector direction(1.0,0.0,0.0); 
00300     if( tMomentum > 0. ){
00301       G4double  inv_Momentum= 1.0 / tMomentum; 
00302       direction= pMomentum * inv_Momentum;
00303     }
00304     pPostStepPoint->SetMomentumDirection(direction);
00305     pPostStepPoint->SetKineticEnergy( energy );
00306   } else {
00307     // stop case
00308     //pPostStepPoint->SetMomentumDirection(G4ThreeVector(1., 0., 0.));
00309     pPostStepPoint->SetKineticEnergy(0.0);
00310   }
00311   // calculate velocity
00312   if (!isVelocityChanged) {
00313     if(energy > 0.0) {
00314       pTrack->SetKineticEnergy(energy);
00315       theVelocityChange = pTrack->CalculateVelocity();
00316       pTrack->SetKineticEnergy(preEnergy);
00317     } else if(theMassChange > 0.0) {
00318       theVelocityChange = 0.0;
00319     }
00320   }
00321   pPostStepPoint->SetVelocity(theVelocityChange);
00322 
00323   // update polarization
00324   pPostStepPoint->AddPolarization( thePolarizationChange
00325                                    - pPreStepPoint->GetPolarization());
00326       
00327   // update position and time
00328   pPostStepPoint->AddPosition( thePositionChange 
00329                                - pPreStepPoint->GetPosition() );
00330   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
00331   pPostStepPoint->AddLocalTime( theTimeChange - theLocalTime0 );               
00332   pPostStepPoint->AddProperTime( theProperTimeChange 
00333                                  - pPreStepPoint->GetProperTime());
00334 
00335   if (isParentWeightProposed ){
00336     pPostStepPoint->SetWeight( theParentWeight );
00337   }
00338 
00339 #ifdef G4VERBOSE
00340   G4Track*     aTrack  = pStep->GetTrack();
00341   if (debugFlag) CheckIt(*aTrack);
00342 #endif
00343 
00344   //  Update the G4Step specific attributes 
00345   return UpdateStepInfo(pStep);
00346 }
00347 
00348 G4Step* G4ParticleChange::UpdateStepForPostStep(G4Step* pStep)
00349 { 
00350   // A physics process always calculates the final state of the particle
00351 
00352   // Take note that the return type of GetMomentumChange is a
00353   // pointer to G4ParticleMometum. Also it is a normalized 
00354   // momentum vector.
00355 
00356   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00357   G4Track* pTrack = pStep->GetTrack();
00358 
00359   // Set Mass/Charge
00360   pPostStepPoint->SetMass(theMassChange);
00361   pPostStepPoint->SetCharge(theChargeChange);  
00362   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);  
00363  
00364   // update kinetic energy and momentum direction
00365   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
00366   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00367 
00368   // calculate velocity
00369   pTrack->SetKineticEnergy( theEnergyChange );
00370   if (!isVelocityChanged) {
00371     if(theEnergyChange > 0.0) {
00372       theVelocityChange = pTrack->CalculateVelocity();
00373     } else if(theMassChange > 0.0) {
00374       theVelocityChange = 0.0;
00375     }
00376   }
00377   pPostStepPoint->SetVelocity(theVelocityChange);
00378  
00379    // update polarization
00380   pPostStepPoint->SetPolarization( thePolarizationChange );
00381       
00382   // update position and time
00383   pPostStepPoint->SetPosition( thePositionChange  );
00384   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
00385   pPostStepPoint->SetLocalTime( theTimeChange );               
00386   pPostStepPoint->SetProperTime( theProperTimeChange  );
00387 
00388   if (isParentWeightProposed ){
00389     pPostStepPoint->SetWeight( theParentWeight );
00390   }
00391 
00392 #ifdef G4VERBOSE
00393   G4Track*     aTrack  = pStep->GetTrack();
00394   if (debugFlag) CheckIt(*aTrack);
00395 #endif
00396 
00397   //  Update the G4Step specific attributes 
00398   return UpdateStepInfo(pStep);
00399 }
00400 
00401 
00402 G4Step* G4ParticleChange::UpdateStepForAtRest(G4Step* pStep)
00403 { 
00404   // A physics process always calculates the final state of the particle
00405 
00406   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00407 
00408   // Set Mass/Charge
00409   pPostStepPoint->SetMass(theMassChange);
00410   pPostStepPoint->SetCharge(theChargeChange);  
00411   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);  
00412  
00413   // update kinetic energy and momentum direction
00414   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
00415   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00416   if (!isVelocityChanged) theVelocityChange = pStep->GetTrack()->CalculateVelocity();
00417   pPostStepPoint->SetVelocity(theVelocityChange);
00418 
00419   // update polarization
00420   pPostStepPoint->SetPolarization( thePolarizationChange );
00421       
00422   // update position and time
00423   pPostStepPoint->SetPosition( thePositionChange  );
00424   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
00425   pPostStepPoint->SetLocalTime( theTimeChange );               
00426   pPostStepPoint->SetProperTime( theProperTimeChange  );
00427 
00428   if (isParentWeightProposed ){
00429     pPostStepPoint->SetWeight( theParentWeight );
00430   }
00431 
00432 #ifdef G4VERBOSE
00433   G4Track*     aTrack  = pStep->GetTrack();
00434   if (debugFlag) CheckIt(*aTrack);
00435 #endif
00436 
00437   //  Update the G4Step specific attributes 
00438   return UpdateStepInfo(pStep);
00439 }
00440 
00441 //----------------------------------------------------------------
00442 // methods for printing messages  
00443 //
00444 
00445 void G4ParticleChange::DumpInfo() const
00446 {
00447 // use base-class DumpInfo
00448   G4VParticleChange::DumpInfo();
00449 
00450   G4int oldprc = G4cout.precision(3);
00451 
00452   G4cout << "        Mass (GeV)   : " 
00453        << std::setw(20) << theMassChange/GeV
00454        << G4endl; 
00455   G4cout << "        Charge (eplus)   : " 
00456        << std::setw(20) << theChargeChange/eplus
00457        << G4endl; 
00458   G4cout << "        MagneticMoment   : " 
00459          << std::setw(20) << theMagneticMomentChange << G4endl;
00460   G4cout << "                :  = " << std::setw(20) 
00461          << theMagneticMomentChange*2.*theMassChange/c_squared/eplus/hbar_Planck 
00462          <<  "*[e hbar]/[2 m]" 
00463          << G4endl; 
00464   G4cout << "        Position - x (mm)   : " 
00465        << std::setw(20) << thePositionChange.x()/mm
00466        << G4endl; 
00467   G4cout << "        Position - y (mm)   : " 
00468        << std::setw(20) << thePositionChange.y()/mm
00469        << G4endl; 
00470   G4cout << "        Position - z (mm)   : " 
00471        << std::setw(20) << thePositionChange.z()/mm
00472        << G4endl;
00473   G4cout << "        Time (ns)           : " 
00474        << std::setw(20) << theTimeChange/ns
00475        << G4endl;
00476   G4cout << "        Proper Time (ns)    : " 
00477        << std::setw(20) << theProperTimeChange/ns
00478        << G4endl;
00479   G4cout << "        Momentum Direct - x : " 
00480        << std::setw(20) << theMomentumDirectionChange.x()
00481        << G4endl;
00482   G4cout << "        Momentum Direct - y : " 
00483        << std::setw(20) << theMomentumDirectionChange.y()
00484        << G4endl;
00485   G4cout << "        Momentum Direct - z : " 
00486        << std::setw(20) << theMomentumDirectionChange.z()
00487        << G4endl;
00488   G4cout << "        Kinetic Energy (MeV): " 
00489        << std::setw(20) << theEnergyChange/MeV
00490        << G4endl;
00491   G4cout << "        Velocity  (/c): " 
00492        << std::setw(20) << theVelocityChange/c_light
00493        << G4endl;
00494   G4cout << "        Polarization - x    : " 
00495        << std::setw(20) << thePolarizationChange.x()
00496        << G4endl;
00497   G4cout << "        Polarization - y    : " 
00498        << std::setw(20) << thePolarizationChange.y()
00499        << G4endl;
00500   G4cout << "        Polarization - z    : " 
00501        << std::setw(20) <<  thePolarizationChange.z()
00502        << G4endl;
00503   G4cout.precision(oldprc);
00504 }
00505 
00506 G4bool G4ParticleChange::CheckIt(const G4Track& aTrack)
00507 {
00508   G4bool    exitWithError = false;
00509   G4double  accuracy;
00510   static G4int nError = 0;
00511 #ifdef G4VERBOSE
00512   const  G4int maxError = 30;
00513 #endif
00514 
00515   // No check in case of "fStopAndKill" 
00516   if (GetTrackStatus() ==   fStopAndKill )  return G4VParticleChange::CheckIt(aTrack);
00517 
00518   // MomentumDirection should be unit vector
00519   G4bool itsOKforMomentum = true;  
00520   if ( theEnergyChange >0.) {
00521     accuracy = std::fabs(theMomentumDirectionChange.mag2()-1.0);
00522     if (accuracy > accuracyForWarning) {
00523       itsOKforMomentum = false;
00524       nError += 1;
00525       exitWithError = exitWithError || (accuracy > accuracyForException);
00526 #ifdef G4VERBOSE
00527       if (nError < maxError) {
00528         G4cout << "  G4ParticleChange::CheckIt  : ";
00529         G4cout << "the Momentum Change is not unit vector !!" 
00530                << "  Difference:  " << accuracy << G4endl;
00531         G4cout << aTrack.GetDefinition()->GetParticleName()
00532                << " E=" << aTrack.GetKineticEnergy()/MeV
00533                << " pos=" << aTrack.GetPosition().x()/m
00534                << ", " << aTrack.GetPosition().y()/m
00535                << ", " << aTrack.GetPosition().z()/m
00536                <<G4endl;
00537       }
00538 #endif
00539     }
00540   }
00541 
00542   // Both global and proper time should not go back
00543   G4bool itsOKforGlobalTime = true;  
00544   accuracy = (aTrack.GetLocalTime()- theTimeChange)/ns;
00545   if (accuracy > accuracyForWarning) {
00546     itsOKforGlobalTime = false;
00547     nError += 1;
00548     exitWithError = exitWithError || (accuracy > accuracyForException);
00549 #ifdef G4VERBOSE
00550     if (nError < maxError) {
00551       G4cout << "  G4ParticleChange::CheckIt    : ";
00552       G4cout << "the local time goes back  !!" 
00553              << "  Difference:  " << accuracy  << "[ns] " <<G4endl;
00554       G4cout << aTrack.GetDefinition()->GetParticleName()
00555              << " E=" << aTrack.GetKineticEnergy()/MeV
00556              << " pos=" << aTrack.GetPosition().x()/m
00557              << ", " << aTrack.GetPosition().y()/m
00558              << ", " << aTrack.GetPosition().z()/m
00559              << " global time=" << aTrack.GetGlobalTime()/ns
00560              << " local time=" << aTrack.GetLocalTime()/ns
00561              << " proper time=" << aTrack.GetProperTime()/ns
00562              << G4endl;
00563     }
00564 #endif
00565   }
00566 
00567   G4bool itsOKforProperTime = true;
00568   accuracy = (aTrack.GetProperTime() - theProperTimeChange )/ns;
00569   if (accuracy > accuracyForWarning) {
00570     itsOKforProperTime = false;
00571     nError += 1;
00572     exitWithError = exitWithError ||  (accuracy > accuracyForException);
00573 #ifdef G4VERBOSE
00574     if (nError < maxError) {
00575       G4cout << "  G4ParticleChange::CheckIt    : ";
00576       G4cout << "the proper time goes back  !!" 
00577              << "  Difference:  " << accuracy  << "[ns] " <<G4endl;
00578       G4cout << aTrack.GetDefinition()->GetParticleName()
00579              << " E=" << aTrack.GetKineticEnergy()/MeV
00580              << " pos=" << aTrack.GetPosition().x()/m
00581              << ", " << aTrack.GetPosition().y()/m
00582              << ", " << aTrack.GetPosition().z()/m
00583              << " global time=" << aTrack.GetGlobalTime()/ns
00584              << " local time=" << aTrack.GetLocalTime()/ns
00585              << " proper time=" << aTrack.GetProperTime()/ns
00586              <<G4endl;
00587     }
00588 #endif
00589   }
00590 
00591   // Kinetic Energy should not be negative
00592   G4bool itsOKforEnergy = true;
00593   accuracy = -1.0*theEnergyChange/MeV;
00594   if (accuracy > accuracyForWarning) {
00595     itsOKforEnergy = false;
00596     nError += 1;
00597     exitWithError = exitWithError ||   (accuracy > accuracyForException);
00598 #ifdef G4VERBOSE
00599     if (nError < maxError) {
00600       G4cout << "  G4ParticleChange::CheckIt    : ";
00601       G4cout << "the kinetic energy is negative  !!" 
00602              << "  Difference:  " << accuracy  << "[MeV] " <<G4endl;
00603       G4cout << aTrack.GetDefinition()->GetParticleName()
00604              << " E=" << aTrack.GetKineticEnergy()/MeV
00605              << " pos=" << aTrack.GetPosition().x()/m
00606              << ", " << aTrack.GetPosition().y()/m
00607              << ", " << aTrack.GetPosition().z()/m
00608              <<G4endl;
00609     }
00610 #endif
00611   }
00612 
00613   // Velocity  should not be less than c_light
00614   G4bool itsOKforVelocity = true;
00615   if (theVelocityChange < 0.) {
00616     itsOKforVelocity = false;
00617     nError += 1;
00618     exitWithError = true;
00619 #ifdef G4VERBOSE
00620     if (nError < maxError) {
00621       G4cout << "  G4ParticleChange::CheckIt    : ";
00622       G4cout << "the velocity is negative  !!" 
00623              << "  Velocity:  " << theVelocityChange/c_light  <<G4endl;
00624       G4cout << aTrack.GetDefinition()->GetParticleName()
00625              << " E=" << aTrack.GetKineticEnergy()/MeV
00626              << " pos=" << aTrack.GetPosition().x()/m
00627              << ", " << aTrack.GetPosition().y()/m
00628              << ", " << aTrack.GetPosition().z()/m
00629              <<G4endl;
00630     }
00631 #endif
00632   }
00633 
00634   accuracy = theVelocityChange/c_light - 1.0;
00635   if (accuracy > accuracyForWarning) {
00636     itsOKforVelocity = false;
00637     nError += 1;
00638     exitWithError = exitWithError ||  (accuracy > accuracyForException);
00639 #ifdef G4VERBOSE
00640     if (nError < maxError) {
00641       G4cout << "  G4ParticleChange::CheckIt    : ";
00642       G4cout << "the velocity is greater than c_light  !!" << G4endl;
00643       G4cout << "  Velocity:  " << theVelocityChange/c_light  <<G4endl;
00644       G4cout << aTrack.GetDefinition()->GetParticleName()
00645              << " E=" << aTrack.GetKineticEnergy()/MeV
00646              << " pos=" << aTrack.GetPosition().x()/m
00647              << ", " << aTrack.GetPosition().y()/m
00648              << ", " << aTrack.GetPosition().z()/m
00649              <<G4endl;
00650     }
00651 #endif
00652   }
00653 
00654   G4bool itsOK = itsOKforMomentum && itsOKforEnergy && itsOKforVelocity && itsOKforProperTime && itsOKforGlobalTime;
00655   // dump out information of this particle change
00656 #ifdef G4VERBOSE
00657   if (!itsOK) { 
00658     DumpInfo();
00659   }
00660 #endif
00661 
00662   // Exit with error
00663   if (exitWithError) {
00664     G4Exception("G4ParticleChange::CheckIt",
00665                 "TRACK003", EventMustBeAborted,
00666                 "momentum, energy, and/or time was illegal");
00667   }
00668   //correction
00669   if (!itsOKforMomentum) {
00670     G4double vmag = theMomentumDirectionChange.mag();
00671     theMomentumDirectionChange = (1./vmag)*theMomentumDirectionChange;
00672   }
00673   if (!itsOKforGlobalTime) {
00674     theTimeChange = aTrack.GetLocalTime();
00675   }
00676   if (!itsOKforProperTime) {
00677     theProperTimeChange = aTrack.GetProperTime();
00678   }
00679   if (!itsOKforEnergy) {
00680     theEnergyChange = 0.0;
00681   }
00682   if (!itsOKforVelocity) {
00683     theVelocityChange = c_light;
00684   }
00685 
00686   itsOK = (itsOK) && G4VParticleChange::CheckIt(aTrack);
00687   return itsOK;
00688 }

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