Hands-on 3 -- Implementing a Geometry

advertisement
Hands-on 4 Scoring
 Introduction
 Installation
 Scoring geometry implementation
 Scorer definition
 User defined run class
 Applying filters
Important:
Every time you open a new shell you need to set your environment up correctly.
Introduction
By the end of this Hands-on you should be able to:
Implement a spherical parameterised geometry to be used for scoring
Construct a sensitive detector (G4MultiFunctionalDetector) and attach scorers
Implement a user defined run class
Construct scorer filters based on particle type and energy
This exercise builds on the HandsOn3 exercise. It is based on an experimental setup developed
for bremsstrahlung benchmarking at UCSF. The simplified experiment is made up of the
following components:
Vacuum beam pipe
Titanium beam window
Iron evacuation chamber window
Silicon monitor
Beryllium target
Electrons are generated with an energy of 15 MeV in the beam pipe. The electrons interact with
the target and generate bremsstrahlung photons. A spherical, parameterised, air filled scoring
geometry is also implemented. The number of photons crossing this scoring volume is counted
in ten theta bins and ten energy bins. The diagram below demonstrates the simulated
experiment.
The following files are provided with the exercise:
beamTest.cc - main program
BeamTestDetectorConstruction – material, geometry , sensitive detector and scorer
definitions
BeamTestPrimaryGeneratorAction - primary particle generator
BeamTestPhysicsList - user defined physics list
BeamTestRun - user defined run class
BeamTestRunAction - G4UserRunAction class
BeamTestScoreParameterisation – scoring volume parameterisation
All the geometries except the spherical scoring geometry are implemented. The scoring
geometry, sensitive detector, scorers and filters are implemented over the course of the exercise.
Installation
To start this exercise, unpack HandsOn4.tgz to your working directory.
Compile and link it using following commands:
$ cd HandsOn4
$ make
Once you have successfully compiled and linked the code, try it to see how it runs:
$ ./bin/$G4SYSTEM/beamTest run.mac
This will produce files named G4Data0.heprep and G4Data1.heprep, which can be viewed by
invoking the Wired visualization tool.
$ wired G4Data0.heprep
You should be able to view the following:
You can see that all the components with the exception of the scoring volume have been
implemented.
Scoring Geometry Implementation
The mother scoring volume is defined as a thin air filled sphere. It has an inner radius of 1 m,
an outer radius of 1.001 m, and is centered in the world volume. Ten scoring rings are placed
within the mother scoring volume. Each ring covers 6 degrees in theta and is constructed of air
with an inner radius of 1m and an outer radius of 1.001 m. G4PVPlacement is used to construct
the
mother
sphere,
while
G4PVParameterised
is
used
to
construct
BeamTestScoreParameterisation is used for the ring parameterisation.
The implementation, along with visualisation attributes is shown below.
BeamTestDetectorConstruction.cc
----- snipped -----
#include "G4Tubs.hh"
#include "G4VisAttributes.hh"
// HandsOn4: Scoring volumes
#include "BeamTestScoreParameterisation.hh"
#include "G4PVParameterised.hh"
#include "G4Sphere.hh"
----- snipped -----
////////////////////////////////////////////////////////////////////////
// HandsOn4: Scoring volumes
// Mother sphere
G4double innerRadius = 1.0*m;
G4double outerRadius = 1.001*m;
G4VSolid* sphereSolid = new G4Sphere("Sphere_Solid",
// Name
innerRadius,
// Inner radius
outerRadius,
// Outer radius
0.*deg,
// Starting phi
360.*deg,
// Delta phi
0.*deg,
// Starting theta
180.*deg);
// Delta theta
G4LogicalVolume* sphereLogical =
new G4LogicalVolume(sphereSolid, air, "Sphere_Logical");
the
rings.
new G4PVPlacement(0, G4ThreeVector(), sphereLogical, "Sphere_Physical",
fpWorldLogical, false, 0);
// 10 scoring rings
G4double deltaTheta = 6.*deg;
G4VSolid* scoreSolid = new G4Sphere("Score_Solid",
// Name
innerRadius,
// Inner radius
outerRadius,
// Outer radius
0.*deg,
// Starting phi
360.*deg,
// Delta phi
0.*deg,
// Starting theta
deltaTheta);
// Delta theta
G4LogicalVolume* fScoreLogical =
new G4LogicalVolume(scoreSolid, air, "scoreLog");
BeamTestScoreParameterisation* param =
new BeamTestScoreParameterisation(innerRadius, outerRadius, deltaTheta);
new G4PVParameterised("scorePhys",
// Name
fScoreLogical, // Logical volume
sphereLogical, // Mother volume
kZAxis,
// Axis
10,
// Number of replicas
param);
// Parameterisation
----- snipped -----
// HandsOn4: Scoring volume attributes
// Mother sphere
G4VisAttributes* sphereAttributes =
new G4VisAttributes(G4Colour(1.0,1.0,1.0,0.2));
sphereAttributes->SetVisibility(false);
sphereLogical->SetVisAttributes(sphereAttributes);
// Ring scoring volumes. Green with transparancy.
G4VisAttributes* scoreAttributes =
new G4VisAttributes(G4Colour(0.0,1.0,0.0,0.2));
scoreAttributes->SetVisibility(true);
fScoreLogical->SetVisAttributes(scoreAttributes);
Implement the above and compile, link and run the program. Use Wired to check that all the
scoring geometries are now in place. You should be able to see something like:
Note that the mother scoring sphere has been made invisible by default. You can change this by
checking the Sphere_Physical[0] box.
Scorer Definition
We are interested in counting the number of photons per unit area which cross the inner surface
of each scoring ring. To do this we need to:
Create a G4MultiFunctionalDetector detector
Register the detector with the sensitive detector manager (G4SDManager)
Attach the detector to the parameterised scoring volume
Create a primitive scorer for scoring surface current
Register the primitive scorer with the detector
We will use the G4PSSphereSurfaceCurrent scorer to count the number of photons crossing
each scoring ring. Since the ten scoring rings are replicas, we only need to create one scorer.
This scorer will automatically record the current as a function of replica copy number.
The implementation is shown below.
BeamTestDetectorConstruction.cc
----- snipped -----
// HandsOn4: Scoring components
#include "G4MultiFunctionalDetector.hh"
#include "G4PSSphereSurfaceCurrent.hh"
#include "G4SDManager.hh"
----- snipped -----
new G4PVParameterised("scorePhys",
// Name
fScoreLogical, // Logical volume
sphereLogical, // Mother volume
kZAxis,
// Axis
10,
// Number of replicas
param);
// Parameterisation
// HandsOn4: Construct scoring components
SetupScoring(fScoreLogical);
////////////////////////////////////////////////////////////////////////
// Target
(Default parameters for Be )
G4Material* beryllium = G4Material::GetMaterial("Beryllium");
----- snipped -----
void BeamTestDetectorConstruction::SetupScoring(G4LogicalVolume* scoringVolume)
{
// HandsOn4: Construct scoring components
// Create a new sensitive detector named "MyDetector"
G4MultiFunctionalDetector* detector =
new G4MultiFunctionalDetector("MyDetector");
// Get pointer to detector manager
G4SDManager* manager = G4SDManager::GetSDMpointer();
// Register detector with manager
manager->AddNewDetector(detector);
// Attach detector to scoring volume
scoringVolume->SetSensitiveDetector(detector);
// Create a primitive Scorer named myScorer
G4PSSphereSurfaceCurrent* scorer = new G4PSSphereSurfaceCurrent("myScorer",
fCurrent_In);
// Register scorer with detector
detector->RegisterPrimitive(scorer);
G4cout<<"Created G4MultiFunctionalDetector named "
<<detector->GetName()<<", and a G4PSSphereSurfaceCurrent scorer "
<<"named "<<scorer->GetName()<<G4endl;
}
After implementing the above, compile, link and run the program. Check that the sensitive
detector and scorer names are printed out, as shown below.
Printout showing detector and scorer details
----- snipped ----Material: Vacuum
density: 0.010 mg/cm3 temperature: 273.15 K pressure: 0.02 atm RadLength: 36.786 km
---> Element: Nitrogen (N) Z = 7.0 N = 14.0 A = 14.01 g/mole fractionMass: 70.00 % Abundance 72.71 %
---> Element: Oxygen (O) Z = 8.0 N = 16.0 A = 16.00 g/mole fractionMass: 30.00 % Abundance 27.29 %
Created G4MultiFunctionalDetector named MyDetector, and a G4PSSphereSurfaceCurrent scorer named
myScorer
BeamTestPhysicsList::SetCuts:CutLength : 1 mm
----- snipped -----
User Defined Run Class
The scorer implemented in the previous section will accumulate data over a single event, but we
are more interested in data accumulated over an entire run. Therefore, we need to create our
own run class, inheriting from G4Run. This class will be responsible for merging the scorer data
for all events.
A partially implemented user run class called BeamTestRun is provided with the example. Also
included
is
a
BeamTestRunAction
class
which
inherits
from
G4UserRunAction.
BeamTestRunAction is responsible for creating an instance of BeamTestRun, and is an example
of one of the optional user action classes. BeamTestRunAction needs to be registered with the
run manager in the main program, as shown below.
beamTest.cc
----- snipped -----
#include "BeamTestPrimaryGeneratorAction.hh"
// HandsOn4: User defined run action
#include "BeamTestRunAction.hh"
#include "G4RunManager.hh"
----- snipped -----
// User action classes
runManager->SetUserAction(new BeamTestPrimaryGeneratorAction());
// HandsOn4: User defined run action
runManager->SetUserAction(new BeamTestRunAction);
// Initialize G4 kernel
After implementing the above, compile, link and run the program. Check that you get printout
shown below.
Printout showing user defined BeamTestRun class creation
Voxelisation: top memory users:
Percent
Memory
------- --------
Heads
Nodes Pointers
------ ------ -------- ----------
Total CPU
Volume
----------
67.84
0k
3
14
36
0.00
World_Logical
32.16
0k
1
7
20
0.00
Sphere_Logical
Creating user define run class BeamTestRun
Start Run processing.
HepRepFile writing to G4Data1.heprep
The event by event scorer data merging still needs to be implemented in BeamTestRun. This
class has a data member, fMap, which is used to hold the accumulated data. fMap is just a map
between hit collection id’s and scorer data (G4THitsMap<G4double>). Merging of scorer data is
done in the BeamTestRun::RecordEvent(const G4Event* anEvent) method, and involves:
Accessing the hit collection for the event (G4HCofThisEvent object)
Using the G4HCofThisEvent object to access the G4THitsMap<double> data for each
registered scorer
Accumulating the hit map data
The implementation is shown below.
BeamTestRun.cc
----- snipped -----
void BeamTestRun::RecordEvent(const G4Event* anEvent)
{
numberOfEvent++;
// HandsOn4: Merging event data
// Get the hits collection
G4HCofThisEvent* eventHitCollection = anEvent->GetHCofThisEvent();
if (!eventHitCollection) return;
// Update our private fMap
std::map< G4int, G4THitsMap<G4double>* >::iterator iter = fMap.begin();
while (iter != fMap.end()) {
G4int id = iter->first;
// Get the hit collection corresponding to "id"
G4THitsMap<G4double>* eventHitsMap
= dynamic_cast< G4THitsMap<G4double>* >(eventHitCollection->GetHC(id));
// Expect this to exist
assert (0 != eventHitsMap);
// Accumulate event data into our G4THitsMap<G4double> map
*(iter->second) += *eventHitsMap;
iter++;
}
}
After implementing the above, compile, link and run the program for 1000 events. If you don’t
want to visualise the
results, disable the visualisation system by adding the command
/vis/disable to your macro. This will also speed up the processing.
Check that you now get data printed out as shown below. Theta bins corresponding to the ten
scoring rings are listed in the first column. The corresponding number of photons per unit area
(mm-2) crossing the scoring ring are listed the second column.
Printout showing current printout in theta bin
Number of Events Processed:1000 events.
Theta myScorer
0
0.00227
1
0.00115
2 0.000476
3 0.000327
4 0.000244
5 0.000162
6 0.000111
7 9.89e-05
8 9.78e-05
9 8.34e-05
Graphics systems deleted.
Visualization Manager deleting...
Applying Filters
So far we have only used one scorer to count all tracks crossing each of the scoring rings. It is
possible to attach a filter to a scorer, so that only hits passing the filter will be processed. For
example, if we are only interested in scoring photons within a given energy range, we would
attach a suitably configured G4SDParticleWithEnergyFilter filter to the scorer.
If we are
interested in scoring a number of different energy ranges we can create multiple scorers, each
with its own filter. This is demonstrated below, where ten scorers filtering on photons in 1.2
MeV energy bins are generated and registered with the G4MultiFunctionalDetector.
BeamTestDetectorConstruction.cc
----- snipped -----
// HandsOn4: Filter
#include "G4SDParticleWithEnergyFilter.hh"
----- snipped -----
void BeamTestDetectorConstruction::SetupScoring(G4LogicalVolume* scoringVolume)
{
// HandsOn4: Construct scoring components
// Create a new sensitive detector named "MyDetector"
G4MultiFunctionalDetector* detector =
new G4MultiFunctionalDetector("MyDetector");
// Get pointer to detector manager
G4SDManager* manager = G4SDManager::GetSDMpointer();
// Register detector with manager
manager->AddNewDetector(detector);
// Attach detector to scoring volume
scoringVolume->SetSensitiveDetector(detector);
// HandsOn4: Applying filters to scorers
G4int nEnergyBins = 10;
G4int i(0);
for (i=0; i<nEnergyBins; i++) {
char name[10];
std::sprintf(name,"Scorer%i", i);
// Create a primitive Scorer
G4PSSphereSurfaceCurrent* scorer =
new G4PSSphereSurfaceCurrent(name, fCurrent_In);
// Create a filter
G4SDParticleWithEnergyFilter* filter =
new G4SDParticleWithEnergyFilter("Gamma Filter");
// Filter will pass only gammas
filter->add("gamma");
// Set energy range of gammas filter will accept
G4double minEnergy = i*1.2*MeV;
G4double maxEnergy = (i+1)*1.2*MeV;
filter->SetKineticEnergy(minEnergy, maxEnergy);
// Attach filter to scorer. Scorer will only process hits which pass
// the filter
scorer->SetFilter(filter);
G4cout<<"Created scorer with name "<<name;
G4cout<<", covering energy range "<<minEnergy*MeV;
G4cout<<" : "<<maxEnergy*MeV<<" MeV"<<G4endl;
// Register scorer with detector
detector->RegisterPrimitive(scorer);
}
}
After implementing the above, compile, link and run the program for around 10000 events.
Check that you see the new scorers registered, and that you see the current printed out for each
theta and energy bin, as shown below.
Printout showing current in each theta and energy bin
----- snipped -----
--->
Element: Nitrogen (N)
Z =
7.0
N =
14.0
A =
14.01 g/mole
fractionMass:
70.00 %
Abundance
fractionMass:
30.00 %
Abundance
72.71 %
--->
Element: Oxygen (O)
Z =
8.0
N =
16.0
A =
16.00 g/mole
27.29 %
Created scorer with name Scorer0, covering energy range 0 : 1.2 MeV
Created scorer with name Scorer1, covering energy range 1.2 : 2.4 MeV
Created scorer with name Scorer2, covering energy range 2.4 : 3.6 MeV
Created scorer with name Scorer3, covering energy range 3.6 : 4.8 MeV
Created scorer with name Scorer4, covering energy range 4.8 : 6 MeV
Created scorer with name Scorer5, covering energy range 6 : 7.2 MeV
Created scorer with name Scorer6, covering energy range 7.2 : 8.4 MeV
Created scorer with name Scorer7, covering energy range 8.4 : 9.6 MeV
Created scorer with name Scorer8, covering energy range 9.6 : 10.8 MeV
Created scorer with name Scorer9, covering energy range 10.8 : 12 MeV
BeamTestPhysicsList::SetCuts:CutLength : 1 mm
----- snipped -----
Number of Events Processed:10000 events.
Theta
Scorer0
Scorer1
Scorer2
Scorer3
0
0.0132
0.00378
0.00215
0.00093 0.000581 0.000436 0.000407 0.000378 0.000349 0.000174
1
0.00724
2
Scorer4
Scorer5
Scorer6
Scorer7
Scorer8
Scorer9
0.00145 0.000573 0.000457 0.000185 0.000214 0.000126 0.000156 5.83e-05 1.94e-05
0.0041 0.000693
0.00031
0.00027
0.0002 0.000106 0.000112 4.11e-05 2.35e-05 1.76e-05 1.76e-05
3
0.00272
0.00014 6.36e-05 2.97e-05 2.55e-05 2.55e-05 4.24e-06 8.49e-06 4.24e-06
4
0.00201 0.000191 6.03e-05 2.34e-05 1.34e-05 2.01e-05
0
5
0.00138 0.000131 4.75e-05 1.68e-05 2.79e-06 5.58e-06
0
0
0
0
6
0.00113 8.94e-05 3.14e-05 9.66e-06 4.83e-06
0
0 2.42e-06
0
0
7
0.00101 4.52e-05 6.45e-06
0
0
0
0 2.15e-06
8 0.000927 4.11e-05 3.91e-06 3.91e-06 1.96e-06 1.96e-06
0
0
0
0
9 0.000722 2.72e-05 7.25e-06 1.81e-06
0
0
0
0
4.3e-06
0
0
0
1e-05 3.35e-06
0
Graphics systems deleted.
An output file called output.csv (Comma Separated Variables) should also be produced. This can
be loaded into for example, OpenOffice or Excel, to make a plot of the data. The plot below
shows the data for 104 events plotted for a selection of energy bins.
You can download the complete source of this exercise from HandsOn4_complete.tgz
Geant4 Tutorial Course
Gean4.v8.0p01
May 2006
Jane Tinslay – Heavily based on a tutorial given at a SLAC in March 2006 by Tsukasa Aso
Download