Event Biasing Techniques
Scoring, Geometrical Importance Sampling and Weight Roulette
Geant4 provides event biasing techniques which may be used to save
computing time in such applications as the simulation of radiation
shielding. These are geometrical splitting
and Russian roulette
(also called geometrical importance sampling), and
weight roulette. Scoring is carried out by G4MultiFunctionalDetector (see and ) using the standard Geant4 scoring technique.
Biasing specific scorers have been implemented and are described within
G4MultiFunctionDetector documentation. In this chapter, it is assumed that
the reader is familiar with both the usage of Geant4 and the
concepts of importance sampling. More detailed documentation may be
found in the documents
'Scoring, geometrical importance sampling and weight roulette'
.
A detailed description of different use-cases which employ the sampling
and scoring techniques can be found in the document
'Use cases of importance sampling and scoring in Geant4'
.
The purpose of importance sampling is to save computing time by
sampling less often the particle histories entering "less
important" geometry regions, and more often in more "important"
regions. Given the same amount of computing time, an
importance-sampled and an analogue-sampled simulation must show
equal mean values, while the importance-sampled simulation will
have a decreased variance.
The implementation of scoring is independent of the implementation
of importance sampling. However both share common concepts.
Scoring and importance sampling apply to particle types chosen
by the user, which should be borne in mind when interpreting the
output of any biased simulation.
Examples on how to use scoring and importance sampling may be found
in examples/extended/biasing.
Geometries
The kind of scoring referred to in this note and the importance
sampling apply to spatial cells provided by the user.
A cell is a physical volume (further specified
by it's replica number, if the volume is a replica). Cells may be defined
in two kinds of geometries:
mass geometry: the geometry setup of the
experiment to be simulated. Physics processes apply to this geometry.
parallel-geometry: a geometry constructed
to define the physical volumes according to which scoring and/or importance
sampling is applied.
The user has the choice to score and/or sample by importance the
particles of the chosen type, according to mass geometry or to
parallel geometry. It is possible to utilize several parallel
geometries in addition to the mass geometry. This provides the user
with a lot of flexibility to define separate geometries for
different particle types in order to apply scoring or/and
importance sampling.
Parallel geometries should be constructed using the implementation as
described in .
There are a few conditions for parallel geometries:
The world volume for parallel and mass geometries must be identical copies.
Scoring and importance cells must not share boundaries with the world volume.
Changing the Sampling
Samplers are higher level tools which perform the necessary
changes of the Geant4 sampling in order to apply importance
sampling and weight roulette.
Variance reduction (and scoring through the
G4MultiFunctionalDetector)
may be combined arbitrarily for chosen particle types and may be applied to the
mass or to parallel geometries.
The G4GeometrySampler can be applied equally to mass or
parallel geometries with an abstract interface supplied by G4VSampler.
G4VSampler provides
Prepare... methods and a Configure
method:
class G4VSampler
{
public:
G4VSampler();
virtual ~G4VSampler();
virtual void PrepareImportanceSampling(G4VIStore *istore,
const G4VImportanceAlgorithm
*ialg = 0) = 0;
virtual void PrepareWeightRoulett(G4double wsurvive = 0.5,
G4double wlimit = 0.25,
G4double isource = 1) = 0;
virtual void PrepareWeightWindow(G4VWeightWindowStore *wwstore,
G4VWeightWindowAlgorithm *wwAlg = 0,
G4PlaceOfAction placeOfAction =
onBoundary) = 0;
virtual void Configure() = 0;
virtual void ClearSampling() = 0;
virtual G4bool IsConfigured() const = 0;
};
The methods for setting up the desired combination need specific
information:
Importance sampling: message PrepareImportanceSampling
with a
G4VIStore
and optionally a G4VImportanceAlgorithm
Weight window: message PrepareWeightWindow with the
arguments:
*wwstore: a
G4VWeightWindowStore for retrieving the lower
weight bounds for the energy-space cells
*wwAlg: a
G4VWeightWindowAlgorithm if a customized algorithm
should be used
placeOfAction: a
G4PlaceOfAction specifying where to perform the
biasing
Weight roulette: message PrepareWeightRoulett with the
optional parameters:
wsurvive: survival weight
wlimit: minimal allowed
value of weight * source importance / cell importance
isource: importance of the source cell
Each object of a sampler class is responsible for one particle
type. The particle type is given to the constructor of the sampler
classes via the particle type name, e.g. "neutron". Depending on
the specific purpose, the Configure() of a sampler will
set up specialized processes (derived from G4VProcess) for
transportation in the parallel geometry, importance
sampling and weight roulette for the given particle type. When
Configure() is invoked the sampler places the processes in
the correct order independent of the order in which user invoked
the Prepare... methods.
The Prepare...() functions may each only be invoked
once.
To configure the sampling the function Configure()
must be called after the
G4RunManager has been initialized and the PhysicsList has
been instantiated.
The interface and framework are demonstrated in the
examples/extended/biasing directory, with the main changes being to the
G4GeometrySampler class and the fact that in the parallel case the WorldVolume
is a copy of the Mass World.
The parallel geometry now has to inherit from
G4VUserParallelWorld which also has the GetWorld() method
in order to retrieve a copy of the mass geometry WorldVolume.
class B02ImportanceDetectorConstruction : public G4VUserParallelWorld
ghostWorld = GetWorld();
The constructor for G4GeometrySampler takes a pointer to
the physical world volume and the particle type name (e.g. "neutron") as arguments.
In a single mass geometry the sampler is created as follows:
G4GeometrySampler mgs(detector->GetWorldVolume(),"neutron");
mgs.SetParallel(false);
Whilst the following lines of code are required in order to set up the sampler for the
parallel geometry case:
G4VPhysicalVolume* ghostWorld = pdet->GetWorldVolume();
G4GeometrySampler pgs(ghostWorld,"neutron");
pgs.SetParallel(true);
Also note that the preparation and configuration of the samplers has to be
carried out after the instantiation of the UserPhysicsList
and after the initialisation of the G4RunManager:
pgs.PrepareImportanceSampling(&aIstore, 0);
pgs.Configure();
Due to the fact that biasing is a process and has to be inserted after all the
other processes have been created.
Importance Sampling
Importance sampling acts on particles crossing boundaries
between "importance cells". The action taken depends on the
importance values assigned to the cells. In general a particle
history is either split or Russian roulette is played if the
importance increases or decreases, respectively. A weight assigned
to the history is changed according to the action taken.
The tools provided for importance sampling require the user to
have a good understanding of the physics in the problem. This is
because the user has to decide which particle types require
importance sampled, define the cells, and assign importance values
to the cells. If this is not done properly the results cannot be
expected to describe a real experiment.
The assignment of importance values to a cell is done using an
importance store described below.
An "importance store" with the interface G4VIStore is
used to store importance values related to cells. In order to do
importance sampling the user has to create an object (e.g. of class
G4IStore) of type G4VIStore. The samplers may be
given a G4VIStore. The user fills the store with cells and
their importance values.
An importance store has to be constructed with a reference to
the world volume of the geometry used for importance sampling. This
may be the world volume of the mass or of a parallel geometry.
Importance stores derive from the interface G4VIStore:
class G4VIStore
{
public:
G4VIStore();
virtual ~G4VIStore();
virtual G4double GetImportance(const G4GeometryCell &gCell) const = 0;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const = 0;
virtual const G4VPhysicalVolume &GetWorldVolume() const = 0;
};
A concrete implementation of an importance store is provided by
the class G4VStore. The public
part of the class is:
class G4IStore : public G4VIStore
{
public:
explicit G4IStore(const G4VPhysicalVolume &worldvolume);
virtual ~G4IStore();
virtual G4double GetImportance(const G4GeometryCell &gCell) const;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const;
virtual const G4VPhysicalVolume &GetWorldVolume() const;
void AddImportanceGeometryCell(G4double importance,
const G4GeometryCell &gCell);
void AddImportanceGeometryCell(G4double importance,
const G4VPhysicalVolume &,
G4int aRepNum = 0);
void ChangeImportance(G4double importance,
const G4GeometryCell &gCell);
void ChangeImportance(G4double importance,
const G4VPhysicalVolume &,
G4int aRepNum = 0);
G4double GetImportance(const G4VPhysicalVolume &,
G4int aRepNum = 0) const ;
private: .....
};
The member function AddImportanceGeometryCell() enters
a cell and an importance value into the importance store. The
importance values may be returned either according to a physical
volume and a replica number or according to a
G4GeometryCell. The user must be aware of the
interpretation of assigning importance values to a cell.
If scoring is also implemented then this is attached to logical volumes, in
which case the physical volume and replica number method should be used for
assigning importance values. See examples/extended/biasing
B01 and B02 for examples of this.
An importance value must be assigned to every cell.
The different cases:
Cell is not in store
Not filling a certain cell in the store will cause an
exception.
Importance value = zero
Tracks of the chosen particle type will be killed.
importance values > 0
Normal allowed values
Importance value smaller zero
Not allowed!
The Importance Sampling Algorithm
Importance sampling supports using a customized importance
sampling algorithm. To this end, the sampler interface
G4VSampler
may be given a pointer to the interface
G4VImportanceAlgorithm:
class G4VImportanceAlgorithm
{
public:
G4VImportanceAlgorithm();
virtual ~G4VImportanceAlgorithm();
virtual G4Nsplit_Weight Calculate(G4double ipre,
G4double ipost,
G4double init_w) const = 0;
};
The method Calculate() takes the arguments:
ipre, ipost: importance
of the previous cell and the importance of the current cell,
respectively.
init_w: the particles weight
It returns the struct:
class G4Nsplit_Weight
{
public:
G4int fN;
G4double fW;
};
fN: the calculated
number of particles to exit the importance sampling
fW: the weight of the particles
The user may have a customized algorithm used by providing a
class inheriting from G4VImportanceAlgorithm.
If no customized algorithm is given to the sampler the default
importance sampling algorithm is used. This algorithm is
implemented in G4ImportanceAlgorithm.
The Weight Window Technique
The weight window technique is a weight-based alternative to
importance sampling:
applies splitting and Russian roulette depending on space
(cells) and energy
user defines weight windows in contrast to defining importance
values as in importance sampling
In contrast to importance sampling this technique is not weight
blind. Instead the technique is applied according to the particle
weight with respect to the current energy-space cell.
Therefore the technique is convenient to apply in combination
with other variance reduction techniques such as cross-section
biasing and implicit capture.
A weight window may be specified for every cell and for several
energy regions: space-energy cell.
Weight window concept
The user specifies a lower weight bound W_L
for every space-energy cell.
The upper weight bound W_U and the survival weight W_S are
calculated as:
W_U = C_U W_L and
W_S = C_S W_L.
The user specifies C_S and C_U once for the whole problem.
The user may give different sets of energy bounds for every cell
or one set for all geometrical cells
Special case: if C_S = C_U = 1 for all energies then weight
window is equivalent to importance sampling
The user can choose to apply the technique: at boundaries, on
collisions or on boundaries and collisions
The energy-space cells are realized by G4GeometryCell
as in importance sampling. The cells are stored in a weight window
store defined by G4VWeightWindowStore:
class G4VWeightWindowStore {
public:
G4VWeightWindowStore();
virtual ~G4VWeightWindowStore();
virtual G4double GetLowerWeitgh(const G4GeometryCell &gCell,
G4double partEnergy) const = 0;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const = 0;
virtual const G4VPhysicalVolume &GetWorldVolume() const = 0;
};
A concrete implementation is provided:
class G4WeightWindowStore: public G4VWeightWindowStore {
public:
explicit G4WeightWindowStore(const G4VPhysicalVolume &worldvolume);
virtual ~G4WeightWindowStore();
virtual G4double GetLowerWeitgh(const G4GeometryCell &gCell,
G4double partEnergy) const;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const;
virtual const G4VPhysicalVolume &GetWorldVolume() const;
void AddLowerWeights(const G4GeometryCell &gCell,
const std::vector<G4double> &lowerWeights);
void AddUpperEboundLowerWeightPairs(const G4GeometryCell &gCell,
const G4UpperEnergyToLowerWeightMap&
enWeMap);
void SetGeneralUpperEnergyBounds(const
std::set<G4double, std::less<G4double> > & enBounds);
private::
...
};
The user may choose equal energy bounds for all cells. In this
case a set of upper energy bounds must be given to the store using
the method SetGeneralUpperEnergyBounds. If a general set
of energy bounds have been set AddLowerWeights can be used
to add the cells.
Alternatively, the user may chose different energy regions for
different cells. In this case the user must provide a mapping of
upper energy bounds to lower weight bounds for every cell using the
method AddUpperEboundLowerWeightPairs.
Weight window algorithms implementing the interface class
G4VWeightWindowAlgorithm can be used to define a
customized algorithm:
class G4VWeightWindowAlgorithm {
public:
G4VWeightWindowAlgorithm();
virtual ~G4VWeightWindowAlgorithm();
virtual G4Nsplit_Weight Calculate(G4double init_w,
G4double lowerWeightBound) const = 0;
};
A concrete implementation is provided and used as a default:
class G4WeightWindowAlgorithm : public G4VWeightWindowAlgorithm {
public:
G4WeightWindowAlgorithm(G4double upperLimitFaktor = 5,
G4double survivalFaktor = 3,
G4int maxNumberOfSplits = 5);
virtual ~G4WeightWindowAlgorithm();
virtual G4Nsplit_Weight Calculate(G4double init_w,
G4double lowerWeightBound) const;
private:
...
};
The constructor takes three parameters which are used to:
calculate the upper weight bound (upperLimitFaktor), calculate the
survival weight (survivalFaktor), and introduce a maximal number
(maxNumberOfSplits) of copies to be created in one go.
In addition, the inverse of the maxNumberOfSplits is used to
specify the minimum survival probability in case of Russian
roulette.
The Weight Roulette Technique
Weight roulette (also called weight cutoff) is usually applied
if importance sampling and implicit capture are used together.
Implicit capture is not described here but it is useful to note
that this procedure reduces a particle weight in every collision
instead of killing the particle with some probability.
Together with importance sampling the weight of a particle may
become so low that it does not change any result significantly.
Hence tracking a very low weight particle is a waste of computing
time. Weight roulette is applied in order to solve this
problem.
The weight roulette concept
Weight roulette takes into account the importance "Ic" of the
current cell and the importance "Is" of the cell in which the
source is located, by using the ratio "R=Is/Ic".
Weight roulette uses a relative minimal weight limit and a
relative survival weight. When a particle falls below the weight
limit Russian roulette is applied. If the particle survives,
tracking will be continued and the particle weight will be set to
the survival weight.
The weight roulette uses the following parameters with their
default values:
wsurvival: 0.5
wlimit: 0.25
isource: 1
The following algorithm is applied:
If a particle weight "w" is lower than R*wlimit:
the weight of the particle will be changed to "ws = wsurvival*R"
the probability for the particle to survive is "p = w/ws"
Physics Based Biasing
Geant4 supports physics based biasing through a number of general
use, built in biasing techniques. A utility class,
G4WrapperProcess, is also available to support user defined
biasing.
Built in Biasing Options
Primary Particle Biasing
Primary particle biasing can be used to increase the number of
primary particles generated in a particular phase space region of
interest. The weight of the primary particle is modified as
appropriate. A general implementation is provided through the
G4GeneralParticleSource class. It is possible to bias position,
angular and energy distributions.
G4GeneralParticleSource is a concrete implementation of
G4VPrimaryGenerator. To use, instantiate G4GeneralParticleSource in
the G4VUserPrimaryGeneratorAction class, as demonstrated below.
MyPrimaryGeneratorAction::MyPrimaryGeneratorAction() {
generator = new G4GeneralParticleSource;
}
void
MyPrimaryGeneratorAction::GeneratePrimaries(G4Event*anEvent){
generator->GeneratePrimaryVertex(anEvent);
}
The biasing can be configured through interactive commands.
Extensive documentation can be found in
Primary particle biasing. Examples are also distributed
with the Geant4 distribution in
examples/extended/eventgenerator/exgps.
Radioactive Decay Biasing
The G4RadioactiveDecay class simulates the decay of radioactive
nuclei and implements the following biasing options:
Increase the sampling rate of radionuclides within observation
times through a user defined probability distribution function
Nuclear splitting, where the parent nuclide is split into a
user defined number of nuclides
Branching ratio biasing where branching ratios are sampled with
equal probability
G4RadioactiveDecay is a process which must be registered with a
process manager, as demonstrated below.
void MyPhysicsList::ConstructProcess()
{
...
G4RadioactiveDecay* theRadioactiveDecay =
new G4RadioactiveDecay();
G4ProcessManager* pmanager = ...
pmanager ->AddProcess(theRadioactiveDecay);
...
}
The biasing can be controlled either in compiled code or through
interactive commands. Extensive documentation can be found in
Radioactive decay biasing example
and
Radioactive decay biasing
.
Radioactive decay biasing examples are also distributed with the Geant4
distribution in
examples/extended/radioactivedecay/exrdm.
Hadronic Leading Particle Biasing
One hadronic leading particle biasing technique is
implemented in the G4HadLeadBias utility. This method keeps only
the most important part of the event, as well as representative
tracks of each given particle type. So the track with the highest
energy as well as one of each of Baryon, pi0, mesons and leptons.
As usual, appropriate weights are assigned to the particles.
Setting the SwitchLeadBiasOn
environmental variable will activate this utility.
Hadronic Cross Section Biasing
Cross section biasing artificially enhances/reduces the cross
section of a process. This may be useful for studying thin layer
interactions or thick layer shielding. The built in hadronic cross
section biasing applies to photon inelastic, electron nuclear and
positron nuclear processes.
The biasing is controlled through the
BiasCrossSectionByFactor method
in G4HadronicProcess, as demonstrated below.
void MyPhysicsList::ConstructProcess()
{
...
G4ElectroNuclearReaction * theElectroReaction =
new G4ElectroNuclearReaction;
G4ElectronNuclearProcess theElectronNuclearProcess;
theElectronNuclearProcess.RegisterMe(theElectroReaction);
theElectronNuclearProcess.BiasCrossSectionByFactor(100);
pManager->AddDiscreteProcess(&theElectronNuclearProcess);
...
}
G4WrapperProcess
G4WrapperProcess can be used to implement user defined event
biasing. G4WrapperProcess, which is a process itself, wraps an
existing process. By default, all function calls are forwared to
the wrapped process. It is a non-invasive way to modify the
behaviour of an existing process.
To use this utility, first create a derived class inheriting
from G4WrapperProcess. Override the methods whose behaviour you
would like to modify, for example, PostStepDoIt, and register the
derived class in place of the process to be wrapped. Finally,
register the wrapped process with G4WrapperProcess. The code
snippets below demonstrate its use.
class MyWrapperProcess : public G4WrapperProcess {
...
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step) {
// Do something interesting
}
};
void MyPhysicsList::ConstructProcess()
{
...
G4LowEnergyBremsstrahlung* bremProcess =
new G4LowEnergyBremsstrahlung();
MyWrapperProcess* wrapper = new MyWrapperProcess();
wrapper->RegisterProcess(bremProcess);
processManager->AddProcess(wrapper, -1, -1, 3);
}