Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ParallelWorldProcess.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 //
27 // $Id: G4ParallelWorldProcess.cc 69966 2013-05-21 09:52:06Z gcosmo $
28 // GEANT4 tag $Name: geant4-09-04-ref-00 $
29 //
30 //
31 
32 #include "G4ios.hh"
34 #include "G4Step.hh"
35 #include "G4StepPoint.hh"
36 #include "G4Navigator.hh"
37 #include "G4VTouchable.hh"
38 #include "G4VPhysicalVolume.hh"
39 #include "G4ParticleChange.hh"
40 #include "G4PathFinder.hh"
42 #include "G4ParticleChange.hh"
43 #include "G4StepPoint.hh"
44 #include "G4FieldTrackUpdator.hh"
45 #include "G4Material.hh"
46 #include "G4ProductionCuts.hh"
47 #include "G4ProductionCutsTable.hh"
48 
49 #include "G4SDManager.hh"
50 #include "G4VSensitiveDetector.hh"
51 
52 G4Step* G4ParallelWorldProcess::fpHyperStep = 0;
53 G4int G4ParallelWorldProcess::nParallelWorlds = 0;
54 G4int G4ParallelWorldProcess::fNavIDHyp = 0;
56 { return fpHyperStep; }
58 { return fNavIDHyp; }
59 
61 G4ParallelWorldProcess(const G4String& processName,G4ProcessType theType)
62 :G4VProcess(processName,theType), fGhostNavigator(0), fNavigatorID(-1),
63  fFieldTrack('0'),layeredMaterialFlag(false)
64 {
65  if(!fpHyperStep) fpHyperStep = new G4Step();
66  iParallelWorld = ++nParallelWorlds;
67 
68  pParticleChange = &aDummyParticleChange;
69 
70  fGhostStep = new G4Step();
71  fGhostPreStepPoint = fGhostStep->GetPreStepPoint();
72  fGhostPostStepPoint = fGhostStep->GetPostStepPoint();
73 
74  fTransportationManager = G4TransportationManager::GetTransportationManager();
75  fTransportationManager->GetNavigatorForTracking()->SetPushVerbosity(false);
76  fPathFinder = G4PathFinder::GetInstance();
77 
78  if (verboseLevel>0)
79  {
80  G4cout << GetProcessName() << " is created " << G4endl;
81  }
82 }
83 
85 {
86  delete fGhostStep;
87  nParallelWorlds--;
88  if(nParallelWorlds==0)
89  {
90  delete fpHyperStep;
91  fpHyperStep = 0;
92  }
93 }
94 
96 SetParallelWorld(G4String parallelWorldName)
97 {
98  fGhostWorldName = parallelWorldName;
99  fGhostWorld = fTransportationManager->GetParallelWorld(fGhostWorldName);
100  fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
101  fGhostNavigator->SetPushVerbosity(false);
102 }
103 
106 {
107  fGhostWorldName = parallelWorld->GetName();
108  fGhostWorld = parallelWorld;
109  fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
110  fGhostNavigator->SetPushVerbosity(false);
111 }
112 
114 {
115  if(fGhostNavigator)
116  { fNavigatorID = fTransportationManager->ActivateNavigator(fGhostNavigator); }
117  else
118  {
119  G4Exception("G4ParallelWorldProcess::StartTracking",
120  "ProcParaWorld000",FatalException,
121  "G4ParallelWorldProcess is used for tracking without having a parallel world assigned");
122  }
123  fPathFinder->PrepareNewTrack(trk->GetPosition(),trk->GetMomentumDirection());
124 
125  fOldGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
126  fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
127  fNewGhostTouchable = fOldGhostTouchable;
128  fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
129 
130  fGhostSafety = -1.;
131  fOnBoundary = false;
132  fGhostPreStepPoint->SetStepStatus(fUndefined);
133  fGhostPostStepPoint->SetStepStatus(fUndefined);
134 
135 // G4VPhysicalVolume* thePhys = fNewGhostTouchable->GetVolume();
136 // if(thePhys)
137 // {
138 // G4Material* ghostMaterial = thePhys->GetLogicalVolume()->GetMaterial();
139 // if(ghostMaterial)
140 // { G4cout << " --- Material : " << ghostMaterial->GetName() << G4endl; }
141 // }
142 
143  *(fpHyperStep->GetPostStepPoint()) = *(trk->GetStep()->GetPostStepPoint());
144  if(layeredMaterialFlag)
145  {
146  G4StepPoint* realWorldPostStepPoint = trk->GetStep()->GetPostStepPoint();
147  SwitchMaterial(realWorldPostStepPoint);
148  }
149  *(fpHyperStep->GetPreStepPoint()) = *(fpHyperStep->GetPostStepPoint());
150 }
151 
152 G4double
154  const G4Track& /*track*/,
156 {
157 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
158 // At Rest must be registered ONLY for the particle which has other At Rest
159 // process(es).
160 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
161  *condition = Forced;
162  return DBL_MAX;
163 }
164 
166  const G4Track& track,
167  const G4Step& step)
168 {
169 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
170 // At Rest must be registered ONLY for the particle which has other At Rest
171 // process(es).
172 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173  fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
174  G4VSensitiveDetector* aSD = 0;
175  if(fOldGhostTouchable->GetVolume())
176  { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
177  fOnBoundary = false;
178  if(aSD)
179  {
180  CopyStep(step);
181  fGhostPreStepPoint->SetSensitiveDetector(aSD);
182 
183  fNewGhostTouchable = fOldGhostTouchable;
184 
185  fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
186  fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
187  if(fNewGhostTouchable->GetVolume())
188  {
189  fGhostPostStepPoint->SetSensitiveDetector(
190  fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
191  }
192  else
193  { fGhostPostStepPoint->SetSensitiveDetector(0); }
194 
195  aSD->Hit(fGhostStep);
196  }
197 
198  pParticleChange->Initialize(track);
199  return pParticleChange;
200 }
201 
202 G4double
204  const G4Track& /*track*/,
205  G4double /*previousStepSize*/,
207 {
208  *condition = StronglyForced;
209  return DBL_MAX;
210 }
211 
213  const G4Track& track,
214  const G4Step& step)
215 {
216  fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
217  G4VSensitiveDetector* aSD = 0;
218  if(fOldGhostTouchable->GetVolume())
219  { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
220  CopyStep(step);
221  fGhostPreStepPoint->SetSensitiveDetector(aSD);
222 
223  if(fOnBoundary)
224  {
225  fNewGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
226  }
227  else
228  {
229  fNewGhostTouchable = fOldGhostTouchable;
230  }
231 
232  fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
233  fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
234 
235  if(fNewGhostTouchable->GetVolume())
236  {
237  fGhostPostStepPoint->SetSensitiveDetector(
238  fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
239  }
240  else
241  { fGhostPostStepPoint->SetSensitiveDetector(0); }
242 
243  G4VSensitiveDetector* sd = fGhostPreStepPoint->GetSensitiveDetector();
244  if(sd)
245  {
246  sd->Hit(fGhostStep);
247  }
248 
249  pParticleChange->Initialize(track);
250  if(layeredMaterialFlag)
251  {
252  G4StepPoint* realWorldPostStepPoint =
253  ((G4Step*)(track.GetStep()))->GetPostStepPoint();
254  SwitchMaterial(realWorldPostStepPoint);
255  }
256  return pParticleChange;
257 }
258 
260  const G4Track& track, G4double previousStepSize, G4double currentMinimumStep,
261  G4double& proposedSafety, G4GPILSelection* selection)
262 {
263  static G4FieldTrack endTrack('0');
264  //static ELimited eLimited;
265  ELimited eLimited;
266  ELimited eLim = kUndefLimited;
267 
268  *selection = NotCandidateForSelection;
269  G4double returnedStep = DBL_MAX;
270 
271  if (previousStepSize > 0.)
272  { fGhostSafety -= previousStepSize; }
273  if (fGhostSafety < 0.) fGhostSafety = 0.0;
274 
275  if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
276  {
277  // I have no chance to limit
278  returnedStep = currentMinimumStep;
279  fOnBoundary = false;
280  proposedSafety = fGhostSafety - currentMinimumStep;
281  eLim = kDoNot;
282  }
283  else
284  {
285  G4FieldTrackUpdator::Update(&fFieldTrack,&track);
286  returnedStep
287  = fPathFinder->ComputeStep(fFieldTrack,currentMinimumStep,fNavigatorID,
288  track.GetCurrentStepNumber(),fGhostSafety,eLimited,
289  endTrack,track.GetVolume());
290  if(eLimited == kDoNot)
291  {
292  fOnBoundary = false;
293  fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition());
294  }
295  else
296  {
297  fOnBoundary = true;
298  }
299  proposedSafety = fGhostSafety;
300  if(eLimited == kUnique || eLimited == kSharedOther) {
301  *selection = CandidateForSelection;
302  }
303  else if (eLimited == kSharedTransport) {
304  returnedStep *= (1.0 + 1.0e-9);
305  }
306  eLim = eLimited;
307  }
308 
309  if(iParallelWorld==nParallelWorlds) fNavIDHyp = 0;
310  if(eLim == kUnique || eLim == kSharedOther) fNavIDHyp = fNavigatorID;
311  return returnedStep;
312 }
313 
315  const G4Track& track, const G4Step& )
316 {
317  pParticleChange->Initialize(track);
318  return pParticleChange;
319 }
320 
321 void G4ParallelWorldProcess::CopyStep(const G4Step & step)
322 {
323  G4StepStatus prevStat = fGhostPostStepPoint->GetStepStatus();
324 
325  fGhostStep->SetTrack(step.GetTrack());
326  fGhostStep->SetStepLength(step.GetStepLength());
327  fGhostStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
329  fGhostStep->SetControlFlag(step.GetControlFlag());
330 
331  *fGhostPreStepPoint = *(step.GetPreStepPoint());
332  *fGhostPostStepPoint = *(step.GetPostStepPoint());
333 
334  fGhostPreStepPoint->SetStepStatus(prevStat);
335  if(fOnBoundary)
336  { fGhostPostStepPoint->SetStepStatus(fGeomBoundary); }
337  else if(fGhostPostStepPoint->GetStepStatus()==fGeomBoundary)
338  { fGhostPostStepPoint->SetStepStatus(fPostStepDoItProc); }
339 
340  if(iParallelWorld==1)
341  {
342  G4StepStatus prevStatHyp = fpHyperStep->GetPostStepPoint()->GetStepStatus();
343 
344  fpHyperStep->SetTrack(step.GetTrack());
345  fpHyperStep->SetStepLength(step.GetStepLength());
346  fpHyperStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
348  fpHyperStep->SetControlFlag(step.GetControlFlag());
349 
350  *(fpHyperStep->GetPreStepPoint()) = *(fpHyperStep->GetPostStepPoint());
351  *(fpHyperStep->GetPostStepPoint()) = *(step.GetPostStepPoint());
352 
353  fpHyperStep->GetPreStepPoint()->SetStepStatus(prevStatHyp);
354  }
355 
356  if(fOnBoundary)
357  { fpHyperStep->GetPostStepPoint()->SetStepStatus(fGeomBoundary); }
358 }
359 
360 void G4ParallelWorldProcess::SwitchMaterial(G4StepPoint* realWorldStepPoint)
361 {
362  if(realWorldStepPoint->GetStepStatus()==fWorldBoundary) return;
363  G4VPhysicalVolume* thePhys = fNewGhostTouchable->GetVolume();
364  if(thePhys)
365  {
366  G4Material* ghostMaterial = thePhys->GetLogicalVolume()->GetMaterial();
367  if(ghostMaterial)
368  {
369  G4Region* ghostRegion = thePhys->GetLogicalVolume()->GetRegion();
370  G4ProductionCuts* prodCuts =
371  realWorldStepPoint->GetMaterialCutsCouple()->GetProductionCuts();
372  if(ghostRegion)
373  {
374  G4ProductionCuts* ghostProdCuts = ghostRegion->GetProductionCuts();
375  if(ghostProdCuts) prodCuts = ghostProdCuts;
376  }
377  const G4MaterialCutsCouple* ghostMCCouple =
379  ->GetMaterialCutsCouple(ghostMaterial,prodCuts);
380  if(ghostMCCouple)
381  {
382  realWorldStepPoint->SetMaterial(ghostMaterial);
383  realWorldStepPoint->SetMaterialCutsCouple(ghostMCCouple);
384  *(fpHyperStep->GetPostStepPoint()) = *(fGhostPostStepPoint);
385  fpHyperStep->GetPostStepPoint()->SetMaterial(ghostMaterial);
386  fpHyperStep->GetPostStepPoint()->SetMaterialCutsCouple(ghostMCCouple);
387  }
388  else
389  {
390  G4cout << "!!! MaterialCutsCouple is not found for "
391  << ghostMaterial->GetName() << "." << G4endl
392  << " Material in real world ("
393  << realWorldStepPoint->GetMaterial()->GetName()
394  << ") is used." << G4endl;
395  }
396  }
397  }
398 }
399 
401 {
402  G4int pdgCode = partDef->GetPDGEncoding();
403  if(pdgCode==0)
404  {
405  G4String partName = partDef->GetParticleName();
406  if(partName=="opticalphoton") return false;
407  if(partName=="geantino") return false;
408  if(partName=="chargedgeantino") return false;
409  }
410  else
411  {
412  if(pdgCode==22) return false; // gamma
413  if(pdgCode==11) return false; // electron
414  if(pdgCode==2212) return false; // proton
415  if(pdgCode==-12) return false; // anti_nu_e
416  if(pdgCode==12) return false; // nu_e
417  if(pdgCode==-14) return false; // anti_nu_mu
418  if(pdgCode==14) return false; // nu_mu
419  if(pdgCode==-16) return false; // anti_nu_tau
420  if(pdgCode==16) return false; // nu_tau
421  }
422  return true;
423 }
424