ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GB03BOptnSplitOrKillOnBoundary.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GB03BOptnSplitOrKillOnBoundary.cc
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 //
29 
30 #include "Randomize.hh"
32 
33 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
34 
36 : G4VBiasingOperation(name),
37  fParticleChange(),
38  fParticleChangeForNothing()
39 {}
40 
41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
42 
44 {}
45 
46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
47 
50  G4double,
52 {
53  // -- return "infinite" distance for interaction, but asks for GenerateBiasingFinalState
54  // -- being called anyway at the end of the step, by returning the "Forced" condition
55  // -- flag.
56  *condition = Forced;
57  return DBL_MAX;
58 }
59 
60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
61 
64  const G4Step* step )
65 {
66 
67  // Check if step is limited by the geometry: as we attached the biasing operator
68  // to the absorber layer, this volume boundary is the one of the absorber.
69  // (check of current step # of track is inelegant, but is to fix a "feature"
70  // that a cloned track can wrongly be seen in the wrong volume, because of numerical
71  // precision issue. In this case it makes a tiny step, which should be disregarded).
72  if ( ( step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary ) &&
73  ( track->GetCurrentStepNumber() != 1 ) )
74  {
75 
76  // -- Before deciding for killing or splitting, we make decision on applying
77  // -- the technique or not:
78  G4double trial = G4UniformRand(); // -- Note: G4UniformRand() is thread-safe
79  // -- engine for random numbers
80  if ( trial <= fApplyProbability )
81  {
82  // -- Get z component of track, to see if it moves forward or backward:
83  G4double pz = track->GetMomentum().z();
84 
85  if ( pz > 0.0 )
86  {
87  // -------------------------------------------------
88  // Here, we are moving "forward". We do "splitting":
89  // -------------------------------------------------
90 
91  // Get track weight:
92  G4double initialWeight = track->GetWeight();
93  // Define the tracks weight:
94  G4double weightOfTrack = initialWeight/fSplittingFactor;
95 
96  // The "particle change" is the object to be used to communicate to
97  // the tracking the update of the primary state and/or creation
98  // secondary tracks.
100 
101  // ask currect track weight to be changed to new value:
102  fParticleChange.ProposeParentWeight( weightOfTrack );
103 
104  // Now make clones of this track (this is the actual splitting):
105  // we will then have the primary and N-1 clones of it, hence the
106  // splitting by a factor N:
108  for ( G4int iSplit = 1 ; iSplit < fSplittingFactor ; iSplit++ )
109  {
110  G4Track* clone = new G4Track( *track );
111  clone->SetWeight( weightOfTrack );
112  fParticleChange.AddSecondary( clone );
113  }
114  fParticleChange.SetSecondaryWeightByProcess(true); // -- tricky
115  // -- take it as is ;) [though not necessary here, put for safety]
116 
117  // this new final state is returned to the tracking;
118  return &fParticleChange;
119 
120  }
121 
122  else
123 
124  {
125  // --------------------------------------------------------------
126  // Here, we are moving backward. We do killing, playing a russian
127  // roulette, killing 1/fSplittingFactor of the tracks in average:
128  // --------------------------------------------------------------
129 
130  // Get track weight:
131  G4double initialWeight = track->GetWeight();
132 
133  // The "particle change" is the object to be used to communicate to
134  // the tracking the update of the primary state and/or creation
135  // secondary tracks.
136  fParticleChange.Initialize(*track);
137 
138  // Shoot a random number (in ]0,1[ segment):
139  G4double random = G4UniformRand();
140 
141  // Decide to kill, keeping 1/fSplittingFactor of tracks:
142  G4double survivingProbability = 1.0/fSplittingFactor;
143  if ( random > survivingProbability )
144  {
145  // We ask for the the track to be killed:
147  }
148  else
149  {
150  // In this case, the track survives. We change its weight
151  // to conserve weight among killed and survival tracks:
153  }
154 
155  // this new final state is returned to the tracking;
156  return &fParticleChange;
157  }
158  } // -- end of : if ( trial > probaForApplying )
159  } // -- end of : if ( ( step->GetPostStepPoint()->GetStepStatus() ==
160  // fGeomBoundary ) ...
161 
162 
163  // Here, the step was not limited by the geometry (but certainly by a physics
164  // process). We do nothing: ie we make no change to the current track.
167 
168 }
169 
170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......