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 #include "G4ParallelWorldScoringProcess.hh"
00032
00033 #include "G4ios.hh"
00034 #include "G4SystemOfUnits.hh"
00035 #include "G4Step.hh"
00036 #include "G4Navigator.hh"
00037 #include "G4VTouchable.hh"
00038 #include "G4VPhysicalVolume.hh"
00039 #include "G4ParticleChange.hh"
00040 #include "G4PathFinder.hh"
00041 #include "G4TransportationManager.hh"
00042 #include "G4ParticleChange.hh"
00043 #include "G4StepPoint.hh"
00044 #include "G4FieldTrackUpdator.hh"
00045 #include "G4ParticleDefinition.hh"
00046
00047 #include "G4SDManager.hh"
00048 #include "G4VSensitiveDetector.hh"
00049
00050
00051
00052
00053 G4ParallelWorldScoringProcess::
00054 G4ParallelWorldScoringProcess(const G4String& processName,G4ProcessType theType)
00055 :G4VProcess(processName,theType), fGhostNavigator(0), fNavigatorID(-1), fFieldTrack('0')
00056 {
00057 pParticleChange = &aDummyParticleChange;
00058
00059 fGhostStep = new G4Step();
00060 fGhostPreStepPoint = fGhostStep->GetPreStepPoint();
00061 fGhostPostStepPoint = fGhostStep->GetPostStepPoint();
00062
00063 fTransportationManager = G4TransportationManager::GetTransportationManager();
00064 fPathFinder = G4PathFinder::GetInstance();
00065
00066 if (verboseLevel>0)
00067 {
00068 G4cout << GetProcessName() << " is created " << G4endl;
00069 }
00070 }
00071
00072
00073
00074
00075 G4ParallelWorldScoringProcess::~G4ParallelWorldScoringProcess()
00076 {
00077 delete fGhostStep;
00078 }
00079
00080
00081
00082
00083
00084
00085 void G4ParallelWorldScoringProcess::
00086 SetParallelWorld(G4String parallelWorldName)
00087 {
00088
00089
00090
00091 fGhostWorldName = parallelWorldName;
00092 fGhostWorld = fTransportationManager->GetParallelWorld(fGhostWorldName);
00093 fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00094
00095 }
00096
00097 void G4ParallelWorldScoringProcess::
00098 SetParallelWorld(G4VPhysicalVolume* parallelWorld)
00099 {
00100
00101
00102
00103 fGhostWorldName = parallelWorld->GetName();
00104 fGhostWorld = parallelWorld;
00105 fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00106
00107 }
00108
00109 G4bool G4ParallelWorldScoringProcess::
00110 IsAtRestRequired(G4ParticleDefinition* partDef)
00111 {
00112 G4int pdgCode = partDef->GetPDGEncoding();
00113 if(pdgCode==0)
00114 {
00115 G4String partName = partDef->GetParticleName();
00116 if(partName=="opticalphoton") return false;
00117 if(partName=="geantino") return false;
00118 if(partName=="chargedgeantino") return false;
00119 }
00120 else
00121 {
00122 if(pdgCode==22) return false;
00123 if(pdgCode==11) return false;
00124 if(pdgCode==2212) return false;
00125 if(pdgCode==-12) return false;
00126 if(pdgCode==12) return false;
00127 if(pdgCode==-14) return false;
00128 if(pdgCode==14) return false;
00129 if(pdgCode==-16) return false;
00130 if(pdgCode==16) return false;
00131 }
00132 return true;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 void G4ParallelWorldScoringProcess::StartTracking(G4Track* trk)
00142 {
00143
00144
00145
00146
00147 if(fGhostNavigator)
00148 { fNavigatorID = fTransportationManager->ActivateNavigator(fGhostNavigator); }
00149 else
00150 {
00151 G4Exception("G4ParallelWorldScoringProcess::StartTracking",
00152 "ProcParaWorld000",FatalException,
00153 "G4ParallelWorldScoringProcess is used for tracking without having a parallel world assigned");
00154 }
00155
00156
00157
00158
00159
00160
00161 fPathFinder->PrepareNewTrack(trk->GetPosition(),trk->GetMomentumDirection());
00162
00163
00164
00165
00166
00167 fOldGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00168 fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00169 fNewGhostTouchable = fOldGhostTouchable;
00170 fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00171
00172
00173 fGhostSafety = -1.;
00174 fOnBoundary = false;
00175 fGhostPreStepPoint->SetStepStatus(fUndefined);
00176 fGhostPostStepPoint->SetStepStatus(fUndefined);
00177 }
00178
00179
00180
00181
00182
00183
00184 G4double
00185 G4ParallelWorldScoringProcess::AtRestGetPhysicalInteractionLength(
00186 const G4Track& ,
00187 G4ForceCondition* condition)
00188 {
00189 *condition = Forced;
00190 return DBL_MAX;
00191 }
00192
00193
00194
00195
00196
00197
00198 G4VParticleChange* G4ParallelWorldScoringProcess::AtRestDoIt(
00199 const G4Track& track,
00200 const G4Step& step)
00201 {
00202 fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
00203 G4VSensitiveDetector* aSD = 0;
00204 if(fOldGhostTouchable->GetVolume())
00205 { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
00206 fOnBoundary = false;
00207 CopyStep(step);
00208 fGhostPreStepPoint->SetSensitiveDetector(aSD);
00209
00210 fNewGhostTouchable = fOldGhostTouchable;
00211
00212 fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00213 fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00214 if(fNewGhostTouchable->GetVolume())
00215 {
00216 fGhostPostStepPoint->SetSensitiveDetector(
00217 fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
00218 }
00219 else
00220 { fGhostPostStepPoint->SetSensitiveDetector(0); }
00221
00222 if (verboseLevel>1) Verbose(step);
00223
00224 G4VSensitiveDetector* sd = fGhostPreStepPoint->GetSensitiveDetector();
00225 if(sd)
00226 {
00227 sd->Hit(fGhostStep);
00228 }
00229
00230 pParticleChange->Initialize(track);
00231 return pParticleChange;
00232 }
00233
00234
00235
00236
00237
00238
00239 G4double
00240 G4ParallelWorldScoringProcess::PostStepGetPhysicalInteractionLength(
00241 const G4Track& ,
00242 G4double ,
00243 G4ForceCondition* condition)
00244 {
00245
00246 *condition = StronglyForced;
00247 return DBL_MAX;
00248 }
00249
00250
00251
00252
00253
00254
00255 G4VParticleChange* G4ParallelWorldScoringProcess::PostStepDoIt(
00256 const G4Track& track,
00257 const G4Step& step)
00258 {
00259 fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
00260 G4VSensitiveDetector* aSD = 0;
00261 if(fOldGhostTouchable->GetVolume())
00262 { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
00263 CopyStep(step);
00264 fGhostPreStepPoint->SetSensitiveDetector(aSD);
00265
00266
00267
00268
00269
00270
00271
00272
00273 if(fOnBoundary)
00274 {
00275
00276
00277
00278
00279
00280 fNewGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00281
00282 }
00283 else
00284 {
00285
00286
00287
00288
00289
00290
00291
00292 fNewGhostTouchable = fOldGhostTouchable;
00293 }
00294
00295 fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00296 fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00297
00298 if(fNewGhostTouchable->GetVolume())
00299 {
00300 fGhostPostStepPoint->SetSensitiveDetector(
00301 fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
00302 }
00303 else
00304 { fGhostPostStepPoint->SetSensitiveDetector(0); }
00305
00306 if (verboseLevel>1) Verbose(step);
00307
00308 G4VSensitiveDetector* sd = fGhostPreStepPoint->GetSensitiveDetector();
00309 if(sd)
00310 {
00311 sd->Hit(fGhostStep);
00312 }
00313
00314 pParticleChange->Initialize(track);
00315 return pParticleChange;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 G4double G4ParallelWorldScoringProcess::AlongStepGetPhysicalInteractionLength(
00325 const G4Track& track, G4double previousStepSize, G4double currentMinimumStep,
00326 G4double& proposedSafety, G4GPILSelection* selection)
00327 {
00328 static G4FieldTrack endTrack('0');
00329 static ELimited eLimited;
00330
00331 *selection = NotCandidateForSelection;
00332 G4double returnedStep = DBL_MAX;
00333
00334 if (previousStepSize > 0.)
00335 { fGhostSafety -= previousStepSize; }
00336
00337
00338 if (fGhostSafety < 0.) fGhostSafety = 0.0;
00339
00340
00341
00342
00343 if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
00344 {
00345
00346 returnedStep = currentMinimumStep;
00347 fOnBoundary = false;
00348 proposedSafety = fGhostSafety - currentMinimumStep;
00349 }
00350 else
00351 {
00352 G4FieldTrackUpdator::Update(&fFieldTrack,&track);
00353
00354
00355
00356 returnedStep
00357 = fPathFinder->ComputeStep(fFieldTrack,currentMinimumStep,fNavigatorID,
00358 track.GetCurrentStepNumber(),fGhostSafety,eLimited,
00359 endTrack,track.GetVolume());
00360
00361 if(eLimited == kDoNot)
00362 {
00363
00364 fOnBoundary = false;
00365 fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition());
00366 }
00367 else
00368 {
00369
00370 fOnBoundary = true;
00371
00372 }
00373 proposedSafety = fGhostSafety;
00374 if(eLimited == kUnique || eLimited == kSharedOther) {
00375 *selection = CandidateForSelection;
00376 }else if (eLimited == kSharedTransport) {
00377 returnedStep *= (1.0 + 1.0e-9);
00378
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387 return returnedStep;
00388 }
00389
00390 G4VParticleChange* G4ParallelWorldScoringProcess::AlongStepDoIt(
00391 const G4Track& track, const G4Step& )
00392 {
00393
00394
00395 pParticleChange->Initialize(track);
00396 return pParticleChange;
00397 }
00398
00399
00400 void G4ParallelWorldScoringProcess::CopyStep(const G4Step & step)
00401 {
00402 G4StepStatus prevStat = fGhostPostStepPoint->GetStepStatus();
00403
00404 fGhostStep->SetTrack(step.GetTrack());
00405 fGhostStep->SetStepLength(step.GetStepLength());
00406 fGhostStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
00407 fGhostStep->SetNonIonizingEnergyDeposit(step.GetNonIonizingEnergyDeposit());
00408 fGhostStep->SetControlFlag(step.GetControlFlag());
00409
00410 *fGhostPreStepPoint = *(step.GetPreStepPoint());
00411 *fGhostPostStepPoint = *(step.GetPostStepPoint());
00412
00413
00414
00415
00416 fGhostPreStepPoint->SetStepStatus(prevStat);
00417 if(fOnBoundary)
00418 { fGhostPostStepPoint->SetStepStatus(fGeomBoundary); }
00419 else if(fGhostPostStepPoint->GetStepStatus()==fGeomBoundary)
00420 { fGhostPostStepPoint->SetStepStatus(fPostStepDoItProc); }
00421
00422 }
00423
00424 void G4ParallelWorldScoringProcess::Verbose(const G4Step& step) const
00425 {
00426 G4cout << "In mass geometry ------------------------------------------------" << G4endl;
00427 G4cout << " StepLength : " << step.GetStepLength()/mm << " TotalEnergyDeposit : "
00428 << step.GetTotalEnergyDeposit()/MeV << G4endl;
00429 G4cout << " PreStepPoint : "
00430 << step.GetPreStepPoint()->GetPhysicalVolume()->GetName() << " - ";
00431 if(step.GetPreStepPoint()->GetProcessDefinedStep())
00432 { G4cout << step.GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
00433 else
00434 { G4cout << "NoProcessAssigned"; }
00435 G4cout << G4endl;
00436 G4cout << " " << step.GetPreStepPoint()->GetPosition() << G4endl;
00437 G4cout << " PostStepPoint : ";
00438 if(step.GetPostStepPoint()->GetPhysicalVolume())
00439 { G4cout << step.GetPostStepPoint()->GetPhysicalVolume()->GetName(); }
00440 else
00441 { G4cout << "OutOfWorld"; }
00442 G4cout << " - ";
00443 if(step.GetPostStepPoint()->GetProcessDefinedStep())
00444 { G4cout << step.GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
00445 else
00446 { G4cout << "NoProcessAssigned"; }
00447 G4cout << G4endl;
00448 G4cout << " " << step.GetPostStepPoint()->GetPosition() << G4endl;
00449
00450 G4cout << "In ghost geometry ------------------------------------------------" << G4endl;
00451 G4cout << " StepLength : " << fGhostStep->GetStepLength()/mm
00452 << " TotalEnergyDeposit : "
00453 << fGhostStep->GetTotalEnergyDeposit()/MeV << G4endl;
00454 G4cout << " PreStepPoint : "
00455 << fGhostStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() << " ["
00456 << fGhostStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber()
00457 << " ]" << " - ";
00458 if(fGhostStep->GetPreStepPoint()->GetProcessDefinedStep())
00459 { G4cout << fGhostStep->GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
00460 else
00461 { G4cout << "NoProcessAssigned"; }
00462 G4cout << G4endl;
00463 G4cout << " " << fGhostStep->GetPreStepPoint()->GetPosition() << G4endl;
00464 G4cout << " PostStepPoint : ";
00465 if(fGhostStep->GetPostStepPoint()->GetPhysicalVolume())
00466 {
00467 G4cout << fGhostStep->GetPostStepPoint()->GetPhysicalVolume()->GetName() << " ["
00468 << fGhostStep->GetPostStepPoint()->GetTouchable()->GetReplicaNumber()
00469 << " ]";
00470 }
00471 else
00472 { G4cout << "OutOfWorld"; }
00473 G4cout << " - ";
00474 if(fGhostStep->GetPostStepPoint()->GetProcessDefinedStep())
00475 { G4cout << fGhostStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
00476 else
00477 { G4cout << "NoProcessAssigned"; }
00478 G4cout << G4endl;
00479 G4cout << " " << fGhostStep->GetPostStepPoint()->GetPosition() << " == "
00480 << fGhostStep->GetTrack()->GetMomentumDirection()
00481 << G4endl;
00482
00483 }
00484