source: trunk/source/processes/scoring/src/G4ScoreSplittingProcess.cc @ 1350

Last change on this file since 1350 was 1350, checked in by garnier, 13 years ago

update to last version 4.9.4

File size: 15.0 KB
Line 
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: G4ScoreSplittingProcess.cc,v 1.9 2010/12/15 13:55:35 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-ref-00 $
29//
30
31#include "G4ios.hh"
32#include "G4ScoreSplittingProcess.hh"
33#include "G4Step.hh"
34#include "G4VTouchable.hh"
35#include "G4VPhysicalVolume.hh"
36#include "G4ParticleChange.hh"
37#include "G4TransportationManager.hh"
38#include "G4ParticleChange.hh"
39#include "G4StepPoint.hh"
40
41#include "G4SDManager.hh"
42#include "G4VSensitiveDetector.hh"
43
44#include "G4EnergySplitter.hh"
45#include "G4TouchableHistory.hh"
46
47//--------------------------------
48// Constructor with name and type:
49//--------------------------------
50G4ScoreSplittingProcess::
51G4ScoreSplittingProcess(const G4String& processName,G4ProcessType theType)
52  :G4VProcess(processName,theType),
53   fOldTouchableH(),  fNewTouchableH(), fInitialTouchableH(), fFinalTouchableH()
54{
55  pParticleChange = &xParticleChange;
56
57  fSplitStep = new G4Step();
58  fSplitPreStepPoint =  fSplitStep->GetPreStepPoint();
59  fSplitPostStepPoint = fSplitStep->GetPostStepPoint();
60
61  if (verboseLevel>0)
62  {
63    G4cout << GetProcessName() << " is created " << G4endl;
64  }
65  fpEnergySplitter = new G4EnergySplitter(); 
66}
67
68// -----------
69// Destructor:
70// -----------
71G4ScoreSplittingProcess::~G4ScoreSplittingProcess()
72{
73  delete fSplitStep;
74  delete fpEnergySplitter; 
75}
76
77//------------------------------------------------------
78//
79// StartTracking
80//
81//------------------------------------------------------
82void G4ScoreSplittingProcess::StartTracking(G4Track* trk)
83{
84//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
85// Setup initial touchables for the first step
86//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
87  const G4Step* pStep= trk->GetStep();
88
89  fOldTouchableH = trk->GetTouchableHandle();
90  *fSplitPreStepPoint = *(pStep->GetPreStepPoint()); // Best to copy, so as to initialise
91  fSplitPreStepPoint->SetTouchableHandle(fOldTouchableH);
92  fNewTouchableH = fOldTouchableH;
93  *fSplitPostStepPoint= *(pStep->GetPostStepPoint()); // Best to copy, so as to initialise
94  fSplitPostStepPoint->SetTouchableHandle(fNewTouchableH);
95
96  ///  Initialize
97  fSplitPreStepPoint ->SetStepStatus(fUndefined);
98  fSplitPostStepPoint->SetStepStatus(fUndefined);
99}
100
101
102//----------------------------------------------------------
103//
104//  PostStepGetPhysicalInteractionLength()
105//
106//----------------------------------------------------------
107G4double
108G4ScoreSplittingProcess::PostStepGetPhysicalInteractionLength(
109         const G4Track& /*track*/, 
110         G4double   /*previousStepSize*/, 
111         G4ForceCondition* condition)
112{
113  // This process must be invoked anyway to score the hit
114  //   - to do the scoring if the current volume is a regular structure, or
115  //   - else to toggle the flag so that the SteppingManager does the scoring.
116  *condition = StronglyForced;
117
118  // Future optimisation: check whether in regular structure. 
119  //  If it is in regular structure,  be StronglyForced
120  //  If  not  in regular structure,
121  //         ask to be called only if SteppingControl is AvoidHitInvocation
122  //         in order to reset it to NormalCondition
123
124  return DBL_MAX;
125}
126
127//------------------------------------
128//
129//             PostStepDoIt()
130//
131//------------------------------------
132G4VParticleChange* G4ScoreSplittingProcess::PostStepDoIt(
133     const G4Track& track,
134     const G4Step& step)
135{ 
136  G4VPhysicalVolume*    pCurrentVolume= track.GetVolume(); 
137  G4LogicalVolume*      pLogicalVolume= pCurrentVolume->GetLogicalVolume(); 
138  G4VSensitiveDetector* ptrSD = pLogicalVolume->GetSensitiveDetector();
139
140  pParticleChange->Initialize(track); 
141  if(  ( ! pCurrentVolume->IsRegularStructure() ) || ( !ptrSD ) )  {
142     // Set the flag to make sure that Stepping Manager does the scoring
143     pParticleChange->ProposeSteppingControl( NormalCondition );     
144  } else { 
145     G4ThreeVector preStepPosition, postStepPosition, direction, finalPostStepPosition;
146     pParticleChange->ProposeSteppingControl( AvoidHitInvocation );
147 
148     G4double totalEnergyDeposit=  step.GetTotalEnergyDeposit();
149     G4StepStatus  fullStepStatus= step.GetPostStepPoint()->GetStepStatus(); 
150
151     CopyStepStart(step);
152     fSplitPreStepPoint->SetSensitiveDetector(ptrSD);
153     fOldTouchableH = fInitialTouchableH;
154     fNewTouchableH=  fOldTouchableH; 
155     *fSplitPostStepPoint= *(step.GetPreStepPoint()); 
156     
157     // Split the energy
158     // ----------------
159     G4int numberVoxelsInStep= fpEnergySplitter->SplitEnergyInVolumes( &step );
160
161     preStepPosition= step.GetPreStepPoint()->GetPosition();
162     finalPostStepPosition= step.GetPostStepPoint()->GetPosition(); 
163     direction= (finalPostStepPosition - preStepPosition).unit(); 
164
165     fFinalTouchableH= track.GetNextTouchableHandle(); 
166
167     postStepPosition= preStepPosition;
168     // Loop over the sub-parts of this step
169     G4int iStep;
170     for ( iStep=0; iStep < numberVoxelsInStep; iStep++ ){ 
171        G4int     idVoxel=  -1;  // Voxel ID
172        G4double  stepLength=0.0, energyLoss= 0.0;
173
174        *fSplitPreStepPoint  = *fSplitPostStepPoint;
175        fOldTouchableH = fNewTouchableH; 
176
177        preStepPosition= postStepPosition;
178        fSplitPreStepPoint->SetPosition( preStepPosition );
179        fSplitPreStepPoint->SetTouchableHandle(fOldTouchableH);
180       
181        fpEnergySplitter->GetLengthAndEnergyDeposited( iStep, idVoxel, stepLength, energyLoss);
182
183        // Correct the material, so that the track->GetMaterial gives correct answer
184        pLogicalVolume->SetMaterial( fpEnergySplitter->GetVoxelMaterial( iStep) );  // idVoxel) );
185
186        postStepPosition= preStepPosition + stepLength * direction; 
187        fSplitPostStepPoint->SetPosition(postStepPosition); 
188
189        // Load the Step with the new values
190        fSplitStep->SetStepLength(stepLength);
191        fSplitStep->SetTotalEnergyDeposit(energyLoss);
192        if( iStep < numberVoxelsInStep -1 ){ 
193          fSplitStep->GetPostStepPoint()->SetStepStatus( fGeomBoundary );
194          G4int  nextVoxelId= -1;
195          fpEnergySplitter->GetVoxelID( iStep+1, nextVoxelId );
196
197          // Create new "next" touchable for each section ??
198          G4VTouchable* fNewTouchablePtr= 
199              CreateTouchableForSubStep( nextVoxelId, postStepPosition );
200          fNewTouchableH= G4TouchableHandle(fNewTouchablePtr); 
201          fSplitPostStepPoint->SetTouchableHandle( fNewTouchableH );
202        } else { 
203          fSplitStep->GetPostStepPoint()->SetStepStatus( fullStepStatus );
204          fSplitPostStepPoint->SetTouchableHandle( fFinalTouchableH );
205        }
206
207
208        // As first approximation, split the NIEL in the same fractions as the energy deposit
209        G4double eLossFraction; 
210        eLossFraction= (totalEnergyDeposit>0.0) ? energyLoss / totalEnergyDeposit : 1.0 ; 
211        fSplitStep->SetNonIonizingEnergyDeposit(step.GetNonIonizingEnergyDeposit()*eLossFraction);
212       
213        fSplitPostStepPoint->SetSensitiveDetector( ptrSD ); 
214
215        // Call the Sensitive Detector
216        ptrSD->Hit(fSplitStep);
217
218        if (verboseLevel>1) Verbose(step);
219     }
220  }
221
222  // This must change the Stepping Control
223  return pParticleChange;
224}
225
226G4TouchableHistory*
227G4ScoreSplittingProcess::CreateTouchableForSubStep( G4int newVoxelNum, G4ThreeVector )
228{
229  // G4cout << " Creating touchable handle for voxel-no " << newVoxelNum << G4endl;
230
231  G4TouchableHistory*  oldTouchableHistory= dynamic_cast<G4TouchableHistory*>(fOldTouchableH());
232  G4TouchableHistory*  ptrTouchableHistory= G4TransportationManager::GetTransportationManager()->
233                                            GetNavigatorForTracking()->CreateTouchableHistory(oldTouchableHistory->GetHistory());
234 
235  // Change the history
236  G4NavigationHistory* ptrNavHistory= const_cast<G4NavigationHistory*>(ptrTouchableHistory->GetHistory());
237  G4VPhysicalVolume*   curPhysicalVol= ptrNavHistory->GetTopVolume();
238
239  EVolume curVolumeType=  ptrNavHistory->GetTopVolumeType();
240  if( curVolumeType == kParameterised )
241  { 
242    ptrNavHistory->BackLevel(); 
243    // G4VPVParameterised parameterisedPV= pNewMother
244    G4VPVParameterisation* curParamstn=  curPhysicalVol->GetParameterisation();
245
246    // From G4ParameterisedNavigation::IdentifyAndPlaceSolid() inline method
247    G4VSolid* sampleSolid = curParamstn->ComputeSolid(newVoxelNum, curPhysicalVol);
248    sampleSolid->ComputeDimensions(curParamstn, newVoxelNum, curPhysicalVol);
249    curParamstn->ComputeTransformation(newVoxelNum, curPhysicalVol);
250
251    ptrNavHistory->NewLevel( curPhysicalVol, kParameterised, newVoxelNum );
252  }
253  else
254  {
255    G4cout << " Current volume type is not Parameterised. " << G4endl; 
256    G4Exception("G4ScoreSplittingProcess::CreateTouchableForSubStep",
257          "ErrorRegularParamaterisation", JustWarning,
258         "Score Splitting Process is used for Regular Structure - but did not find one here.");
259  }
260  return ptrTouchableHistory; 
261}
262
263void G4ScoreSplittingProcess::CopyStepStart(const G4Step & step)
264{
265  fSplitStep->SetTrack(step.GetTrack());
266  fSplitStep->SetStepLength(step.GetStepLength());
267  fSplitStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
268  fSplitStep->SetNonIonizingEnergyDeposit(step.GetNonIonizingEnergyDeposit());
269  fSplitStep->SetControlFlag(step.GetControlFlag());
270
271  *fSplitPreStepPoint  = *(step.GetPreStepPoint());
272
273  fInitialTouchableH=  (step.GetPreStepPoint()) ->GetTouchableHandle();
274  fFinalTouchableH =   (step.GetPostStepPoint())->GetTouchableHandle();
275}
276
277void G4ScoreSplittingProcess::Verbose(const G4Step& step) const
278{
279  G4cout << "In mass geometry ------------------------------------------------" << G4endl;
280  G4cout << " StepLength : " << step.GetStepLength()/mm << "      TotalEnergyDeposit : "
281         << step.GetTotalEnergyDeposit()/MeV << G4endl;
282  G4cout << " PreStepPoint : "
283         << step.GetPreStepPoint()->GetPhysicalVolume()->GetName() << " - ";
284  if(step.GetPreStepPoint()->GetProcessDefinedStep())
285  { G4cout << step.GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
286  else
287  { G4cout << "NoProcessAssigned"; }
288  G4cout << G4endl;
289  G4cout << "                " << step.GetPreStepPoint()->GetPosition() << G4endl;
290  G4cout << " PostStepPoint : ";
291  if(step.GetPostStepPoint()->GetPhysicalVolume()) 
292  { G4cout << step.GetPostStepPoint()->GetPhysicalVolume()->GetName(); }
293  else
294  { G4cout << "OutOfWorld"; }
295  G4cout << " - ";
296  if(step.GetPostStepPoint()->GetProcessDefinedStep())
297  { G4cout << step.GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
298  else
299  { G4cout << "NoProcessAssigned"; }
300  G4cout << G4endl;
301  G4cout << "                 " << step.GetPostStepPoint()->GetPosition() << G4endl;
302
303  G4cout << "In ghost geometry ------------------------------------------------" << G4endl;
304  G4cout << " StepLength : " << fSplitStep->GetStepLength()/mm
305         << "      TotalEnergyDeposit : "
306         << fSplitStep->GetTotalEnergyDeposit()/MeV << G4endl;
307  G4cout << " PreStepPoint : "
308         << fSplitStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() << " ["
309           << fSplitStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber()
310           << " ]" << " - ";
311  if(fSplitStep->GetPreStepPoint()->GetProcessDefinedStep())
312  { G4cout << fSplitStep->GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
313  else
314  { G4cout << "NoProcessAssigned"; }
315  G4cout << G4endl;
316  G4cout << "                " << fSplitStep->GetPreStepPoint()->GetPosition() << G4endl;
317  G4cout << " PostStepPoint : ";
318  if(fSplitStep->GetPostStepPoint()->GetPhysicalVolume()) 
319  {
320    G4cout << fSplitStep->GetPostStepPoint()->GetPhysicalVolume()->GetName() << " ["
321           << fSplitStep->GetPostStepPoint()->GetTouchable()->GetReplicaNumber()
322           << " ]";
323  }
324  else
325  { G4cout << "OutOfWorld"; }
326  G4cout << " - ";
327  if(fSplitStep->GetPostStepPoint()->GetProcessDefinedStep())
328  { G4cout << fSplitStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); }
329  else
330  { G4cout << "NoProcessAssigned"; }
331  G4cout << G4endl;
332  G4cout << "                 " << fSplitStep->GetPostStepPoint()->GetPosition() << " == "
333         << fSplitStep->GetTrack()->GetMomentumDirection() 
334         << G4endl;
335
336}
337
338
339//----------------------------------------------------------
340//
341//  AtRestGetPhysicalInteractionLength()
342//
343//----------------------------------------------------------
344G4double
345G4ScoreSplittingProcess::AtRestGetPhysicalInteractionLength(
346         const G4Track& /*track*/, 
347         G4ForceCondition* condition)
348{
349  *condition = NotForced;  // Was Forced
350  return DBL_MAX;
351}
352
353
354//---------------------------------------
355//  AlongStepGetPhysicalInteractionLength
356//---------------------------------------
357G4double G4ScoreSplittingProcess::AlongStepGetPhysicalInteractionLength(
358            const G4Track&   , // track,
359            G4double         , // previousStepSize,
360            G4double         , // currentMinimumStep,
361            G4double&        , // proposedSafety,
362            G4GPILSelection* selection)
363{
364  *selection = NotCandidateForSelection;
365  return DBL_MAX;
366}
367
368//------------------------------------
369//             AlongStepDoIt()
370//------------------------------------
371
372G4VParticleChange* G4ScoreSplittingProcess::AlongStepDoIt(
373    const G4Track& track, const G4Step& )
374{
375  // Dummy ParticleChange ie: does nothing
376  // Expecting G4Transportation to move the track
377  dummyParticleChange.Initialize(track);
378  return &dummyParticleChange;
379}
380
381//------------------------------------
382//             AtRestDoIt()
383//------------------------------------
384G4VParticleChange* G4ScoreSplittingProcess::AtRestDoIt(
385     const G4Track& track,
386     const G4Step&)
387{ 
388  pParticleChange->Initialize(track);
389  return pParticleChange;
390}
Note: See TracBrowser for help on using the repository browser.