ECCE @ EIC Software
Reference for
ECCE @ EIC
simulation and reconstruction software on GitHub
Home page
Related Pages
Modules
Namespaces
Classes
Files
External Links
File List
File Members
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
"
31
#include "
GB03BOptnSplitOrKillOnBoundary.hh
"
32
33
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
34
35
GB03BOptnSplitOrKillOnBoundary::GB03BOptnSplitOrKillOnBoundary
(
G4String
name
)
36
:
G4VBiasingOperation
(name),
37
fParticleChange(),
38
fParticleChangeForNothing()
39
{}
40
41
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
42
43
GB03BOptnSplitOrKillOnBoundary::~GB03BOptnSplitOrKillOnBoundary
()
44
{}
45
46
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
47
48
G4double
GB03BOptnSplitOrKillOnBoundary::
49
DistanceToApplyOperation
(
const
G4Track
*,
50
G4double
,
51
G4ForceCondition
*
condition
)
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
62
G4VParticleChange
*
63
GB03BOptnSplitOrKillOnBoundary::GenerateBiasingFinalState
(
const
G4Track
*
track
,
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.
99
fParticleChange
.
Initialize
(*track);
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:
107
fParticleChange
.
SetNumberOfSecondaries
(
fSplittingFactor
-1 );
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:
146
fParticleChange
.
ProposeTrackStatus
(
fStopAndKill
);
147
}
148
else
149
{
150
// In this case, the track survives. We change its weight
151
// to conserve weight among killed and survival tracks:
152
fParticleChange
.
ProposeParentWeight
( initialWeight*
fSplittingFactor
);
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.
165
fParticleChangeForNothing
.
Initialize
(*track);
166
return
&
fParticleChangeForNothing
;
167
168
}
169
170
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
geant4
tree
geant4-10.6-release
examples
extended
biasing
GB03
src
GB03BOptnSplitOrKillOnBoundary.cc
Built by
Jin Huang
. updated:
Wed Jun 29 2022 17:25:02
using
1.8.2 with
ECCE GitHub integration