00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
00056 fFastTrack=&fastTrack;
00057
00058
00059 const G4Track& currentTrack = *(fFastTrack->GetPrimaryTrack());
00060
00061
00062 G4VParticleChange::Initialize(currentTrack);
00063
00064
00065 const G4DynamicParticle* pParticle = currentTrack.GetDynamicParticle();
00066 theEnergyChange = pParticle->GetKineticEnergy();
00067 theMomentumChange = pParticle->GetMomentumDirection();
00068 thePolarizationChange = pParticle->GetPolarization();
00069 theProperTimeChange = pParticle->GetProperTime();
00070
00071
00072 thePositionChange = currentTrack.GetPosition();
00073 theTimeChange = currentTrack.GetGlobalTime();
00074
00075
00076 theSteppingControlFlag = AvoidHitInvocation;
00077
00078
00079 theWeightChange = currentTrack.GetWeight();
00080 }
00081
00082
00083
00084
00085
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
00102
00103 G4ThreeVector globalPosition = position;
00104 if (localCoordinates)
00105 globalPosition = fFastTrack->GetInverseAffineTransformation()->
00106 TransformPoint(position);
00107
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
00128
00129 G4ThreeVector globalMomentum = momentum;
00130 if (localCoordinates)
00131 globalMomentum = fFastTrack->GetInverseAffineTransformation()->
00132 TransformAxis(momentum);
00133
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
00155 G4ThreeVector globalDirection = direction;
00156 if (localCoordinates)
00157 globalDirection =fFastTrack->GetInverseAffineTransformation()->
00158 TransformAxis(direction);
00159
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
00182 G4ThreeVector globalPolarization(polarization);
00183 if (localCoordinates)
00184 globalPolarization = fFastTrack->GetInverseAffineTransformation()->
00185 TransformAxis(globalPolarization);
00186
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
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
00231
00232
00233
00234
00235 G4DynamicParticle* globalDynamics =
00236 new G4DynamicParticle(dynamics);
00237 G4ThreeVector globalPosition(position);
00238
00239
00240
00241
00242 if (localCoordinates)
00243 {
00244
00245 globalDynamics->SetMomentumDirection(fFastTrack->
00246 GetInverseAffineTransformation()->
00247 TransformAxis(globalDynamics->
00248 GetMomentumDirection()));
00249
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
00260 globalPosition = fFastTrack->GetInverseAffineTransformation()->
00261 TransformPoint(globalPosition);
00262 }
00263
00264
00265
00266
00267 G4Track* secondary = new G4Track(
00268 globalDynamics,
00269 time,
00270 globalPosition
00271 );
00272
00273
00274
00275
00276 AddSecondary(secondary);
00277
00278
00279
00280
00281 return secondary;
00282 }
00283
00284
00285
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
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
00360
00361
00362 G4Step* G4FastStep::UpdateStepForPostStep(G4Step* pStep)
00363 {
00364
00365
00366
00367
00368
00369
00370
00371 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
00372 G4Track* aTrack = pStep->GetTrack();
00373
00374
00375
00376 pPostStepPoint->SetMomentumDirection(theMomentumChange);
00377 pPostStepPoint->SetKineticEnergy( theEnergyChange );
00378
00379
00380 pPostStepPoint->SetPolarization( thePolarizationChange );
00381
00382
00383 pPostStepPoint->SetPosition( thePositionChange );
00384 pPostStepPoint->SetGlobalTime( theTimeChange );
00385 pPostStepPoint->AddLocalTime( theTimeChange
00386 - aTrack->GetGlobalTime());
00387 pPostStepPoint->SetProperTime( theProperTimeChange );
00388
00389
00390 pPostStepPoint->SetWeight( theWeightChange );
00391
00392 if (debugFlag) CheckIt(*aTrack);
00393
00394
00395
00396 return UpdateStepInfo(pStep);
00397 }
00398
00399 G4Step* G4FastStep::UpdateStepForAtRest(G4Step* pStep)
00400 {
00401
00402
00403
00404 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
00405 G4Track* aTrack = pStep->GetTrack();
00406
00407
00408
00409 pPostStepPoint->SetMomentumDirection(theMomentumChange);
00410 pPostStepPoint->SetKineticEnergy( theEnergyChange );
00411
00412
00413 pPostStepPoint->SetPolarization( thePolarizationChange );
00414
00415
00416 pPostStepPoint->SetPosition( thePositionChange );
00417 pPostStepPoint->SetGlobalTime( theTimeChange );
00418 pPostStepPoint->AddLocalTime( theTimeChange
00419 - aTrack->GetGlobalTime());
00420 pPostStepPoint->SetProperTime( theProperTimeChange );
00421
00422
00423 pPostStepPoint->SetWeight( theWeightChange );
00424
00425 if (debugFlag) CheckIt(*aTrack);
00426
00427
00428 return UpdateStepInfo(pStep);
00429 }
00430
00431
00432
00433
00434
00435 void G4FastStep::DumpInfo() const
00436 {
00437
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
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 G4bool itsOK = true;
00500 G4bool exitWithError = false;
00501 G4double accuracy;
00502
00503
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
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
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 }