Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ITStepProcessor2.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: G4ITStepProcessor2.cc 64057 2012-10-30 15:04:49Z gcosmo $
27 //
28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
29 //
30 // History:
31 // -----------
32 // 10 Oct 2011 M.Karamitros created
33 //
34 // -------------------------------------------------------------------
35 
36 #include "G4ITStepProcessor.hh"
37 #include "G4LossTableManager.hh"
38 #include "G4EnergyLossTables.hh"
39 #include "G4ProductionCuts.hh"
40 #include "G4ProductionCutsTable.hh"
41 #include "G4VITProcess.hh"
42 #include "G4TrackingInformation.hh"
43 #include "G4IT.hh"
44 #include "G4ITTrackingManager.hh"
45 #include "G4ITTransportation.hh"
46 
47 #include "G4ITNavigator.hh" // Include from 'geometry'
48 //#include "G4Navigator.hh" // Include from 'geometry'
49 
51 {
52  // Now Store the secondaries from ParticleChange to SecondaryList
53  G4Track* tempSecondaryTrack;
54 
55  for(G4int DSecLoop=0 ;
56  DSecLoop<fpParticleChange->GetNumberOfSecondaries() ;
57  DSecLoop++)
58  {
59  tempSecondaryTrack = fpParticleChange->GetSecondary(DSecLoop);
60 
61  if(tempSecondaryTrack->GetDefinition()->GetApplyCutsFlag())
62  {
63  ApplyProductionCut(tempSecondaryTrack);
64  }
65 
66  // Set parentID
67  tempSecondaryTrack->SetParentID( fpTrack->GetTrackID() );
68 
69  // Set the process pointer which created this track
70  tempSecondaryTrack->SetCreatorProcess( fpCurrentProcess );
71 
72  // If this 2ndry particle has 'zero' kinetic energy, make sure
73  // it invokes a rest process at the beginning of the tracking
74  if(tempSecondaryTrack->GetKineticEnergy() <= DBL_MIN)
75  {
76  G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
77  if (pm->GetAtRestProcessVector()->entries()>0){
78  tempSecondaryTrack->SetTrackStatus( fStopButAlive );
79  fpSecondary->push_back( tempSecondaryTrack );
80  fN2ndariesAtRestDoIt++;
81  } else {
82  delete tempSecondaryTrack;
83  }
84  }
85  else
86  {
87  fpSecondary->push_back( tempSecondaryTrack );
88  counter++;
89  }
90  } //end of loop on secondary
91 }
92 
93 //______________________________________________________________________________
94 
95 void G4ITStepProcessor::Stepping(G4Track* track, const double & timeStep)
96 {
98  if(track == 0) return ; // maybe put an exception here
99  fTimeStep = timeStep ;
100  SetTrack(track);
101  DoStepping();
102 }
103 //______________________________________________________________________________
104 
105 // ************************************************************************
106 // Stepping
107 // ************************************************************************
109 {
110  SetupMembers() ;
111 
112  if(!fpProcessInfo)
113  {
114  G4ExceptionDescription exceptionDescription ;
115  exceptionDescription << "No process info found for particle :"
116  << fpTrack->GetDefinition()->GetParticleName();
117  G4Exception("G4ITStepProcessor::DoStepping","ITStepProcessor0012",
118  FatalErrorInArgument,exceptionDescription);
119  return ;
120  }
121  else if(fpTrack->GetTrackStatus() == fStopAndKill )
122  {
123  fpState->fStepStatus = fUndefined;
124  return ;
125  }
126 
127  if(fpProcessInfo->MAXofPostStepLoops == 0
128  && fpProcessInfo->MAXofAlongStepLoops == 0
129  && fpProcessInfo->MAXofAtRestLoops == 0)
130  {
131  fpTrack -> SetTrackStatus(fStopAndKill) ;
132  fpState->fStepStatus = fUndefined;
133  return ;
134  }
135  //---------------------------------
136  // AtRestStep, AlongStep and PostStep Processes
137  //---------------------------------
138  else
139  {
140  fpNavigator->SetNavigatorState(fpITrack->GetTrackingInfo()->GetNavigatorState());
141  fpNavigator->ResetHierarchyAndLocate( fpTrack->GetPosition(),
142  fpTrack->GetMomentumDirection(),
143  *((G4TouchableHistory*)fpTrack->GetTouchableHandle()()) );
144  fpNavigator->SetNavigatorState(fpITrack->GetTrackingInfo()->GetNavigatorState());
145  // We reset the navigator state before checking for AtRest
146  // in case a AtRest processe would use a navigator info
147 
148  if( fpTrack->GetTrackStatus() == fStopButAlive )
149  {
150  if( fpProcessInfo->MAXofAtRestLoops>0 &&
151  fpProcessInfo->fpAtRestDoItVector != 0) // second condition to make coverity happy
152  {
153  //-----------------
154  // AtRestStepDoIt
155  //-----------------
157  fpState->fStepStatus = fAtRestDoItProc;
158  fpStep->GetPostStepPoint()->SetStepStatus( fpState->fStepStatus );
159 
160  }
161  // Make sure the track is killed
162  fpTrack->SetTrackStatus( fStopAndKill );
163  }
164  else // if(fTimeStep > 0.) // Bye, because PostStepIL can return 0 => time =0
165  {
166  if(fpITrack == 0)
167  {
168  G4ExceptionDescription exceptionDescription ;
169  exceptionDescription
170  << " !!! TrackID : "<< fpTrack->GetTrackID() << G4endl
171  << " !!! Track status : "<< fpTrack->GetTrackStatus() << G4endl
172  << " !!! Particle Name : "<< fpTrack -> GetDefinition() -> GetParticleName() << G4endl
173  << "No G4ITStepProcessor::fpITrack found" << G4endl;
174 
175  G4Exception("G4ITStepProcessor::DoStepping","ITStepProcessor0013",
176  FatalErrorInArgument,exceptionDescription);
177  return ; // to make coverity happy
178  }
179 
180  if(fpITrack->GetTrackingInfo()->IsLeadingStep() == false)
181  {
182  // In case the track has NOT the minimum step length
183  // Given the final step time, the transportation
184  // will compute the final position of the particle
185 
186  fpState->fStepStatus = fPostStepDoItProc;
187  fpStep->GetPostStepPoint()
188  ->SetProcessDefinedStep(fpTransportation);
190  }
191 
192 
193  // Store the Step length (geometrical length) to G4Step and G4Track
194  fpTrack->SetStepLength( fpState->fPhysicalStep );
195  fpStep->SetStepLength( fpState->fPhysicalStep );
196 
197  G4double GeomStepLength = fpState->fPhysicalStep;
198 
199  // Store StepStatus to PostStepPoint
200  fpStep->GetPostStepPoint()->SetStepStatus( fpState->fStepStatus );
201 
202  // Invoke AlongStepDoIt
204 
205  // Update track by taking into account all changes by AlongStepDoIt
206  // fpStep->UpdateTrack(); // done in InvokeAlongStepDoItProcs
207 
208  // Update safety after invocation of all AlongStepDoIts
209  fpState->endpointSafOrigin= fpPostStepPoint->GetPosition();
210 
211  fpState->endpointSafety= std::max( fpState->proposedSafety - GeomStepLength, kCarTolerance);
212 
213  fpStep->GetPostStepPoint()->SetSafety( fpState->endpointSafety );
214 
215  if(GetIT(fpTrack)->GetTrackingInfo()->IsLeadingStep())
216  {
217  // Invoke PostStepDoIt including G4ITTransportation::PSDI
219  }
220  else
221  {
222  // Only invoke transportation
224  }
225  }
226 
227  fpITrack->GetTrackingInfo()->SetNavigatorState(fpNavigator->GetNavigatorState());
228  fpNavigator->SetNavigatorState(0);
229  }
230  //-------
231  // Finale
232  //-------
233 
234  // Update 'TrackLength' and remeber the Step length of the current Step
235  fpTrack->AddTrackLength(fpStep->GetStepLength());
236  fpTrack->IncrementCurrentStepNumber();
237 
238  // Send G4Step information to Hit/Dig if the volume is sensitive
239 /***
240  fpCurrentVolume = fpStep->GetPreStepPoint()->GetPhysicalVolume();
241  StepControlFlag = fpStep->GetControlFlag();
242 
243  if( fpCurrentVolume != 0 && StepControlFlag != AvoidHitInvocation)
244  {
245  fpSensitive = fpStep->GetPreStepPoint()->
246  GetSensitiveDetector();
247  if( fpSensitive != 0 )
248  {
249  fpSensitive->Hit(fpStep);
250  }
251  }
252 
253  User intervention process.
254  if( fpUserSteppingAction != 0 )
255  {
256  fpUserSteppingAction->UserSteppingAction(fpStep);
257  }
258  G4UserSteppingAction* regionalAction
259  = fpStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()
260  ->GetRegionalSteppingAction();
261  if( regionalAction ) regionalAction->UserSteppingAction(fpStep);
262 ***/
263  fpTrackingManager->AppendStep(fpTrack,fpStep);
264  // Stepping process finish. Return the value of the StepStatus.
265 
266  // return fpState->fStepStatus;
267 }
268 
269 //______________________________________________________________________________
270 
271 // ************************************************************************
272 // AtRestDoIt
273 // ************************************************************************
274 
276 {
277  fpStep->SetStepLength( 0. ); //the particle has stopped
278  fpTrack->SetStepLength( 0. );
279 
280  G4SelectedAtRestDoItVector& selectedAtRestDoItVector = fpState->fSelectedAtRestDoItVector;
281 
282  // invoke selected process
283  for(size_t np=0; np < fpProcessInfo->MAXofAtRestLoops; np++)
284  {
285  //
286  // Note: DoItVector has inverse order against GetPhysIntVector
287  // and SelectedAtRestDoItVector.
288  //
289  if( selectedAtRestDoItVector[fpProcessInfo->MAXofAtRestLoops-np-1] != InActivated)
290  {
291  fpCurrentProcess = (G4VITProcess*) (*fpProcessInfo->fpAtRestDoItVector)[np];
292 
293  fpCurrentProcess->SetProcessState(
294  fpTrackingInfo->GetProcessState(fpCurrentProcess->GetProcessID()));
295  fpParticleChange
296  = fpCurrentProcess->AtRestDoIt( *fpTrack, *fpStep);
297  fpCurrentProcess->SetProcessState(0);
298 
299  // Set the current process as a process which defined this Step length
300  fpStep->GetPostStepPoint()
301  ->SetProcessDefinedStep(fpCurrentProcess);
302 
303  // Update Step
304  fpParticleChange->UpdateStepForAtRest(fpStep);
305 
306  // Now Store the secondaries from ParticleChange to SecondaryList
307  DealWithSecondaries(fN2ndariesAtRestDoIt) ;
308 
309  // clear ParticleChange
310  fpParticleChange->Clear();
311 
312  } //if(fSelectedAtRestDoItVector[np] != InActivated){
313  } //for(size_t np=0; np < MAXofAtRestLoops; np++){
314  fpStep->UpdateTrack();
315 
316  fpTrack->SetTrackStatus( fStopAndKill );
317 }
318 
319 //______________________________________________________________________________
320 
321 // ************************************************************************
322 // AlongStepDoIt
323 // ************************************************************************
324 
326 {
327 
328  // If the current Step is defined by a 'ExclusivelyForced'
329  // PostStepDoIt, then don't invoke any AlongStepDoIt
330  if(fpState->fStepStatus == fExclusivelyForcedProc)
331  {
332  return; // Take note 'return' at here !!!
333  }
334 
335  // Invoke the all active continuous processes
336  for( size_t ci=0 ; ci<fpProcessInfo->MAXofAlongStepLoops ; ci++ )
337  {
338  fpCurrentProcess = (G4VITProcess*) (*fpProcessInfo->fpAlongStepDoItVector)[ci];
339  if (fpCurrentProcess== 0) continue;
340  // NULL means the process is inactivated by a user on fly.
341 
342  fpCurrentProcess->SetProcessState(fpTrackingInfo->GetProcessState(fpCurrentProcess->GetProcessID()));
343  fpParticleChange
344  = fpCurrentProcess->AlongStepDoIt( *fpTrack, *fpStep );
345  fpCurrentProcess->SetProcessState(0);
346  // Update the PostStepPoint of Step according to ParticleChange
347 
348  fpParticleChange->UpdateStepForAlongStep(fpStep);
349 
350  // Now Store the secondaries from ParticleChange to SecondaryList
351  DealWithSecondaries(fN2ndariesAlongStepDoIt) ;
352 
353  // Set the track status according to what the process defined
354  // if kinetic energy >0, otherwise set fStopButAlive
355  fpTrack->SetTrackStatus( fpParticleChange->GetTrackStatus() );
356 
357  // clear ParticleChange
358  fpParticleChange->Clear();
359  }
360 
361  fpStep->UpdateTrack();
362 
363  G4TrackStatus fNewStatus = fpTrack->GetTrackStatus();
364 
365  if ( fNewStatus == fAlive && fpTrack->GetKineticEnergy() <= DBL_MIN )
366  {
367  // G4cout << "G4ITStepProcessor::InvokeAlongStepDoItProcs : Track will be killed" << G4endl;
368  if(fpProcessInfo->MAXofAtRestLoops>0) fNewStatus = fStopButAlive;
369  else fNewStatus = fStopAndKill;
370  fpTrack->SetTrackStatus( fNewStatus );
371  }
372 
373 }
374 
375 //______________________________________________________________________________
376 
377 
378 // ************************************************************************
379 // PostStepDoIt
380 // ************************************************************************
381 
382 
384 {
385 
386  G4SelectedPostStepDoItVector& selectedPostStepDoItVector = fpState->fSelectedPostStepDoItVector;
387  G4StepStatus& stepStatus = fpState->fStepStatus;
388 
389  // Invoke the specified discrete processes
390  for(size_t np=0; np < fpProcessInfo->MAXofPostStepLoops; np++)
391  {
392  //
393  // Note: DoItVector has inverse order against GetPhysIntVector
394  // and SelectedPostStepDoItVector.
395  //
396  G4int Cond = selectedPostStepDoItVector[fpProcessInfo->MAXofPostStepLoops-np-1];
397  if(Cond != InActivated)
398  {
399  if( ((Cond == NotForced) && (stepStatus == fPostStepDoItProc)) ||
400  ((Cond == Forced) && (stepStatus != fExclusivelyForcedProc)) ||
401  // ((Cond == Conditionally) && (stepStatus == fAlongStepDoItProc)) ||
402  ((Cond == ExclusivelyForced) && (stepStatus == fExclusivelyForcedProc)) ||
403  ((Cond == StronglyForced) )
404  )
405  {
406 
407  InvokePSDIP(np);
408  }
409  } //if(*fSelectedPostStepDoItVector(np)........
410 
411  // Exit from PostStepLoop if the track has been killed,
412  // but extra treatment for processes with Strongly Forced flag
413  if(fpTrack->GetTrackStatus() == fStopAndKill)
414  {
415  for(size_t np1=np+1; np1 < fpProcessInfo->MAXofPostStepLoops; np1++)
416  {
417  G4int Cond2 = selectedPostStepDoItVector[fpProcessInfo->MAXofPostStepLoops-np1-1];
418  if (Cond2 == StronglyForced)
419  {
420  InvokePSDIP(np1);
421  }
422  }
423  break;
424  }
425  } //for(size_t np=0; np < MAXofPostStepLoops; np++){
426 }
427 
428 //______________________________________________________________________________
429 
431 {
432  fpCurrentProcess = (G4VITProcess*) (*fpProcessInfo->fpPostStepDoItVector)[np];
433 
434  fpCurrentProcess->SetProcessState(fpTrackingInfo->GetProcessState(fpCurrentProcess->GetProcessID()));
435  fpParticleChange
436  = fpCurrentProcess->PostStepDoIt( *fpTrack, *fpStep);
437  fpCurrentProcess->SetProcessState(0);
438 
439  // Update PostStepPoint of Step according to ParticleChange
440  fpParticleChange->UpdateStepForPostStep(fpStep);
441 
442  // Update G4Track according to ParticleChange after each PostStepDoIt
443  fpStep->UpdateTrack();
444 
445  // Update safety after each invocation of PostStepDoIts
447 
448  // Now Store the secondaries from ParticleChange to SecondaryList
449  DealWithSecondaries(fN2ndariesPostStepDoIt) ;
450 
451  // Set the track status according to what the process defined
452  fpTrack->SetTrackStatus( fpParticleChange->GetTrackStatus() );
453 
454  // clear ParticleChange
455  fpParticleChange->Clear();
456 }
457 
458 //______________________________________________________________________________
459 
460 // ************************************************************************
461 // Transport on a given time
462 // ************************************************************************
463 
465 {
466  double physicalStep(0.) ;
467 
468  fpTransportation = fpProcessInfo->fpTransportation;
469  // dynamic_cast<G4ITTransportation*>((fpProcessInfo->fpAlongStepGetPhysIntVector)[MAXofAlongStepLoops-1]);
470 
471  if(!fpTrack)
472  {
473  G4ExceptionDescription exceptionDescription ;
474  exceptionDescription
475  << "No G4ITStepProcessor::fpTrack found";
476  G4Exception("G4ITStepProcessor::FindTransportationStep","ITStepProcessor0013",
477  FatalErrorInArgument,exceptionDescription);
478  return;
479 
480  }
481  if(!fpITrack)
482  {
483  G4ExceptionDescription exceptionDescription ;
484  exceptionDescription
485  << "No G4ITStepProcessor::fITrack" ;
486  G4Exception("G4ITStepProcessor::FindTransportationStep","ITStepProcessor0014",
487  FatalErrorInArgument,exceptionDescription);
488  return;
489  }
490  if(!(fpITrack->GetTrack()))
491  {
492  G4ExceptionDescription exceptionDescription ;
493  exceptionDescription
494  << "No G4ITStepProcessor::fITrack->GetTrack()" ;
495  G4Exception("G4ITStepProcessor::FindTransportationStep","ITStepProcessor0015",
496  FatalErrorInArgument,exceptionDescription);
497  return;
498  }
499 
500  if(fpTransportation)
501  {
502  fpTransportation->SetProcessState(fpTrackingInfo->GetProcessState(fpTransportation->GetProcessID()));
503  fpTransportation->ComputeStep(*fpTrack, *fpStep, fTimeStep, physicalStep) ;
504  fpTransportation->SetProcessState(0);
505  }
506 
507  if(physicalStep >= DBL_MAX)
508  {
509  fpTrack -> SetTrackStatus(fStopAndKill) ;
510  return ;
511  }
512 
513  fpState->fPhysicalStep = physicalStep ;
514 }
515 
516 //______________________________________________________________________________
517 
519 {
520  size_t _MAXofPostStepLoops = fpProcessInfo->MAXofPostStepLoops;
521  G4SelectedPostStepDoItVector& selectedPostStepDoItVector = fpState->fSelectedPostStepDoItVector;
522  G4StepStatus& stepStatus = fpState->fStepStatus;
523 
524  // Invoke the specified discrete processes
525  for(size_t np=0; np < _MAXofPostStepLoops; np++)
526  {
527  //
528  // Note: DoItVector has inverse order against GetPhysIntVector
529  // and SelectedPostStepDoItVector.
530  //
531  G4int Cond = selectedPostStepDoItVector[_MAXofPostStepLoops-np-1];
532  if(Cond != InActivated)
533  {
534  if(
535  ((Cond == Forced) && (stepStatus != fExclusivelyForcedProc)) ||
536  // ((Cond == Conditionally) && (stepStatus == fAlongStepDoItProc)) ||
537  ((Cond == ExclusivelyForced) && (stepStatus == fExclusivelyForcedProc)) ||
538  ((Cond == StronglyForced) )
539  )
540  {
541 
542  InvokePSDIP(np);
543  }
544  } //if(*fSelectedPostStepDoItVector(np)........
545 
546  // Exit from PostStepLoop if the track has been killed,
547  // but extra treatment for processes with Strongly Forced flag
548  if(fpTrack->GetTrackStatus() == fStopAndKill)
549  {
550  for(size_t np1=np+1; np1 < _MAXofPostStepLoops; np1++)
551  {
552  G4int Cond2 = selectedPostStepDoItVector[_MAXofPostStepLoops-np1-1];
553  if (Cond2 == StronglyForced)
554  {
555  InvokePSDIP(np1);
556  }
557  }
558  break;
559  }
560  }
561 }
562 
563 //______________________________________________________________________________
564 
565 // ************************************************************************
566 // Apply cuts
567 // ************************************************************************
568 
569 
571 {
572  G4bool tBelowCutEnergyAndSafety = false;
573  G4int tPtclIdx
574  = G4ProductionCuts::GetIndex(aSecondary->GetDefinition());
575  if (tPtclIdx<0)
576  {
577  return;
578  }
579  G4ProductionCutsTable* tCutsTbl
581  G4int tCoupleIdx
582  = tCutsTbl->GetCoupleIndex(fpPreStepPoint->GetMaterialCutsCouple());
583  G4double tProdThreshold
584  = (*(tCutsTbl->GetEnergyCutsVector(tPtclIdx)))[tCoupleIdx];
585  if( aSecondary->GetKineticEnergy()<tProdThreshold )
586  {
587  tBelowCutEnergyAndSafety = true;
588  if(std::abs(aSecondary->GetDynamicParticle()->GetCharge()) > DBL_MIN)
589  {
590  G4double currentRange
592  aSecondary->GetKineticEnergy(),
593  fpPreStepPoint->GetMaterialCutsCouple());
594  tBelowCutEnergyAndSafety = (currentRange < CalculateSafety() );
595  }
596  }
597 
598  if( tBelowCutEnergyAndSafety )
599  {
600  if( !(aSecondary->IsGoodForTracking()) )
601  {
602  // Add kinetic energy to the total energy deposit
603  fpStep->AddTotalEnergyDeposit(
604  aSecondary->GetKineticEnergy() );
605  aSecondary->SetKineticEnergy(0.0);
606  }
607  }
608 }