/home/cern/BDSIM_new/src/BDSConvParticleChange.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 3.11.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 //
00007 // ********************************************************************
00008 // * DISCLAIMER                                                       *
00009 // *                                                                  *
00010 // * The following disclaimer summarizes all the specific disclaimers *
00011 // * of contributors to this software. The specific disclaimers,which *
00012 // * govern, are listed with their locations in:                      *
00013 // *   http://cern.ch/geant4/license                                  *
00014 // *                                                                  *
00015 // * Neither the authors of this software system, nor their employing *
00016 // * institutes,nor the agencies providing financial support for this *
00017 // * work  make  any representation or  warranty, express or implied, *
00018 // * regarding  this  software system or assume any liability for its *
00019 // * use.                                                             *
00020 // *                                                                  *
00021 // * This  code  implementation is the  intellectual property  of the *
00022 // * GEANT4 collaboration.                                            *
00023 // * By copying,  distributing  or modifying the Program (or any work *
00024 // * based  on  the Program)  you indicate  your  acceptance of  this *
00025 // * statement, and all its terms.                                    *
00026 // ********************************************************************
00027 //
00028 //
00029 // $Id: BDSConvParticleChange.cc,v 1.2 2007/05/10 16:23:22 malton Exp $
00030 // GEANT4 tag $Name:  $
00031 //
00032 // 
00033 // --------------------------------------------------------------
00034 //      GEANT 4 class implementation file 
00035 //
00036 //      
00037 //      
00038 // ------------------------------------------------------------
00039 //   Implemented for the new scheme                 23 Mar. 1998  H.Kurahige
00040 //   Change default debug flag to false             10 May. 1998  H.Kurahige
00041 //   Add Track weight                               12 Nov. 1998  H.Kurashige
00042 //   Activate CheckIt method for VERBOSE mode       14 Dec. 1998 H.Kurashige
00043 //   Modified CheckIt method for time                9 Feb. 1999 H.Kurashige
00044 // --------------------------------------------------------------
00045 
00046 #include "BDSConvParticleChange.hh"
00047 #include "G4Track.hh"
00048 #include "G4Step.hh"
00049 #include "G4TrackFastVector.hh"
00050 #include "G4DynamicParticle.hh"
00051 
00052 
00053 BDSConvParticleChange::BDSConvParticleChange():G4VParticleChange()
00054 {
00055   // gab set flag so that secondaries can have different weights from
00056   // their parents
00057   G4VParticleChange::SetSecondaryWeightByProcess(true);
00058 
00059 }
00060 
00061 BDSConvParticleChange::~BDSConvParticleChange() 
00062 {
00063 #ifdef G4VERBOSE
00064   if (verboseLevel>2) {
00065     G4cout << "BDSConvParticleChange::~BDSConvParticleChange() " << G4endl;
00066   }
00067 #endif
00068 }
00069 
00070 // copy constructor
00071 BDSConvParticleChange::BDSConvParticleChange(const BDSConvParticleChange &right): G4VParticleChange(right)
00072 {
00073    if (verboseLevel>1) {
00074     G4cout << "BDSConvParticleChange::  copy constructor is called " << G4endl;
00075    }
00076    theMomentumDirectionChange = right.theMomentumDirectionChange;
00077    thePolarizationChange = right.thePolarizationChange;
00078    thePositionChange = right.thePositionChange;
00079    theTimeChange = right.theTimeChange;
00080    theEnergyChange = right.theEnergyChange;
00081    theMassChange = right.theMassChange;
00082    theChargeChange = right.theChargeChange;
00083    theWeightChange = right.theWeightChange;
00084    theProperTimeChange = right.theProperTimeChange;
00085 }
00086 
00087 // assignemnt operator
00088 BDSConvParticleChange & BDSConvParticleChange::operator=(const BDSConvParticleChange &right)
00089 {
00090    if (verboseLevel>1) {
00091     G4cout << "BDSConvParticleChange:: assignment operator is called " << G4endl;
00092    }
00093    if (this != &right)
00094    {
00095       theListOfSecondaries = right.theListOfSecondaries;
00096       theSizeOftheListOfSecondaries = right.theSizeOftheListOfSecondaries;
00097       theNumberOfSecondaries = right.theNumberOfSecondaries;
00098       theStatusChange = right.theStatusChange;
00099 
00100       theMomentumDirectionChange = right.theMomentumDirectionChange;
00101       thePolarizationChange = right.thePolarizationChange;
00102       thePositionChange = right.thePositionChange;
00103       theTimeChange = right.theTimeChange;
00104       theEnergyChange = right.theEnergyChange;
00105       theMassChange = right.theMassChange;
00106       theChargeChange = right.theChargeChange;
00107       theWeightChange = right.theWeightChange;
00108 
00109       theTrueStepLength = right.theTrueStepLength;
00110       theLocalEnergyDeposit = right.theLocalEnergyDeposit;
00111       theSteppingControlFlag = right.theSteppingControlFlag;
00112    }
00113    return *this;
00114 }
00115 
00116 G4bool BDSConvParticleChange::operator==(const BDSConvParticleChange &right) const
00117 {
00118    return ((G4VParticleChange *)this == (G4VParticleChange *) &right);
00119 }
00120 
00121 G4bool BDSConvParticleChange::operator!=(const BDSConvParticleChange &right) const
00122 {
00123    return ((G4VParticleChange *)this != (G4VParticleChange *) &right);
00124 }
00125 
00126 
00127 //----------------------------------------------------------------
00128 // methods for handling secondaries 
00129 //
00130 
00131 void BDSConvParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00132                                     G4bool   IsGoodForTracking    )
00133 {
00134   //  create track
00135   G4Track* aTrack = new G4Track(aParticle, theTimeChange, thePositionChange);
00136   // set weight:
00137   if(abs(aParticle->GetDefinition()->GetPDGEncoding())==13)
00138     aTrack->SetWeight(theMuonWeight);
00139 
00140   // set IsGoodGorTrackingFlag
00141   if (IsGoodForTracking) aTrack->SetGoodForTrackingFlag();
00142 
00143   //   Touchable handle is copied to keep the pointer
00144   aTrack->SetTouchableHandle(theCurrentTrack->GetTouchableHandle());
00145  
00146  //  add a secondary
00147   G4VParticleChange::AddSecondary(aTrack);
00148 }
00149 
00150 void BDSConvParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00151                                     G4ThreeVector      newPosition,
00152                                     G4bool   IsGoodForTracking    )
00153 {
00154   //  create track
00155   G4Track*  aTrack = new G4Track(aParticle, theTimeChange, newPosition);
00156 
00157   // set IsGoodGorTrackingFlag
00158   if (IsGoodForTracking) aTrack->SetGoodForTrackingFlag();
00159 
00160   //   Touchable is a temporary object, so you cannot keep the pointer
00161   aTrack->SetTouchableHandle((G4VTouchable*)0);
00162 
00163   //  add a secondary
00164   G4VParticleChange::AddSecondary(aTrack);
00165 }
00166 
00167 void BDSConvParticleChange::AddSecondary(G4DynamicParticle* aParticle, 
00168                                     G4double           newTime,
00169                                     G4bool   IsGoodForTracking    )
00170 {
00171   //  create track
00172   G4Track*  aTrack = new G4Track(aParticle, newTime, 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 BDSConvParticleChange::AddSecondary(G4Track* aTrack)
00185 {
00186   //  add a secondary
00187   G4VParticleChange::AddSecondary(aTrack);
00188 }
00189 
00190 //----------------------------------------------------------------
00191 // functions for Initialization
00192 //
00193 
00194 void BDSConvParticleChange::Initialize(const G4Track& track)
00195 {
00196   // use base class's method at first
00197   G4VParticleChange::Initialize(track);
00198   theCurrentTrack= &track;
00199 
00200   // set Energy/Momentum etc. equal to those of the parent particle
00201   const G4DynamicParticle*  pParticle = track.GetDynamicParticle();
00202   theEnergyChange          = pParticle->GetKineticEnergy();
00203   theMomentumDirectionChange        = pParticle->GetMomentumDirection();
00204   thePolarizationChange    = pParticle->GetPolarization();
00205   theProperTimeChange      = pParticle->GetProperTime();
00206 
00207   // Set mass/charge of DynamicParticle
00208   theMassChange = pParticle->GetMass();
00209   theChargeChange = pParticle->GetCharge();
00210 
00211   // set Position/Time etc. equal to those of the parent track
00212   thePositionChange      = track.GetPosition();
00213   theTimeChange          = track.GetGlobalTime();
00214 
00215   theWeightChange        = track.GetWeight();
00216 }
00217 
00218 //----------------------------------------------------------------
00219 // methods for updating G4Step 
00220 //
00221 
00222 G4Step* BDSConvParticleChange::UpdateStepForAlongStep(G4Step* pStep)
00223 {
00224   // A physics process always calculates the final state of the
00225   // particle relative to the initial state at the beginning
00226   // of the Step, i.e., based on information of G4Track (or
00227   // equivalently the PreStepPoint). 
00228   // So, the differences (delta) between these two states have to be
00229   // calculated and be accumulated in PostStepPoint. 
00230   
00231   // Take note that the return type of GetMomentumDirectionChange is a
00232   // pointer to G4ParticleMometum. Also it is a normalized 
00233   // momentum vector.
00234 
00235   G4StepPoint* pPreStepPoint  = pStep->GetPreStepPoint(); 
00236   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00237   G4Track*     aTrack  = pStep->GetTrack();
00238   G4double     mass = theMassChange;
00239 
00240   // Set Mass/Charge
00241   pPostStepPoint->SetMass(theMassChange);
00242   pPostStepPoint->SetCharge(theChargeChange);  
00243  
00244   // calculate new kinetic energy
00245   G4double energy = pPostStepPoint->GetKineticEnergy() 
00246                     + (theEnergyChange - pPreStepPoint->GetKineticEnergy()); 
00247 
00248   // update kinetic energy and momentum direction
00249   if (energy > 0.0) {
00250     // calculate new momentum
00251     G4ThreeVector pMomentum =  pPostStepPoint->GetMomentum() 
00252                 + ( CalcMomentum(theEnergyChange, theMomentumDirectionChange, mass)
00253                     - pPreStepPoint->GetMomentum());
00254     G4double      tMomentum = pMomentum.mag();
00255     G4ThreeVector direction(1.0,0.0,0.0); 
00256     if( tMomentum > 0. ){
00257       G4double  inv_Momentum= 1.0 / tMomentum; 
00258       direction= pMomentum * inv_Momentum;
00259     }
00260     pPostStepPoint->SetMomentumDirection(direction);
00261     pPostStepPoint->SetKineticEnergy( energy );
00262   } else {
00263     // stop case
00264     pPostStepPoint->SetMomentumDirection(G4ThreeVector(1., 0., 0.));
00265     pPostStepPoint->SetKineticEnergy(0.0);
00266   }
00267 
00268   // update polarization
00269   pPostStepPoint->AddPolarization( thePolarizationChange
00270                                    - pPreStepPoint->GetPolarization());
00271       
00272   // update position and time
00273   pPostStepPoint->AddPosition( thePositionChange 
00274                                - pPreStepPoint->GetPosition() );
00275   pPostStepPoint->AddGlobalTime( theTimeChange
00276                                  - pPreStepPoint->GetGlobalTime());
00277   pPostStepPoint->AddLocalTime( theTimeChange 
00278                                  - pPreStepPoint->GetGlobalTime()); 
00279   pPostStepPoint->AddProperTime( theProperTimeChange 
00280                                  - pPreStepPoint->GetProperTime());
00281 
00282   G4double newWeight= theWeightChange/(pPreStepPoint->GetWeight())*(pPostStepPoint->GetWeight());
00283   pPostStepPoint->SetWeight( newWeight );
00284 
00285 
00286 #ifdef G4VERBOSE
00287   if (debugFlag) CheckIt(*aTrack);
00288 #endif
00289 
00290   //  Update the G4Step specific attributes 
00291   return UpdateStepInfo(pStep);
00292 }
00293 
00294 G4Step* BDSConvParticleChange::UpdateStepForPostStep(G4Step* pStep)
00295 { 
00296   // A physics process always calculates the final state of the particle
00297 
00298   // Take note that the return type of GetMomentumChange is a
00299   // pointer to G4ParticleMometum. Also it is a normalized 
00300   // momentum vector.
00301 
00302   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00303   G4Track*     aTrack  = pStep->GetTrack();
00304 
00305   // Set Mass/Charge
00306   pPostStepPoint->SetMass(theMassChange);
00307   pPostStepPoint->SetCharge(theChargeChange);  
00308  
00309   // update kinetic energy and momentum direction
00310   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
00311   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00312 
00313    // update polarization
00314   pPostStepPoint->SetPolarization( thePolarizationChange );
00315       
00316   // update position and time
00317   pPostStepPoint->SetPosition( thePositionChange  );
00318   pPostStepPoint->SetGlobalTime( theTimeChange  );
00319   pPostStepPoint->AddLocalTime( theTimeChange 
00320                                  - aTrack->GetGlobalTime());
00321   pPostStepPoint->SetProperTime( theProperTimeChange  );
00322 
00323   // update weight
00324   if(abs(aTrack->GetDynamicParticle()->GetDefinition()->GetPDGEncoding())==13)
00325     {
00326       pPostStepPoint->SetWeight( theMuonWeight );
00327     }
00328   else
00329     pPostStepPoint->SetWeight( theWeightChange );
00330 
00331 #ifdef G4VERBOSE
00332   if (debugFlag) CheckIt(*aTrack);
00333 #endif
00334 
00335   //  Update the G4Step specific attributes 
00336   return UpdateStepInfo(pStep);
00337 }
00338 
00339 
00340 G4Step* BDSConvParticleChange::UpdateStepForAtRest(G4Step* pStep)
00341 { 
00342   // A physics process always calculates the final state of the particle
00343 
00344   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint(); 
00345   G4Track*     aTrack  = pStep->GetTrack();
00346 
00347   // Set Mass/Charge
00348   pPostStepPoint->SetMass(theMassChange);
00349   pPostStepPoint->SetCharge(theChargeChange);  
00350  
00351   // update kinetic energy and momentum direction
00352   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
00353   pPostStepPoint->SetKineticEnergy( theEnergyChange );
00354 
00355   // update polarization
00356   pPostStepPoint->SetPolarization( thePolarizationChange );
00357       
00358   // update position and time
00359   pPostStepPoint->SetPosition( thePositionChange  );
00360   pPostStepPoint->SetGlobalTime( theTimeChange  );
00361   pPostStepPoint->AddLocalTime( theTimeChange 
00362                                  - aTrack->GetGlobalTime());
00363   pPostStepPoint->SetProperTime( theProperTimeChange  );
00364 
00365   // update weight 
00366   pPostStepPoint->SetWeight( theWeightChange );
00367 
00368 #ifdef G4VERBOSE
00369   if (debugFlag) CheckIt(*aTrack);
00370 #endif
00371 
00372   //  Update the G4Step specific attributes 
00373   return UpdateStepInfo(pStep);
00374 }
00375 
00376 //----------------------------------------------------------------
00377 // methods for printing messages  
00378 //
00379 
00380 void BDSConvParticleChange::DumpInfo() const
00381 {
00382 // use base-class DumpInfo
00383   G4VParticleChange::DumpInfo();
00384 
00385   G4cout.precision(3);
00386 
00387   G4cout << "        Mass (GeV)   : " 
00388        << std::setw(20) << theMassChange/GeV
00389        << G4endl; 
00390   G4cout << "        Charge (eplus)   : " 
00391        << std::setw(20) << theChargeChange/eplus
00392        << G4endl; 
00393   G4cout << "        Position - x (mm)   : " 
00394        << std::setw(20) << thePositionChange.x()/mm
00395        << G4endl; 
00396   G4cout << "        Position - y (mm)   : " 
00397        << std::setw(20) << thePositionChange.y()/mm
00398        << G4endl; 
00399   G4cout << "        Position - z (mm)   : " 
00400        << std::setw(20) << thePositionChange.z()/mm
00401        << G4endl;
00402   G4cout << "        Time (ns)           : " 
00403        << std::setw(20) << theTimeChange/ns
00404        << G4endl;
00405   G4cout << "        Proper Time (ns)    : " 
00406        << std::setw(20) << theProperTimeChange/ns
00407        << G4endl;
00408   G4cout << "        Momentum Direct - x : " 
00409        << std::setw(20) << theMomentumDirectionChange.x()
00410        << G4endl;
00411   G4cout << "        Momentum Direct - y : " 
00412        << std::setw(20) << theMomentumDirectionChange.y()
00413        << G4endl;
00414   G4cout << "        Momentum Direct - z : " 
00415        << std::setw(20) << theMomentumDirectionChange.z()
00416        << G4endl;
00417   G4cout << "        Kinetic Energy (MeV): " 
00418        << std::setw(20) << theEnergyChange/MeV
00419        << G4endl;
00420   G4cout << "        Polarization - x    : " 
00421        << std::setw(20) << thePolarizationChange.x()
00422        << G4endl;
00423   G4cout << "        Polarization - y    : " 
00424        << std::setw(20) << thePolarizationChange.y()
00425        << G4endl;
00426   G4cout << "        Polarization - z    : " 
00427        << std::setw(20) <<  thePolarizationChange.z()
00428        << G4endl;
00429   G4cout << "        Track Weight      : " 
00430          << std::setw(20) <<  theWeightChange
00431          << G4endl;     
00432 }
00433 
00434 G4bool BDSConvParticleChange::CheckIt(const G4Track& aTrack)
00435 {
00436   G4bool    exitWithError = false;
00437   G4double  accuracy;
00438 
00439   // No check in case of "fStopAndKill" 
00440   //if (GetStatusChange() ==   fStopAndKill )  {
00441   //  return G4VParticleChange::CheckIt(aTrack);
00442   //}
00443 
00444   // MomentumDirection should be unit vector
00445   G4bool itsOKforMomentum = true;  
00446   if ( theEnergyChange >0.) {
00447     accuracy = fabs(theMomentumDirectionChange.mag2()-1.0);
00448     if (accuracy > accuracyForWarning) {
00449       G4cout << "  BDSConvParticleChange::CheckIt  : ";
00450       G4cout << "the Momentum Change is not unit vector !!" << G4endl;
00451       G4cout << "  Difference:  " << accuracy << G4endl;
00452       itsOKforMomentum = false;
00453       if (accuracy > accuracyForException) exitWithError = true;
00454     }
00455   }
00456 
00457   // Both global and proper time should not go back
00458   G4bool itsOKforGlobalTime = true;  
00459   accuracy = (aTrack.GetGlobalTime()- theTimeChange)/ns;
00460   if (accuracy > accuracyForWarning) {
00461     G4cout << "  BDSConvParticleChange::CheckIt    : ";
00462     G4cout << "the global time goes back  !!" << G4endl;
00463     G4cout << "  Difference:  " << accuracy  << "[ns] " <<G4endl;
00464     itsOKforGlobalTime = false;
00465     if (accuracy > accuracyForException) exitWithError = true;
00466   }
00467 
00468   G4bool itsOKforProperTime = true;
00469   accuracy = (aTrack.GetProperTime() - theProperTimeChange )/ns;
00470   if (accuracy > accuracyForWarning) {
00471     G4cout << "  BDSConvParticleChange::CheckIt    : ";
00472     G4cout << "the proper time goes back  !!" << G4endl;
00473     G4cout << "  Difference:  " << accuracy  << "[ns] " <<G4endl;
00474     itsOKforProperTime = false;
00475     if (accuracy > accuracyForException) exitWithError = true;
00476   }
00477 
00478   // Kinetic Energy should not be negative
00479   G4bool itsOKforEnergy = true;
00480   accuracy = -1.0*theEnergyChange/MeV;
00481   if (accuracy > accuracyForWarning) {
00482     G4cout << "  BDSConvParticleChange::CheckIt    : ";
00483     G4cout << "the kinetic energy is negative  !!" << G4endl;
00484     G4cout << "  Difference:  " << accuracy  << "[MeV] " <<G4endl;
00485     itsOKforEnergy = false;
00486     if (accuracy > accuracyForException) exitWithError = true;
00487   }
00488 
00489   G4bool itsOK = itsOKforMomentum && itsOKforEnergy && itsOKforProperTime && itsOKforGlobalTime;
00490   // dump out information of this particle change
00491   if (!itsOK) { 
00492     G4cout << " BDSConvParticleChange::CheckIt " <<G4endl;
00493     DumpInfo();
00494   }
00495 
00496   // Exit with error
00497   if (exitWithError) G4Exception("BDSConvParticleChange::CheckIt");
00498 
00499   //correction
00500   if (!itsOKforMomentum) {
00501     G4double vmag = theMomentumDirectionChange.mag();
00502     theMomentumDirectionChange = (1./vmag)*theMomentumDirectionChange;
00503   }
00504   if (!itsOKforGlobalTime) {
00505     theTimeChange = aTrack.GetGlobalTime();
00506   }
00507   if (!itsOKforProperTime) {
00508     theProperTimeChange = aTrack.GetProperTime();
00509   }
00510   if (!itsOKforEnergy) {
00511     theEnergyChange = 0.0;
00512   }
00513 
00514   itsOK = (itsOK) && G4VParticleChange::CheckIt(aTrack);
00515   return itsOK;
00516 }
00517 
00518 
00519 

Generated on Wed Mar 5 17:25:22 2008 for BDSIM by  doxygen 1.5.3