Import Geant4 11.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2022-12-09 14:43:28 +01:00
parent c07cea1fe0
commit 9f34590941
3810 changed files with 200490 additions and 182326 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ Webified README pages are not yet available for all examples. </i>
- A set of common classes which can be reused in other examples demonstrating just a particular feature
- \link Examples_electromagnetic electromagnetic \endlink
- Specific EM physics simulation with histogramming
- \link Exampleerrorpropagation errorpropagation \endlink
- \link Examples_errorpropagation errorpropagation \endlink
- Use of the error propagation utility (Geant4e)
- \link Examples_eventgenerator eventgenerator \endlink
- Applications demonstrating various ways of primary event generation:
+7 -1
View File
@@ -13,7 +13,13 @@
\link ExampleAnaEx02 AnaEx02 \endlink
As AnaEx01, but direct interface to ROOT.
\link ExampleAnaEx03 AnaEx03 \endlink
Demonstrates usage of analysis commands for file management
(new since Geant4 11.1), in particular writing histograms and ntuples in a file
multiple times.
\link ExampleB1Con B1Con \endlink
B1Con shows how to use the statistical tool G4ConvergenceTester.
+23 -3
View File
@@ -96,9 +96,29 @@
One can control the name of the histograms file and its format:
- default name : AnaEx01
The format of the histogram file can be : root (default),
xml, csv. Include correct g4nnn.hh in HistoManager.hh
xml, csv.
\section AnaEx01_s7 How to build
We can define the default file type and set it to the analysis manager via
\verbatim
/analysis/setDefaultFileType root # or csv hdf5 xml
\endverbatim
The file names then need not to be provided with the file extension and the same macro
can be used with different output types.
\section AnaEx03_s7 Macros
- The AnaEx01.in macro uses the defaultFileType parameter (alias), which default value,
"root" is defined in main.
- AnaEx01-csv.in, AnaEx01-hdf5.in, AnaEx01-root.in, AnaEx01-xml.in:
In these macros, the default value of the defaultFileType is overritten with
\verbatim
/control/alias defaultFileType cvs # or hdf5 root xml
\endverbatim
and then the AnaEx01.in macro is called.
\section AnaEx01_s8 How to build
An additional step is needed when building the example with GNUmake
due to using the extra shared directory:
@@ -114,7 +134,7 @@
% gmake clean_setup
\endverbatim
\section AnaEx01_s8 HOW TO RUN
\section AnaEx01_s9 HOW TO RUN
- Execute AnaEx01 in the 'interactive mode' with visualization
\verbatim
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx01 example
# with csv file type
#
/control/alias defaultFileType csv
/control/execute AnaEx01.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx01 example
# with hdf5 file type
#
/control/alias defaultFileType hdf5
/control/execute AnaEx01.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx01 example
# with root file type (default)
#
/control/alias defaultFileType root
/control/execute AnaEx01.in
@@ -11,7 +11,7 @@ Environment variable "G4FORCE_RUN_MANAGER_TYPE" enabled with value == Serial. Fo
**************************************************************
Geant4 version Name: geant4-11-01-beta-01 (30-June-2022)
Geant4 version Name: geant4-11-01-ref-00 (9-December-2022)
Copyright : Geant4 Collaboration
References : NIM A 506 (2003), 250-303
: IEEE-TNS 53 (2006), 270-278
@@ -67,6 +67,8 @@ Registered graphics systems are:
RayTracer (RayTracer)
VRML2FILE (VRML2FILE)
gMocrenFile (gMocrenFile)
TOOLSSG_OFFSCREEN (TSG_OFFSCREEN)
TOOLSSG_OFFSCREEN (TSG_OFFSCREEN, TSG_FILE)
OpenGLImmediateQt (OGLIQt, OGLI)
OpenGLStoredQt (OGLSQt, OGL, OGLS)
OpenGLImmediateXm (OGLIXm, OGLIQt_FALLBACK)
@@ -122,6 +124,23 @@ Some /vis commands (optionally) take a string to specify colour.
for neutron : 3 to 6 GeV
### Adding tracking cuts for neutron TimeCut(ns)= 10000 KinEnergyCut(MeV)= 0
#
/det/setAbsMat G4_Al
/det/setGapMat G4_Air
/det/setAbsThick 20. mm
/run/reinitializeGeometry
/det/setGapThick 10. mm
/run/reinitializeGeometry
/det/setSizeYZ 30. mm
/run/reinitializeGeometry
/det/setNbOfLayers 20
/run/reinitializeGeometry
#
/run/beamOn 1
------------------------------------------------------------
---> The calorimeter is 20 layers of: [ 20mm of G4_Al + 10mm of G4_lAr ]
------------------------------------------------------------
=======================================================================
====== Electromagnetic Physics Parameters ========
=======================================================================
@@ -131,6 +150,7 @@ Apply cuts on all EM processes 0
Use combined TransportationWithMsc Disabled
Use general process 1
Enable linear polarisation for gamma 0
Enable photoeffect sampling below K-shell 1
Enable sampling of quantum entanglement 0
X-section factor for integral approach 0.8
Min kinetic energy for tables 100 eV
@@ -158,7 +178,7 @@ Lowest e+e- kinetic energy 1 keV
Lowest muon/hadron kinetic energy 1 keV
Use ICRU90 data 0
Fluctuations of dE/dx are enabled 1
Type of fluctuation model 2
Type of fluctuation model for leptons and hadrons Urban
Use built-in Birks satuaration 0
Build CSDA range enabled 0
Use cut as a final range enabled 0
@@ -209,8 +229,8 @@ conv: for gamma SubType=14 BuildTable=1
BetheHeitlerLPM : Emin= 0 eV Emax= 100 TeV ModifiedTsai
Rayl: for gamma SubType=11 BuildTable=1
Lambda table from 100 eV to 100 keV, 7 bins/decade, spline: 0
LambdaPrime table from 100 keV to 100 TeV in 63 bins
Lambda table from 100 eV to 150 keV, 7 bins/decade, spline: 0
LambdaPrime table from 150 keV to 100 TeV in 62 bins
===== EM models for the G4Region DefaultRegionForTheWorld ======
LivermoreRayleigh : Emin= 0 eV Emax= 100 TeV CullenGenerator
@@ -692,6 +712,11 @@ CoulombScat: for pi- XStype:1 SubType=1 BuildTable=1
Process: hFritiofCaptureAtRest
---------------------------------------------------
Hadronic Processes for anti_hypertriton
Process: hFritiofCaptureAtRest
---------------------------------------------------
Hadronic Processes for anti_lambda
@@ -967,6 +992,47 @@ See commands in /vis/modeling/trajectories/ for other options.
---> Begin of event: 0
--------------------End of Run------------------------------
mean Energy in Absorber : 256.274 MeV +- 0 eV
mean Energy in Gap : 50.16 MeV +- 0 eV
mean trackLength in Absorber : 63.8594 cm +- 0 fm
mean trackLength in Gap : 26.1088 cm +- 0 fm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 256.274 MeV rms = 0 eV
EGap: mean = 50.16 MeV rms = 0 eV
LAbs: mean = 63.8594 cm rms = 0 fm
LGap: mean = 26.1088 cm rms = 0 fm
... write file : AnaEx01.root - done
... close file : AnaEx01.root - done
----> Histograms and ntuples are saved
There are 4 h1 histograms
0 with 0 entries: Edep in absorber (MeV)
1 with 0 entries: Edep in gap (MeV)
2 with 0 entries: trackL in absorber (mm)
3 with 0 entries: trackL in gap (mm)
List them with "/analysis/list".
View them with "/vis/plot" or "/vis/reviewPlots".
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
### Run 1 start.
... create file : AnaEx01.root - done
... open analysis file : AnaEx01.root - done
... open analysis file : AnaEx01.root - done
----> Output file is open in AnaEx01.root.
---> Begin of event: 0
---> Begin of event: 100
---> Begin of event: 200
@@ -987,74 +1053,20 @@ See commands in /vis/modeling/trajectories/ for other options.
--------------------End of Run------------------------------
mean Energy in Absorber : 453.656 MeV +- 12.4449 MeV
mean Energy in Gap : 24.7474 MeV +- 7.52057 MeV
mean Energy in Absorber : 188.96 MeV +- 48.8659 MeV
mean Energy in Gap : 46.7177 MeV +- 12.7612 MeV
mean trackLength in Absorber : 32.6632 cm +- 9.51264 mm
mean trackLength in Gap : 12.2578 cm +- 3.86035 cm
mean trackLength in Absorber : 46.7149 cm +- 12.1118 cm
mean trackLength in Gap : 23.7187 cm +- 6.51829 cm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 453.656 MeV rms = 12.4449 MeV
EGap: mean = 24.7474 MeV rms = 7.52057 MeV
LAbs: mean = 32.6632 cm rms = 9.51264 mm
LGap: mean = 12.2578 cm rms = 3.86035 cm
... write file : AnaEx01.root - done
... close file : AnaEx01.root - done
----> Histograms and ntuples are saved
There are 4 h1 histograms
0 with 0 entries: Edep in absorber (MeV)
1 with 0 entries: Edep in gap (MeV)
2 with 0 entries: trackL in absorber (mm)
3 with 0 entries: trackL in gap (mm)
List them with "/analysis/list".
View them with "/vis/plot" or "/vis/reviewPlots".
#
/det/setAbsMat G4_Al
/det/setGapMat G4_Air
/det/setAbsThick 20. mm
/run/reinitializeGeometry
/det/setGapThick 10. mm
/run/reinitializeGeometry
/det/setSizeYZ 30. mm
/run/reinitializeGeometry
/det/setNbOfLayers 20
/run/reinitializeGeometry
#
/run/beamOn 1
------------------------------------------------------------
---> The calorimeter is 20 layers of: [ 20mm of G4_Al + 10mm of G4_lAr ]
------------------------------------------------------------
### Run 1 start.
... create file : AnaEx01.root - done
... open analysis file : AnaEx01.root - done
... open analysis file : AnaEx01.root - done
----> Output file is open in AnaEx01.root.
---> Begin of event: 0
--------------------End of Run------------------------------
mean Energy in Absorber : 135.077 MeV +- 0 eV
mean Energy in Gap : 45.3511 MeV +- 0 eV
mean trackLength in Absorber : 33.6513 cm +- 0 fm
mean trackLength in Gap : 22.1697 cm +- 0 fm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 135.077 MeV rms = 0 eV
EGap: mean = 45.3511 MeV rms = 0 eV
LAbs: mean = 33.6513 cm rms = 0 fm
LGap: mean = 22.1697 cm rms = 0 fm
EAbs: mean = 188.96 MeV rms = 48.8659 MeV
EGap: mean = 46.7177 MeV rms = 12.7612 MeV
LAbs: mean = 46.7149 cm rms = 12.1118 cm
LGap: mean = 23.7187 cm rms = 6.51829 cm
... write file : AnaEx01.root - done
... close file : AnaEx01.root - done
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx01 example
# with xml file type
#
/control/alias defaultFileType xml
/control/execute AnaEx01.in
File diff suppressed because it is too large Load Diff
@@ -49,7 +49,7 @@ int main(int argc,char** argv)
{
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = 0;
G4UIExecutive* ui = nullptr;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
@@ -62,7 +62,7 @@ int main(int argc,char** argv)
// Set mandatory initialization classes
//
DetectorConstruction* detector = new DetectorConstruction;
auto detector = new DetectorConstruction;
runManager->SetUserInitialization(detector);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization(detector));
@@ -76,10 +76,12 @@ int main(int argc,char** argv)
//
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if ( ! ui ) {
if ( ui == nullptr ) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand("/control/alias defaultFileType root");
// define the default value for alias used in AnaEx01.in
UImanager->ApplyCommand(command+fileName);
}
else {
+10 -4
View File
@@ -2,16 +2,17 @@
# Macro file for the test of AnaEx01 example
#
#/run/numberOfThreads 2
# reduce output in MT
/control/cout/ignoreThreadsExcept 0
# initialize
/run/initialize
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
# set file type via parameter passed from calling macro
# or use the default value "root" set in main
/analysis/setDefaultFileType {defaultFileType}
# Test commands defined in this example
/control/verbose 2
@@ -24,3 +25,8 @@
/det/setNbOfLayers 20
#
/run/beamOn 1
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
@@ -23,8 +23,8 @@ include(${Geant4_USE_FILE})
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/shared/include
include_directories(${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/shared/include
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc
${PROJECT_SOURCE_DIR}/shared/src/*.cc)
@@ -34,8 +34,8 @@ file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(AnaEx01 AnaEx01.cc
${sources} ${add_sources} ${fortran_sources}
add_executable(AnaEx01 AnaEx01.cc
${sources} ${add_sources} ${fortran_sources}
${headers} ${add_headers})
target_link_libraries(AnaEx01 ${Geant4_LIBRARIES} ${HBOOK_LIBRARIES})
@@ -44,16 +44,12 @@ target_link_libraries(AnaEx01 ${Geant4_LIBRARIES} ${HBOOK_LIBRARIES})
# build AnaEx01. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(AnaEx01_SCRIPTS
AnaEx01.in run.mac init_vis.mac vis.mac
)
set(AnaEx01_FILES
AnaEx01.in AnaEx01-csv.in AnaEx01-hdf5.in AnaEx01-root.in AnaEx01-xml.in run.mac init_vis.mac vis.mac
histo ntuple)
foreach(_script ${AnaEx01_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
foreach(_file ${AnaEx01_FILES})
file(COPY ${PROJECT_SOURCE_DIR}/${_file} DESTINATION ${PROJECT_BINARY_DIR})
endforeach()
#----------------------------------------------------------------------------
@@ -5,6 +5,14 @@ which **must** added in reverse chronological order (newest at the top). It must
be used as a substitute for writing good git commit messages!
## 2022-11-04 I. Hrivnacova (AnaEx01-V11-00-02)
- Updated README files (new macros description)
## 2022-11-03 I. Hrivnacova (AnaEx01-V11-00-01)
- Added test macros for all supported file types
and moved instatiating of G4AnalysisManager in the HistoManager class
constructor to get analysis commands available before run initialization
## 2021-12-10 Ben Morgan (AnaEx01-V11-00-00)
- Change to new Markdown History format
+66 -45
View File
@@ -6,35 +6,35 @@
AnaEx01
-------
Examples AnaEx01 and AnaEx02 show the usage of histogram and tuple
manipulations using G4Analysis and ROOT compliant systems on the same
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
three examples.
This example shows the usage of histogram and tuple manipulations using
G4Analysis system.
The example is an adaptation of examples/novice/N03. It describes a simple
This example shows the usage of histogram and tuple manipulations using
G4Analysis system.
The example is an adaptation of examples/novice/N03. It describes a simple
sampling calorimeter setup.
1- Detector description
-----------------------
The calorimeter is a box made of a given number of layers. A layer
consists of an absorber plate and of a detection gap. The layer is
replicated.
Six parameters define the calorimeter :
- the material of the absorber,
- the thickness of an absorber plate,
- the material of the detection gap,
- the thickness of a gap,
- the number of layers,
- the transverse size of the calorimeter (the input face is a square).
- the transverse size of the calorimeter (the input face is a square).
The default geometry is constructed in DetectorConstruction class,
but all of the above parameters can be modified interactively via
the commands defined in the DetectorMessenger class.
@@ -48,66 +48,87 @@
======> || | || | || | ||
|| | || | || | ||
==========================================================================
2- Physics list
---------------
The particle's type and the physic processes which will be available
in this example are set in the FTFP_BERT physics list.
3- Action Initialization
------------------------
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
which are defined thread-local and a run action class
which is defined both thread-local and global.
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
ActionInitialization::BuildForMaster().
Note that ActionInitialization::Build() is also used to
Note that ActionInitialization::Build() is also used to
instatiate user action clasess in sequential mode.
4- An event : PrimaryGeneratorAction
------------------------------------
The primary kinematic consists of a single particle which hits the
calorimeter perpendicular to the input face. The type of the particle
and its energy are set in the PrimaryGeneratorAction class, and can
be changed via the G4 build-in commands of ParticleGun class.
5- Histograms
-------------
-------------
AnaEx01 can produce 4 histograms :
EAbs : total energy deposit in absorber per event
EGap : total energy deposit in gap per event
LAbs : total track length of charged particles in absorber per event
LGap : total track length of charged particles in gap per event
EGap : total energy deposit in gap per event
LAbs : total track length of charged particles in absorber per event
LGap : total track length of charged particles in gap per event
And 2 Ntuples :
- Ntuple1:
- one row per event : EnergyAbs EnergyGap
- Ntuple2:
- one row per event : TrackLAbs TrackLGap
These histos and ntuples are booked in HistoManager and filled from
These histos and ntuples are booked in HistoManager and filled from
EventAction.
One can control the name of the histograms file and its format:
default name : AnaEx01
default name : AnaEx01
The format of the histogram file can be : root (default),
xml, csv. Include correct g4nnn.hh in HistoManager.hh
6- How to build
---------------
xml, csv.
We can define the default file type and set it to the analysis manager via
/analysis/setDefaultFileType root # or csv hdf5 xml
The file names then need not to be provided with the file extension and the same macro
can be used with different output types.
6- Macros:
----------
The AnaEx01.in macro uses the defaultFileType parameter (alias), which default value,
"root" is defined in main.
AnaEx01-csv.in, AnaEx01-hdf5.in, AnaEx01-root.in, AnaEx01-xml.in:
In these macros, the default value of the defaultFileType is overritten with
/control/alias defaultFileType cvs # or hdf5 root xml
and then the AnaEx01.in macro is called.
7- How to build
---------------
An additional step is needed when building the example with GNUmake
due to using the extra shared directory:
due to using the extra shared directory:
% cd path_to_AnaEx01/AnaEx01
% gmake setup
% gmake
@@ -116,15 +137,15 @@
to remove these files:
% gmake clean_setup
7- How to run
8- How to run
--------------
- Execute AnaEx01 in the 'interactive mode' with visualization
% ./AnaEx01
and type in the commands from run.mac line by line:
and type in the commands from run.mac line by line:
Idle> /control/verbose 2
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> /run/beamOn 10
Idle> ...
Idle> exit
or
@@ -0,0 +1,2 @@
This directory will be used for saving histogram files
when running AnaEx01 example with the Csv output type
@@ -27,9 +27,9 @@
/// \brief Definition of the HistoManager class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef HistoManager_h
#define HistoManager_h 1
@@ -47,17 +47,17 @@ class HistoManager
void Book();
void Save();
void FillHisto(G4int id, G4double e, G4double weight = 1.0);
void Normalize(G4int id, G4double fac);
void Normalize(G4int id, G4double fac);
void FillNtuple(G4double EnergyAbs, G4double EnergyGap,
G4double TrackLAbs, G4double TrackLGap);
void PrintStatistic();
void PrintStatistic();
private:
G4bool fFactoryOn;
G4bool fFactoryOn = false;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,2 @@
This directory will be used for saving ntuple files
when running AnaEx01 example with the Csv output type
+15 -15
View File
@@ -1,22 +1,22 @@
{
gROOT->Reset();
// Draw histos filled by Geant4 simulation
//
TFile f = TFile("AnaEx01.root");
// Draw histos filled by Geant4 simulation
//
TFile f = TFile("AnaEx01.root");
TCanvas* c1 = new TCanvas("c1", " ");
TDirectory* dir = f.Get("histo");
TH1D* hist1 = (TH1D*)dir->Get("1");
TH1D* hist1 = (TH1D*)dir->Get("1");
hist1->Draw("HIST");
TH1D* hist2 = (TH1D*)dir->Get("2");
TH1D* hist2 = (TH1D*)dir->Get("2");
hist2->Draw("HIST");
TH1D* hist3 = (TH1D*)dir->Get("3");
TH1D* hist3 = (TH1D*)dir->Get("3");
hist3->Draw("HIST");
TH1D* hist4 = (TH1D*)dir->Get("4");
hist4->Draw("HIST");
}
TH1D* hist4 = (TH1D*)dir->Get("4");
hist4->Draw("HIST");
}
@@ -21,7 +21,7 @@ be used as a substitute for writing good git commit messages!
03-07-18 I. Hrivnacova (analysisShared-V10-04-00)
- Macro & commands review:
- Removed obsolete /N03 top command directory
- Added protection against warnings issued from ReinitializeGeometry() if
- Added protection against warnings issued from ReinitializeGeometry() if
called in PreInit phase
04-07-16 I. Hrivnacova (analysisShared-V10-02-01)
@@ -33,9 +33,9 @@ be used as a substitute for writing good git commit messages!
27-08-15 I. Hrivnacova (analysisShared-V10-01-00)
- Updated histogram ids in FillHiso (now starting from 0);
updated for changed function names in HistoManager classes
06-11-14 I. Hrivnacova (analysisShared-V10-00-01)
- Moved scripts from upper directory in shared
05-11-14 I. Hrivnacova (analysisShared-V10-00-00)
- Tagged version which will be included in AnaEx0N examples
@@ -41,15 +41,15 @@ class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization(DetectorConstruction* detector);
virtual ~ActionInitialization();
~ActionInitialization() override;
virtual void BuildForMaster() const;
virtual void Build() const;
void BuildForMaster() const override;
void Build() const override;
private:
DetectorConstruction* fDetector;
DetectorConstruction* fDetector = nullptr;
};
#endif
@@ -25,10 +25,6 @@
//
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -39,6 +35,8 @@
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "CLHEP/Units/SystemOfUnits.h"
class G4Box;
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -50,90 +48,82 @@ class DetectorMessenger;
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
virtual ~DetectorConstruction();
DetectorConstruction();
~DetectorConstruction() override;
public:
void SetAbsorberMaterial (G4String);
void SetAbsorberThickness(G4double);
G4VPhysicalVolume* Construct() override;
void SetGapMaterial (G4String);
void SetGapThickness(G4double);
void SetCalorSizeYZ(G4double);
void SetNbOfLayers (G4int);
virtual G4VPhysicalVolume* Construct();
void SetAbsorberMaterial (const G4String&);
void SetAbsorberThickness(G4double);
void SetGapMaterial (const G4String&);
void SetGapThickness(G4double);
void SetCalorSizeYZ(G4double);
void SetNbOfLayers (G4int);
void PrintCalorParameters();
G4double GetWorldSizeX() { return fWorldSizeX; }
G4double GetWorldSizeYZ() { return fWorldSizeYZ; }
G4double GetCalorThickness() { return fCalorThickness; }
G4double GetCalorSizeYZ() { return fCalorSizeYZ; }
G4int GetNbOfLayers() { return fNbOfLayers; }
G4Material* GetAbsorberMaterial() { return fAbsorberMaterial; }
G4double GetAbsorberThickness() { return fAbsorberThickness; }
G4Material* GetGapMaterial() { return fGapMaterial; }
G4double GetGapThickness() { return fGapThickness; }
const G4VPhysicalVolume* GetphysiWorld() { return fPhysiWorld; }
const G4VPhysicalVolume* GetAbsorber() { return fPhysiAbsorber; }
const G4VPhysicalVolume* GetGap() { return fPhysiGap; }
public:
void PrintCalorParameters();
G4double GetWorldSizeX() {return fWorldSizeX;};
G4double GetWorldSizeYZ() {return fWorldSizeYZ;};
G4double GetCalorThickness() {return fCalorThickness;};
G4double GetCalorSizeYZ() {return fCalorSizeYZ;};
G4int GetNbOfLayers() {return fNbOfLayers;};
G4Material* GetAbsorberMaterial() {return fAbsorberMaterial;};
G4double GetAbsorberThickness() {return fAbsorberThickness;};
G4Material* GetGapMaterial() {return fGapMaterial;};
G4double GetGapThickness() {return fGapThickness;};
const G4VPhysicalVolume* GetphysiWorld() {return fPhysiWorld;};
const G4VPhysicalVolume* GetAbsorber() {return fPhysiAbsorber;};
const G4VPhysicalVolume* GetGap() {return fPhysiGap;};
private:
G4Material* fAbsorberMaterial;
G4double fAbsorberThickness;
G4Material* fGapMaterial;
G4double fGapThickness;
G4int fNbOfLayers;
G4double fLayerThickness;
G4double fCalorSizeYZ;
G4double fCalorThickness;
G4Material* fDefaultMaterial;
G4double fWorldSizeYZ;
G4double fWorldSizeX;
G4Box* fSolidWorld; //pointer to the solid World
G4LogicalVolume* fLogicWorld; //pointer to the logical World
G4VPhysicalVolume* fPhysiWorld; //pointer to the physical World
void DefineMaterials();
void ComputeCalorParameters();
G4VPhysicalVolume* ConstructCalorimeter();
G4Box* fSolidCalor; //pointer to the solid Calor
G4LogicalVolume* fLogicCalor; //pointer to the logical Calor
G4VPhysicalVolume* fPhysiCalor; //pointer to the physical Calor
G4Box* fSolidLayer; //pointer to the solid Layer
G4LogicalVolume* fLogicLayer; //pointer to the logical Layer
G4VPhysicalVolume* fPhysiLayer; //pointer to the physical Layer
G4Box* fSolidAbsorber; //pointer to the solid Absorber
G4LogicalVolume* fLogicAbsorber; //pointer to the logical Absorber
G4VPhysicalVolume* fPhysiAbsorber; //pointer to the physical Absorber
G4Box* fSolidGap; //pointer to the solid Gap
G4LogicalVolume* fLogicGap; //pointer to the logical Gap
G4VPhysicalVolume* fPhysiGap; //pointer to the physical Gap
DetectorMessenger* fDetectorMessenger; //pointer to the Messenger
private:
void DefineMaterials();
void ComputeCalorParameters();
G4VPhysicalVolume* ConstructCalorimeter();
G4Material* fAbsorberMaterial = nullptr;
G4Material* fGapMaterial = nullptr;
G4Material* fDefaultMaterial = nullptr;
G4int fNbOfLayers = 10;
G4double fAbsorberThickness = 10.*CLHEP::mm;
G4double fGapThickness = 5.*CLHEP::mm;
G4double fCalorSizeYZ = 10.*CLHEP::cm;
G4double fCalorThickness = 0.; // will be computed
G4double fLayerThickness= 0.; // will be computed
G4double fWorldSizeYZ = 0.; // will be computed;
G4double fWorldSizeX = 0.; // will be computed;
G4Box* fSolidWorld = nullptr; //pointer to the solid World
G4LogicalVolume* fLogicWorld = nullptr; //pointer to the logical World
G4VPhysicalVolume* fPhysiWorld = nullptr; //pointer to the physical World
G4Box* fSolidCalor = nullptr; //pointer to the solid Calor
G4LogicalVolume* fLogicCalor = nullptr; //pointer to the logical Calor
G4VPhysicalVolume* fPhysiCalor = nullptr; //pointer to the physical Calor
G4Box* fSolidLayer = nullptr; //pointer to the solid Layer
G4LogicalVolume* fLogicLayer = nullptr; //pointer to the logical Layer
G4VPhysicalVolume* fPhysiLayer = nullptr; //pointer to the physical Layer
G4Box* fSolidAbsorber = nullptr; //pointer to the solid Absorber
G4LogicalVolume* fLogicAbsorber = nullptr; //pointer to the logical Absorber
G4VPhysicalVolume* fPhysiAbsorber = nullptr; //pointer to the physical Absorber
G4Box* fSolidGap = nullptr; //pointer to the solid Gap
G4LogicalVolume* fLogicGap = nullptr; //pointer to the logical Gap
G4VPhysicalVolume* fPhysiGap = nullptr; //pointer to the physical Gap
DetectorMessenger* fDetectorMessenger = nullptr; //pointer to the Messenger
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -141,10 +131,10 @@ class DetectorConstruction : public G4VUserDetectorConstruction
inline void DetectorConstruction::ComputeCalorParameters()
{
// Compute derived parameters of the calorimeter
fLayerThickness = fAbsorberThickness + fGapThickness;
fCalorThickness = fNbOfLayers*fLayerThickness;
fWorldSizeX = 1.2*fCalorThickness; fWorldSizeYZ = 1.2*fCalorSizeYZ;
fLayerThickness = fAbsorberThickness + fGapThickness;
fCalorThickness = fNbOfLayers*fLayerThickness;
fWorldSizeX = 1.2*fCalorThickness; fWorldSizeYZ = 1.2*fCalorSizeYZ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,7 +40,6 @@ class G4UIdirectory;
class G4UIcmdWithAString;
class G4UIcmdWithAnInteger;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -52,23 +47,22 @@ class DetectorMessenger: public G4UImessenger
{
public:
DetectorMessenger(DetectorConstruction* );
virtual ~DetectorMessenger();
virtual void SetNewValue(G4UIcommand*, G4String);
~DetectorMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetDir;
G4UIcmdWithAString* fAbsMaterCmd;
G4UIcmdWithAString* fGapMaterCmd;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd;
G4UIcmdWithADoubleAndUnit* fGapThickCmd;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd;
G4UIcmdWithAnInteger* fNbLayersCmd;
DetectorConstruction* fDetector = nullptr;
G4UIdirectory* fDetDir = nullptr;
G4UIcmdWithAString* fAbsMaterCmd = nullptr;
G4UIcmdWithAString* fGapMaterCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fGapThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd = nullptr;
G4UIcmdWithAnInteger* fNbLayersCmd = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,26 +48,28 @@ class EventAction : public G4UserEventAction
{
public:
EventAction(RunAction*, HistoManager*);
virtual ~EventAction();
~EventAction() override;
void BeginOfEventAction(const G4Event*) override;
void EndOfEventAction(const G4Event*) override;
virtual void BeginOfEventAction(const G4Event*);
virtual void EndOfEventAction(const G4Event*);
void AddAbs(G4double de, G4double dl) {fEnergyAbs += de; fTrackLAbs += dl;};
void AddGap(G4double de, G4double dl) {fEnergyGap += de; fTrackLGap += dl;};
private:
RunAction* fRunAct;
HistoManager* fHistoManager;
G4double fEnergyAbs, fEnergyGap;
G4double fTrackLAbs, fTrackLGap;
G4int fPrintModulo;
RunAction* fRunAct = nullptr;
HistoManager* fHistoManager = nullptr;
G4double fEnergyAbs = 0.;
G4double fEnergyGap = 0;
G4double fTrackLAbs = 0;
G4double fTrackLGap = 0;
G4int fPrintModulo = 100;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -25,10 +25,6 @@
//
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,14 +44,14 @@ class DetectorConstruction;
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction(DetectorConstruction*);
virtual ~PrimaryGeneratorAction();
PrimaryGeneratorAction(DetectorConstruction*);
~PrimaryGeneratorAction() override;
virtual void GeneratePrimaries(G4Event*);
void GeneratePrimaries(G4Event*) override;
private:
G4ParticleGun* fParticleGun; //pointer a to G4 class
DetectorConstruction* fDetector; //pointer to the geometry
G4ParticleGun* fParticleGun = nullptr; //pointer a to G4 class
DetectorConstruction* fDetector = nullptr; //pointer to the geometry
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -37,6 +37,7 @@
#define RunAction_h 1
#include "G4UserRunAction.hh"
#include "G4Accumulable.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,21 +49,25 @@ class RunAction : public G4UserRunAction
{
public:
RunAction(HistoManager*);
virtual ~RunAction();
~RunAction() override;
virtual void BeginOfRunAction(const G4Run*);
virtual void EndOfRunAction(const G4Run*);
void FillPerEvent(G4double, G4double, G4double, G4double);
void BeginOfRunAction(const G4Run*) override;
void EndOfRunAction(const G4Run*) override;
void FillPerEvent(G4double, G4double, G4double, G4double);
private:
HistoManager* fHistoManager;
HistoManager* fHistoManager = nullptr;
G4double fSumEAbs, fSum2EAbs;
G4double fSumEGap, fSum2EGap;
G4double fSumLAbs, fSum2LAbs;
G4double fSumLGap, fSum2LGap;
G4Accumulable<G4double> fSumEAbs = 0.;
G4Accumulable<G4double> fSum2EAbs = 0.;
G4Accumulable<G4double> fSumEGap = 0.;
G4Accumulable<G4double> fSum2EGap = 0.;
G4Accumulable<G4double> fSumLAbs = 0.;
G4Accumulable<G4double> fSum2LAbs = 0.;
G4Accumulable<G4double> fSumLGap = 0.;
G4Accumulable<G4double> fSum2LGap = 0.;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -47,13 +43,13 @@ class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction(DetectorConstruction*, EventAction*);
virtual ~SteppingAction();
~SteppingAction() override;
void UserSteppingAction(const G4Step*) override;
virtual void UserSteppingAction(const G4Step*);
private:
DetectorConstruction* fDetector;
EventAction* fEventAction;
DetectorConstruction* fDetector = nullptr;
EventAction* fEventAction = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -11,6 +11,6 @@ be used as a substitute for writing good git commit messages!
---
# History entries prior to 11.0
05-11-14 I. Hrivnacova (analysisScripts-V10-00-00)
- Tagged version which will be included in AnaEx0N examples
@@ -9,10 +9,10 @@ DIRNAME=$1
for FILE in `ls $DIRNAME/include`; do
rm -f include/$FILE
done
done
for FILE in `ls $DIRNAME/src`; do
rm -f src/$FILE
done
done
echo "... clean_files.sh from $1 finished"
@@ -37,22 +37,20 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization(DetectorConstruction* detector)
: G4VUserActionInitialization(),
fDetector(detector)
: fDetector(detector)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{}
ActionInitialization::~ActionInitialization() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
{
// Histo manager
HistoManager* histo = new HistoManager();
auto histo = new HistoManager();
// Actions
SetUserAction(new RunAction(histo));
}
@@ -62,20 +60,20 @@ void ActionInitialization::BuildForMaster() const
void ActionInitialization::Build() const
{
// Histo manager
HistoManager* histo = new HistoManager();
auto histo = new HistoManager();
// Actions
//
SetUserAction(new PrimaryGeneratorAction(fDetector));
RunAction* runAction = new RunAction(histo);
auto runAction = new RunAction(histo);
SetUserAction(runAction);
EventAction* eventAction = new EventAction(runAction, histo);
auto eventAction = new EventAction(runAction, histo);
SetUserAction(eventAction);
SteppingAction* steppingAction = new SteppingAction(fDetector, eventAction);
auto steppingAction = new SteppingAction(fDetector, eventAction);
SetUserAction(steppingAction);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -58,27 +54,14 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
:G4VUserDetectorConstruction(),
fAbsorberMaterial(0),fGapMaterial(0),fDefaultMaterial(0),
fSolidWorld(0),fLogicWorld(0),fPhysiWorld(0),
fSolidCalor(0),fLogicCalor(0),fPhysiCalor(0),
fSolidLayer(0),fLogicLayer(0),fPhysiLayer(0),
fSolidAbsorber(0),fLogicAbsorber(0),fPhysiAbsorber(0),
fSolidGap (0),fLogicGap (0),fPhysiGap (0),
fDetectorMessenger(0)
{
// default parameter values of the calorimeter
fAbsorberThickness = 10.*mm;
fGapThickness = 5.*mm;
fNbOfLayers = 10;
fCalorSizeYZ = 10.*cm;
ComputeCalorParameters();
// materials
DefineMaterials();
SetAbsorberMaterial("G4_Pb");
SetGapMaterial("G4_lAr");
// create commands for interactive definition of the calorimeter
fDetectorMessenger = new DetectorMessenger(this);
}
@@ -86,7 +69,9 @@ DetectorConstruction::DetectorConstruction()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{ delete fDetectorMessenger;}
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -98,24 +83,23 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineMaterials()
{
// use G4-NIST materials data base
//
G4NistManager* man = G4NistManager::Instance();
fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
man->FindOrBuildMaterial("G4_Pb");
man->FindOrBuildMaterial("G4_lAr");
{
// use G4-NIST materials data base
//
G4NistManager* man = G4NistManager::Instance();
fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
man->FindOrBuildMaterial("G4_Pb");
man->FindOrBuildMaterial("G4_lAr");
// print table
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
// print table
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
{
// Clean old geometry, if any
//
G4GeometryManager::GetInstance()->OpenGeometry();
@@ -125,126 +109,128 @@ G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
// complete the Calor parameters definition
ComputeCalorParameters();
//
//
// World
//
fSolidWorld = new G4Box("World", //its name
fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
fSolidWorld = new G4Box("World", //its name
fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
fLogicWorld = new G4LogicalVolume(fSolidWorld, //its solid
fDefaultMaterial, //its material
"World"); //its name
fPhysiWorld = new G4PVPlacement(0, //no rotation
fPhysiWorld = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicWorld, //its logical volume
fLogicWorld, //its logical volume
"World", //its name
0, //its mother volume
false, //no boolean operation
nullptr, //its mother volume
false, //no boolean operation
0); //copy number
//
// Calorimeter
//
fSolidCalor=0; fLogicCalor=0; fPhysiCalor=0;
fSolidLayer=0; fLogicLayer=0; fPhysiLayer=0;
if (fCalorThickness > 0.)
{ fSolidCalor = new G4Box("Calorimeter", //its name
fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);//size
fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
fDefaultMaterial, //its material
"Calorimeter"); //its name
fPhysiCalor = new G4PVPlacement(0, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicCalor, //its logical volume
"Calorimeter", //its name
fLogicWorld, //its mother volume
false, //no boolean operation
0); //copy number
//
// Layer
//
// Calorimeter
//
fSolidCalor = nullptr; fLogicCalor = nullptr; fPhysiCalor = nullptr;
fSolidLayer = nullptr; fLogicLayer = nullptr; fPhysiLayer = nullptr;
if (fCalorThickness > 0.) {
fSolidCalor = new G4Box("Calorimeter", //its name
fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
fDefaultMaterial, //its material
"Calorimeter"); //its name
fPhysiCalor = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicCalor, //its logical volume
"Calorimeter", //its name
fLogicWorld, //its mother volume
false, //no boolean operation
0); //copy number
//
// Layer
//
fSolidLayer = new G4Box("Layer", //its name
fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
fDefaultMaterial, //its material
"Layer"); //its name
if (fNbOfLayers > 1) {
fPhysiLayer = new G4PVReplica("Layer", //its name
fLogicLayer, //its logical volume
fLogicCalor, //its mother
kXAxis, //axis of replication
fNbOfLayers, //number of replica
fLayerThickness); //witdth of replica
}
else {
fPhysiLayer = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicLayer, //its logical volume
"Layer", //its name
fLogicCalor, //its mother volume
false, //no boolean operation
0); //copy number
}
}
//
fSolidLayer = new G4Box("Layer", //its name
fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
fDefaultMaterial, //its material
"Layer"); //its name
if (fNbOfLayers > 1)
fPhysiLayer = new G4PVReplica("Layer", //its name
fLogicLayer, //its logical volume
fLogicCalor, //its mother
kXAxis, //axis of replication
fNbOfLayers, //number of replica
fLayerThickness); //witdth of replica
else
fPhysiLayer = new G4PVPlacement(0, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicLayer, //its logical volume
"Layer", //its name
fLogicCalor, //its mother volume
false, //no boolean operation
0); //copy number
}
//
// Absorber
//
fSolidAbsorber=0; fLogicAbsorber=0; fPhysiAbsorber=0;
if (fAbsorberThickness > 0.)
{ fSolidAbsorber = new G4Box("Absorber", //its name
fAbsorberThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, //its solid
fAbsorberMaterial, //its material
fAbsorberMaterial->GetName());//name
fPhysiAbsorber = new G4PVPlacement(0, //no rotation
G4ThreeVector(-fGapThickness/2,0.,0.), //its position
fLogicAbsorber, //its logical volume
fAbsorberMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
//
fSolidAbsorber = nullptr; fLogicAbsorber = nullptr; fPhysiAbsorber = nullptr;
if (fAbsorberThickness > 0.) {
fSolidAbsorber = new G4Box("Absorber", //its name
fAbsorberThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, //its solid
fAbsorberMaterial, //its material
fAbsorberMaterial->GetName()); //name
fPhysiAbsorber = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(-fGapThickness/2,0.,0.), //its position
fLogicAbsorber, //its logical volume
fAbsorberMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
//
// Gap
//
fSolidGap=0; fLogicGap=0; fPhysiGap=0;
if (fGapThickness > 0.)
{ fSolidGap = new G4Box("Gap",
fGapThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicGap = new G4LogicalVolume(fSolidGap,
fGapMaterial,
fGapMaterial->GetName());
fPhysiGap = new G4PVPlacement(0, //no rotation
G4ThreeVector(fAbsorberThickness/2,0.,0.), //its position
fLogicGap, //its logical volume
fGapMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
PrintCalorParameters();
//
fSolidGap = nullptr; fLogicGap = nullptr; fPhysiGap = nullptr;
if (fGapThickness > 0.) {
fSolidGap = new G4Box("Gap",
fGapThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicGap = new G4LogicalVolume(fSolidGap,
fGapMaterial,
fGapMaterial->GetName());
fPhysiGap = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(fAbsorberThickness/2,0.,0.), //its position
fLogicGap, //its logical volume
fGapMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
PrintCalorParameters();
//
// Visualization attributes
//
fLogicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
auto simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
simpleBoxVisAtt->SetVisibility(true);
fLogicCalor->SetVisAttributes(simpleBoxVisAtt);
@@ -260,54 +246,47 @@ void DetectorConstruction::PrintCalorParameters()
{
G4cout << "\n------------------------------------------------------------"
<< "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ "
<< fAbsorberThickness/mm << "mm of " << fAbsorberMaterial->GetName()
<< fAbsorberThickness/mm << "mm of " << fAbsorberMaterial->GetName()
<< " + "
<< fGapThickness/mm << "mm of " << fGapMaterial->GetName() << " ] "
<< fGapThickness/mm << "mm of " << fGapMaterial->GetName() << " ] "
<< "\n------------------------------------------------------------\n";
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
{
// search the material by its name
G4Material* pttoMaterial =
G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (pttoMaterial)
{
fAbsorberMaterial = pttoMaterial;
if ( fLogicAbsorber )
{
fLogicAbsorber->SetMaterial(fAbsorberMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapMaterial(G4String materialChoice)
void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
{
// search the material by its name
G4Material* pttoMaterial =
G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (pttoMaterial)
{
fGapMaterial = pttoMaterial;
if ( fLogicGap )
{
fLogicGap->SetMaterial(fGapMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fAbsorberMaterial = material;
if (fLogicAbsorber != nullptr) {
fLogicAbsorber->SetMaterial(fAbsorberMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberThickness(G4double val)
void DetectorConstruction::SetGapMaterial(const G4String& materialChoice)
{
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fGapMaterial = material;
if ( fLogicGap != nullptr) {
fLogicGap->SetMaterial(fGapMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberThickness(G4double value)
{
// change Absorber thickness and recompute the calorimeter parameters
fAbsorberThickness = val;
fAbsorberThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -315,10 +294,10 @@ void DetectorConstruction::SetAbsorberThickness(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapThickness(G4double val)
void DetectorConstruction::SetGapThickness(G4double value)
{
// change Gap thickness and recompute the calorimeter parameters
fGapThickness = val;
fGapThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -326,10 +305,10 @@ void DetectorConstruction::SetGapThickness(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetCalorSizeYZ(G4double val)
void DetectorConstruction::SetCalorSizeYZ(G4double value)
{
// change the transverse size and recompute the calorimeter parameters
fCalorSizeYZ = val;
fCalorSizeYZ = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -337,9 +316,9 @@ void DetectorConstruction::SetCalorSizeYZ(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetNbOfLayers(G4int val)
void DetectorConstruction::SetNbOfLayers(G4int value)
{
fNbOfLayers = val;
fNbOfLayers = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.cc
/// \brief Implementation of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -45,57 +41,48 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
: G4UImessenger(),
fDetector(Det),
fDetDir(0),
fAbsMaterCmd(0),
fGapMaterCmd(0),
fAbsThickCmd(0),
fGapThickCmd(0),
fSizeYZCmd(0),
fNbLayersCmd(0)
{
: fDetector(Det)
{
G4bool broadcast = false;
fDetDir = new G4UIdirectory("/det/",broadcast);
fDetDir->SetGuidance("Detector control");
fAbsMaterCmd = new G4UIcmdWithAString("/det/setAbsMat",this);
fAbsMaterCmd->SetGuidance("Select Material of the Absorber.");
fAbsMaterCmd->SetParameterName("choice",false);
fAbsMaterCmd->SetParameterName("AbsMat",false);
fAbsMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapMaterCmd = new G4UIcmdWithAString("/det/setGapMat",this);
fGapMaterCmd->SetGuidance("Select Material of the Gap.");
fGapMaterCmd->SetParameterName("choice",false);
fGapMaterCmd->SetParameterName("GapMat",false);
fGapMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fAbsThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setAbsThick",this);
fAbsThickCmd->SetGuidance("Set Thickness of the Absorber");
fAbsThickCmd->SetParameterName("Size",false);
fAbsThickCmd->SetRange("Size>=0.");
fAbsThickCmd->SetParameterName("AbsThick",false);
fAbsThickCmd->SetRange("AbsThick>=0.");
fAbsThickCmd->SetUnitCategory("Length");
fAbsThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setGapThick",this);
fGapThickCmd->SetGuidance("Set Thickness of the Gap");
fGapThickCmd->SetParameterName("Size",false);
fGapThickCmd->SetRange("Size>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->SetParameterName("GapThick",false);
fGapThickCmd->SetRange("GapThick>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fSizeYZCmd = new G4UIcmdWithADoubleAndUnit("/det/setSizeYZ",this);
fSizeYZCmd->SetGuidance("Set tranverse size of the calorimeter");
fSizeYZCmd->SetParameterName("Size",false);
fSizeYZCmd->SetRange("Size>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->SetParameterName("SizeYZ",false);
fSizeYZCmd->SetRange("SizeYZ>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fNbLayersCmd = new G4UIcmdWithAnInteger("/det/setNbOfLayers",this);
fNbLayersCmd->SetGuidance("Set number of layers.");
fNbLayersCmd->SetParameterName("NbLayers",false);
fNbLayersCmd->SetRange("NbLayers>0 && NbLayers<500");
fNbLayersCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -103,34 +90,46 @@ DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
DetectorMessenger::~DetectorMessenger()
{
delete fNbLayersCmd;
delete fAbsMaterCmd; delete fGapMaterCmd;
delete fAbsThickCmd; delete fGapThickCmd;
delete fSizeYZCmd;
delete fAbsMaterCmd;
delete fGapMaterCmd;
delete fAbsThickCmd;
delete fGapThickCmd;
delete fSizeYZCmd;
delete fDetDir;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == fAbsMaterCmd ) {
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if( command == fAbsMaterCmd ) {
fDetector->SetAbsorberMaterial(newValue);
}
else if( command == fGapMaterCmd ) {
return;
}
if( command == fGapMaterCmd ) {
fDetector->SetGapMaterial(newValue);
return;
}
else if( command == fAbsThickCmd ) {
fDetector
->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
}
else if( command == fGapThickCmd ) {
if( command == fAbsThickCmd ) {
fDetector->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
return;
}
if( command == fGapThickCmd ) {
fDetector->SetGapThickness(fGapThickCmd->GetNewDoubleValue(newValue));
return;
}
else if( command == fSizeYZCmd ) {
if( command == fSizeYZCmd ) {
fDetector->SetCalorSizeYZ(fSizeYZCmd->GetNewDoubleValue(newValue));
}
else if( command == fNbLayersCmd ) {
return;
}
if( command == fNbLayersCmd ) {
fDetector->SetNbOfLayers(fNbLayersCmd->GetNewIntValue(newValue));
return;
}
}
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -43,30 +43,25 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction(RunAction* run, HistoManager* histo)
:G4UserEventAction(),
fRunAct(run),fHistoManager(histo),
fEnergyAbs(0.), fEnergyGap(0.),
fTrackLAbs(0.), fTrackLGap(0.),
fPrintModulo(0)
{
fPrintModulo = 100; }
: fRunAct(run),fHistoManager(histo)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{ }
EventAction::~EventAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event* evt)
{
{
G4int evtNb = evt->GetEventID();
if (evtNb%fPrintModulo == 0)
if (evtNb%fPrintModulo == 0) {
G4cout << "\n---> Begin of event: " << evtNb << G4endl;
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -76,17 +71,17 @@ void EventAction::EndOfEventAction(const G4Event*)
//accumulates statistic
//
fRunAct->FillPerEvent(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
//fill histograms
//
fHistoManager->FillHisto(0, fEnergyAbs);
fHistoManager->FillHisto(1, fEnergyGap);
fHistoManager->FillHisto(2, fTrackLAbs);
fHistoManager->FillHisto(3, fTrackLGap);
//fill ntuple
//
fHistoManager->FillNtuple(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,7 @@
//
/// \file PrimaryGeneratorAction.cc
/// \brief Implementation of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,10 +41,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
: G4VUserPrimaryGeneratorAction(),
fParticleGun(0),
fDetector(DC)
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* dc)
: fDetector(dc)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
@@ -56,8 +51,7 @@ PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition* particle
= particleTable->FindParticle(particleName="e-");
G4ParticleDefinition* particle = particleTable->FindParticle(particleName="e-");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.));
fParticleGun->SetParticleEnergy(500.*MeV);
@@ -78,7 +72,7 @@ PrimaryGeneratorAction::~PrimaryGeneratorAction()
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
//this function is called at the begining of event
//
//
fParticleGun->GeneratePrimaryVertex(anEvent);
}
@@ -36,105 +36,136 @@
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4AccumulableManager.hh"
#include "G4UnitsTable.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(HistoManager* histo)
: G4UserRunAction(),
fHistoManager(histo),
fSumEAbs(0.), fSum2EAbs(0.),
fSumEGap(0.), fSum2EGap(0.),
fSumLAbs(0.), fSum2LAbs(0.),
fSumLGap(0.), fSum2LGap(0.)
{}
: fHistoManager(histo)
{
// Register accumulable to the accumulable manager
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->RegisterAccumulable(fSumEAbs);
accumulableManager->RegisterAccumulable(fSum2EAbs);
accumulableManager->RegisterAccumulable(fSumEGap);
accumulableManager->RegisterAccumulable(fSum2EGap);
accumulableManager->RegisterAccumulable(fSumLAbs);
accumulableManager->RegisterAccumulable(fSum2LAbs);
accumulableManager->RegisterAccumulable(fSumLGap);
accumulableManager->RegisterAccumulable(fSum2LGap);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{}
RunAction::~RunAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
{
G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl;
//initialize cumulative quantities
//
fSumEAbs = fSum2EAbs =fSumEGap = fSum2EGap = 0.;
fSumLAbs = fSum2LAbs =fSumLGap = fSum2LGap = 0.;
// reset accumulables to their initial values
G4AccumulableManager::Instance()->Reset();
//histograms
//
fHistoManager->Book();
fHistoManager->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::FillPerEvent(G4double EAbs, G4double EGap,
G4double LAbs, G4double LGap)
G4double LAbs, G4double LGap)
{
//accumulate statistic
//
fSumEAbs += EAbs; fSum2EAbs += EAbs*EAbs;
fSumEGap += EGap; fSum2EGap += EGap*EGap;
fSumLAbs += LAbs; fSum2LAbs += LAbs*LAbs;
fSumLGap += LGap; fSum2LGap += LGap*LGap;
fSumLGap += LGap; fSum2LGap += LGap*LGap;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run* aRun)
{
G4int NbOfEvents = aRun->GetNumberOfEvent();
if (NbOfEvents == 0) {
// Merge accumulables
G4AccumulableManager::Instance()->Merge();
G4int nofEvents = aRun->GetNumberOfEvent();
if (nofEvents == 0) {
// close open files
fHistoManager->Save();
return;
}
//compute statistics: mean and rms
//
fSumEAbs /= NbOfEvents; fSum2EAbs /= NbOfEvents;
G4double rmsEAbs = fSum2EAbs - fSumEAbs*fSumEAbs;
if (rmsEAbs >0.) rmsEAbs = std::sqrt(rmsEAbs); else rmsEAbs = 0.;
fSumEGap /= NbOfEvents; fSum2EGap /= NbOfEvents;
G4double rmsEGap = fSum2EGap - fSumEGap*fSumEGap;
if (rmsEGap >0.) rmsEGap = std::sqrt(rmsEGap); else rmsEGap = 0.;
fSumLAbs /= NbOfEvents; fSum2LAbs /= NbOfEvents;
G4double rmsLAbs = fSum2LAbs - fSumLAbs*fSumLAbs;
if (rmsLAbs >0.) rmsLAbs = std::sqrt(rmsLAbs); else rmsLAbs = 0.;
fSumLGap /= NbOfEvents; fSum2LGap /= NbOfEvents;
G4double rmsLGap = fSum2LGap - fSumLGap*fSumLGap;
if (rmsLGap >0.) rmsLGap = std::sqrt(rmsLGap); else rmsLGap = 0.;
auto sumEAbs = fSumEAbs.GetValue();
auto sum2EAbs = fSum2EAbs.GetValue();
sumEAbs /= nofEvents; sum2EAbs /= nofEvents;
auto rmsEAbs = sum2EAbs - sumEAbs*sumEAbs;
if (rmsEAbs >0.) {
rmsEAbs = std::sqrt(rmsEAbs);
} else {
rmsEAbs = 0.;
}
auto sumEGap = fSumEGap.GetValue();
auto sum2EGap = fSum2EGap.GetValue();
sumEGap /= nofEvents; sum2EGap /= nofEvents;
auto rmsEGap = sum2EGap - sumEGap*sumEGap;
if (rmsEGap >0.) {
rmsEGap = std::sqrt(rmsEGap);
} else {
rmsEGap = 0.;
}
auto sumLAbs = fSumLAbs.GetValue();
auto sum2LAbs = fSum2LAbs.GetValue();
sumLAbs /= nofEvents; sum2LAbs /= nofEvents;
auto rmsLAbs = sum2LAbs - sumLAbs*sumLAbs;
if (rmsLAbs >0.) {
rmsLAbs = std::sqrt(rmsLAbs);
} else {
rmsLAbs = 0.;
}
auto sumLGap = fSumLGap.GetValue();
auto sum2LGap = fSum2LGap.GetValue();
sumLGap /= nofEvents; sum2LGap /= nofEvents;
G4double rmsLGap = sum2LGap - sumLGap*sumLGap;
if (rmsLGap >0.) {
rmsLGap = std::sqrt(rmsLGap);
} else {
rmsLGap = 0.;
}
//print
//
G4cout
<< "\n--------------------End of Run------------------------------\n"
<< "\n mean Energy in Absorber : " << G4BestUnit(fSumEAbs,"Energy")
<< " +- " << G4BestUnit(rmsEAbs,"Energy")
<< "\n mean Energy in Gap : " << G4BestUnit(fSumEGap,"Energy")
<< "\n mean Energy in Absorber : " << G4BestUnit(sumEAbs,"Energy")
<< " +- " << G4BestUnit(rmsEAbs,"Energy")
<< "\n mean Energy in Gap : " << G4BestUnit(sumEGap,"Energy")
<< " +- " << G4BestUnit(rmsEGap,"Energy")
<< G4endl;
G4cout
<< "\n mean trackLength in Absorber : " << G4BestUnit(fSumLAbs,"Length")
<< " +- " << G4BestUnit(rmsLAbs,"Length")
<< "\n mean trackLength in Gap : " << G4BestUnit(fSumLGap,"Length")
<< "\n mean trackLength in Absorber : " << G4BestUnit(sumLAbs,"Length")
<< " +- " << G4BestUnit(rmsLAbs,"Length")
<< "\n mean trackLength in Gap : " << G4BestUnit(sumLGap,"Length")
<< " +- " << G4BestUnit(rmsLGap,"Length")
<< "\n------------------------------------------------------------\n"
<< G4endl;
//save histograms
//
fHistoManager->PrintStatistic();
fHistoManager->Save();
fHistoManager->Save();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,7 @@
//
/// \file SteppingAction.cc
/// \brief Implementation of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,34 +38,32 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction(DetectorConstruction* det,
EventAction* evt)
: G4UserSteppingAction(),
fDetector(det), fEventAction(evt)
{ }
SteppingAction::SteppingAction(DetectorConstruction* det, EventAction* evt)
: fDetector(det), fEventAction(evt)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::~SteppingAction()
{ }
SteppingAction::~SteppingAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction(const G4Step* aStep)
{
// get volume of the current step
G4VPhysicalVolume* volume
= aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
G4VPhysicalVolume* volume =
aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
// collect energy and track length step by step
G4double edep = aStep->GetTotalEnergyDeposit();
G4double stepl = 0.;
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.)
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.) {
stepl = aStep->GetStepLength();
if (volume == fDetector->GetAbsorber()) fEventAction->AddAbs(edep,stepl);
if (volume == fDetector->GetGap()) fEventAction->AddGap(edep,stepl);
}
if (volume == fDetector->GetAbsorber()) { fEventAction->AddAbs(edep,stepl); }
if (volume == fDetector->GetGap()) { fEventAction->AddGap(edep,stepl); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -38,26 +38,26 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HistoManager::HistoManager()
: fFactoryOn(false)
{}
{
// Create or get analysis manager
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
analysisManager->SetDefaultFileType("root");
// the default file type can be overriden in run macro
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HistoManager::~HistoManager()
{}
HistoManager::~HistoManager() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HistoManager::Book()
{
// Create or get analysis manager
// The choice of analysis technology is done via selection of a namespace
// in HistoManager.hh
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
if ( ! fFactoryOn ) {
//
analysisManager->SetDefaultFileType("root");
analysisManager->SetVerboseLevel(1);
// Only merge in MT mode to avoid warning when running in Sequential mode
#ifdef G4MULTITHREADED
@@ -123,7 +123,7 @@ void HistoManager::Book()
void HistoManager::Save()
{
if (! fFactoryOn) return;
if (! fFactoryOn) { return; }
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
analysisManager->Write();
@@ -146,7 +146,8 @@ void HistoManager::Normalize(G4int ih, G4double fac)
{
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
auto h1 = analysisManager->GetH1(ih);
if (h1) h1->scale(fac);
if (h1 != nullptr) { h1->scale(fac);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -169,7 +170,7 @@ void HistoManager::FillNtuple(G4double energyAbs, G4double energyGap,
void HistoManager::PrintStatistic()
{
if (! fFactoryOn) return;
if (! fFactoryOn) { return; }
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
@@ -179,8 +180,8 @@ void HistoManager::PrintStatistic()
auto h1 = analysisManager->GetH1(i);
G4String unitCategory;
if (name[0U] == 'E' ) unitCategory = "Energy";
if (name[0U] == 'L' ) unitCategory = "Length";
if (name[0U] == 'E' ) { unitCategory = "Energy"; }
if (name[0U] == 'L' ) { unitCategory = "Length"; }
// we use an explicit unsigned int type for operator [] argument
// to avoid problems with windows compiler
+34 -34
View File
@@ -6,16 +6,16 @@
Examples AnaEx01 and AnaEx02 show the usage of histogram and tuple
manipulations using G4Analysis and ROOT compliant systems on the same
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
three examples.
This example shows the usage of histogram and tuple manipulations using
ROOT system. Please install ROOT before building this example:
This example shows the usage of histogram and tuple manipulations using
ROOT system. Please install ROOT before building this example:
http://root.cern.ch
The example is an adaptation of examples/novice/N03. It describes a simple
The example is an adaptation of examples/novice/N03. It describes a simple
sampling calorimeter setup.
\section AnaEx02_s1 Detector description
@@ -30,7 +30,7 @@
- the material of the detection gap,
- the thickness of a gap,
- the number of layers,
- the transverse size of the calorimeter (the input face is a square).
- the transverse size of the calorimeter (the input face is a square).
The default geometry is constructed in DetectorConstruction class,
but all of the above parameters can be modified interactively via
@@ -56,20 +56,20 @@
\section AnaEx02_s3 Action Initialization
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
which are defined thread-local and a run action class
which is defined both thread-local and global.
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
ActionInitialization::BuildForMaster().
Note that ActionInitialization::Build() is also used to
Note that ActionInitialization::Build() is also used to
instatiate user action clasess in sequential mode.
\section AnaEx02_s4 An event : PrimaryGeneratorAction
The primary kinematic consists of a single particle which hits the
calorimeter perpendicular to the input face. The type of the particle
and its energy are set in the PrimaryGeneratorAction class, and can
@@ -79,34 +79,34 @@
\section AnaEx02_s5 Histograms
To produce histograms, ROOT system must be installed
AnaEx02 can produce 4 histograms :
- EAbs : total energy deposit in absorber per event
- EGap : total energy deposit in gap per event
- LAbs : total track length of charged particles in absorber per event
- LGap : total track length of charged particles in gap per event
- EGap : total energy deposit in gap per event
- LAbs : total track length of charged particles in absorber per event
- LGap : total track length of charged particles in gap per event
And 2 Ntuples :
- Ntuple1:
- one row per event : EnergyAbs EnergyGap
- Ntuple2:
- one row per event : TrackLAbs TrackLGap
These histos and ntuples are booked in HistoManager and filled from
These histos and ntuples are booked in HistoManager and filled from
EventAction.
One can control the name of the histograms file :
- default name : AnaEx02
Format : root
See HistoManager constructor
\section AnaEx02_s6 How to build
An additional step is needed when building the example with GNUmake
due to using the extra shared directory:
\verbatim
due to using the extra shared directory:
\verbatim
% cd path_to_AnaEx02/AnaEx02
% gmake setup
% gmake
@@ -114,7 +114,7 @@
This will copy the files from shared in the example include and src;
to remove these files:
\verbatim
\verbatim
% gmake clean_setup
\endverbatim
@@ -126,23 +126,23 @@
and type in the commands from run.mac line by line:
Idle> /control/verbose 2
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> /run/beamOn 10
Idle> ...
Idle> exit
\endverbatim
\endverbatim
or
\verbatim
Idle> /control/execute run.mac
....
Idle> exit
\endverbatim
\endverbatim
- Execute AnaEx02 in the 'batch' mode from macro files
- Execute AnaEx02 in the 'batch' mode from macro files
(without visualization)
\verbatim
% ./AnaEx02 run.mac
% ./AnaEx02 run.mac > run.out
\endverbatim
\endverbatim
The AnaEx02.in macro is used in Geant4 testing.
+10 -30
View File
@@ -32,10 +32,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "FTFP_BERT.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.hh"
@@ -43,6 +40,10 @@
#include "SteppingAction.hh"
#include "HistoManager.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "FTFP_BERT.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
@@ -52,7 +53,7 @@ int main(int argc,char** argv)
{
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = 0;
G4UIExecutive* ui = nullptr;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
@@ -63,34 +64,14 @@ int main(int argc,char** argv)
// Set mandatory initialization classes
//
DetectorConstruction* detector = new DetectorConstruction;
auto detector = new DetectorConstruction;
runManager->SetUserInitialization(detector);
//
runManager->SetUserInitialization(new FTFP_BERT);
// set an HistoManager
//
HistoManager* histo = new HistoManager();
// Set user action classes
//
PrimaryGeneratorAction* gen_action =
new PrimaryGeneratorAction(detector);
runManager->SetUserAction(gen_action);
//
RunAction* run_action = new RunAction(histo);
runManager->SetUserAction(run_action);
//
EventAction* event_action = new EventAction(run_action,histo);
runManager->SetUserAction(event_action);
//
SteppingAction* stepping_action =
new SteppingAction(detector, event_action);
runManager->SetUserAction(stepping_action);
runManager->SetUserInitialization(new ActionInitialization(detector));
// Initialize G4 kernel
//
runManager->Initialize();
// runManager->Initialize();
// Initialize visualization
//
@@ -101,7 +82,7 @@ int main(int argc,char** argv)
//
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if ( ! ui ) {
if ( ui == nullptr ) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
@@ -116,7 +97,6 @@ int main(int argc,char** argv)
// Job termination
delete visManager;
delete histo;
delete runManager;
return 0;
@@ -8,11 +8,6 @@
# initialize
/run/initialize
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
# Test commands defined in this example
/control/verbose 2
#
@@ -25,3 +20,7 @@
#
/run/beamOn 1
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
+78 -66
View File
@@ -10,7 +10,7 @@
**************************************************************
Geant4 version Name: geant4-11-01-beta-01 (30-June-2022)
Geant4 version Name: geant4-11-01-ref-00 (9-December-2022)
Copyright : Geant4 Collaboration
References : NIM A 506 (2003), 250-303
: IEEE-TNS 53 (2006), 270-278
@@ -54,18 +54,6 @@
<<< Geant4 Physics List simulation engine: FTFP_BERT
------------------------------------------------------------
---> The calorimeter is 10 layers of: [ 10mm of G4_Pb + 5mm of G4_lAr ]
------------------------------------------------------------
hInelastic FTFP_BERT : threshold between BERT and FTFP is over the interval
for pions : 3 to 6 GeV
for kaons : 3 to 6 GeV
for proton : 3 to 6 GeV
for neutron : 3 to 6 GeV
### Adding tracking cuts for neutron TimeCut(ns)= 10000 KinEnergyCut(MeV)= 0
Visualization Manager instantiating with verbosity "warnings (3)"...
Visualization Manager initialising...
Registering graphics systems...
@@ -78,6 +66,8 @@ Registered graphics systems are:
RayTracer (RayTracer)
VRML2FILE (VRML2FILE)
gMocrenFile (gMocrenFile)
TOOLSSG_OFFSCREEN (TSG_OFFSCREEN)
TOOLSSG_OFFSCREEN (TSG_OFFSCREEN, TSG_FILE)
OpenGLImmediateQt (OGLIQt, OGLI)
OpenGLStoredQt (OGLSQt, OGL, OGLS)
OpenGLImmediateXm (OGLIXm, OGLIQt_FALLBACK)
@@ -121,6 +111,35 @@ End of Run User Vis Actions: none
Some /vis commands (optionally) take a string to specify colour.
"/vis/list" to see available colours.
------------------------------------------------------------
---> The calorimeter is 10 layers of: [ 10mm of G4_Pb + 5mm of G4_lAr ]
------------------------------------------------------------
hInelastic FTFP_BERT : threshold between BERT and FTFP is over the interval
for pions : 3 to 6 GeV
for kaons : 3 to 6 GeV
for proton : 3 to 6 GeV
for neutron : 3 to 6 GeV
### Adding tracking cuts for neutron TimeCut(ns)= 10000 KinEnergyCut(MeV)= 0
#
/det/setAbsMat G4_Al
/det/setGapMat G4_Air
/det/setAbsThick 20. mm
/run/reinitializeGeometry
/det/setGapThick 10. mm
/run/reinitializeGeometry
/det/setSizeYZ 30. mm
/run/reinitializeGeometry
/det/setNbOfLayers 20
/run/reinitializeGeometry
#
/run/beamOn 1
------------------------------------------------------------
---> The calorimeter is 20 layers of: [ 20mm of G4_Al + 10mm of G4_lAr ]
------------------------------------------------------------
=======================================================================
====== Electromagnetic Physics Parameters ========
=======================================================================
@@ -130,6 +149,7 @@ Apply cuts on all EM processes 0
Use combined TransportationWithMsc Disabled
Use general process 1
Enable linear polarisation for gamma 0
Enable photoeffect sampling below K-shell 1
Enable sampling of quantum entanglement 0
X-section factor for integral approach 0.8
Min kinetic energy for tables 100 eV
@@ -157,7 +177,7 @@ Lowest e+e- kinetic energy 1 keV
Lowest muon/hadron kinetic energy 1 keV
Use ICRU90 data 0
Fluctuations of dE/dx are enabled 1
Type of fluctuation model 2
Type of fluctuation model for leptons and hadrons Urban
Use built-in Birks satuaration 0
Build CSDA range enabled 0
Use cut as a final range enabled 0
@@ -208,8 +228,8 @@ conv: for gamma SubType=14 BuildTable=1
BetheHeitlerLPM : Emin= 0 eV Emax= 100 TeV ModifiedTsai
Rayl: for gamma SubType=11 BuildTable=1
Lambda table from 100 eV to 100 keV, 7 bins/decade, spline: 0
LambdaPrime table from 100 keV to 100 TeV in 63 bins
Lambda table from 100 eV to 150 keV, 7 bins/decade, spline: 0
LambdaPrime table from 150 keV to 100 TeV in 62 bins
===== EM models for the G4Region DefaultRegionForTheWorld ======
LivermoreRayleigh : Emin= 0 eV Emax= 100 TeV CullenGenerator
@@ -691,6 +711,11 @@ CoulombScat: for pi- XStype:1 SubType=1 BuildTable=1
Process: hFritiofCaptureAtRest
---------------------------------------------------
Hadronic Processes for anti_hypertriton
Process: hFritiofCaptureAtRest
---------------------------------------------------
Hadronic Processes for anti_lambda
@@ -962,6 +987,35 @@ See commands in /vis/modeling/trajectories/ for other options.
---> Begin of event: 0
--------------------End of Run------------------------------
mean Energy in Absorber : 256.274 MeV +- 0 eV
mean Energy in Gap : 50.16 MeV +- 0 eV
mean trackLength in Absorber : 63.8594 cm +- 0 fm
mean trackLength in Gap : 26.1088 cm +- 0 fm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 256.274 MeV rms = 0 eV
EGap: mean = 50.16 MeV rms = 0 eV
LAbs: mean = 63.8594 cm rms = 0 fm
LGap: mean = 26.1088 cm rms = 0 fm
----> Histograms and ntuples are saved
# e- 500MeV
/gun/particle e-
/gun/energy 500 MeV
/run/beamOn 1000
### Run 1 start.
----> Output file is open in AnaEx02.root
---> Begin of event: 0
---> Begin of event: 100
---> Begin of event: 200
@@ -982,62 +1036,20 @@ See commands in /vis/modeling/trajectories/ for other options.
--------------------End of Run------------------------------
mean Energy in Absorber : 453.656 MeV +- 12.4449 MeV
mean Energy in Gap : 24.7474 MeV +- 7.52057 MeV
mean Energy in Absorber : 188.96 MeV +- 48.8659 MeV
mean Energy in Gap : 46.7177 MeV +- 12.7612 MeV
mean trackLength in Absorber : 32.6632 cm +- 9.51264 mm
mean trackLength in Gap : 12.2578 cm +- 3.86035 cm
mean trackLength in Absorber : 46.7149 cm +- 12.1118 cm
mean trackLength in Gap : 23.7187 cm +- 6.51829 cm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 453.656 MeV rms = 12.4449 MeV
EGap: mean = 24.7474 MeV rms = 7.52057 MeV
LAbs: mean = 32.6632 cm rms = 9.51264 mm
LGap: mean = 12.2578 cm rms = 3.86035 cm
----> Histograms and ntuples are saved
#
/det/setAbsMat G4_Al
/det/setGapMat G4_Air
/det/setAbsThick 20. mm
/run/reinitializeGeometry
/det/setGapThick 10. mm
/run/reinitializeGeometry
/det/setSizeYZ 30. mm
/run/reinitializeGeometry
/det/setNbOfLayers 20
/run/reinitializeGeometry
#
/run/beamOn 1
------------------------------------------------------------
---> The calorimeter is 20 layers of: [ 20mm of G4_Al + 10mm of G4_lAr ]
------------------------------------------------------------
### Run 1 start.
----> Output file is open in AnaEx02.root
---> Begin of event: 0
--------------------End of Run------------------------------
mean Energy in Absorber : 135.077 MeV +- 0 eV
mean Energy in Gap : 45.3511 MeV +- 0 eV
mean trackLength in Absorber : 33.6513 cm +- 0 fm
mean trackLength in Gap : 22.1697 cm +- 0 fm
------------------------------------------------------------
----> print histograms statistic
EAbs: mean = 135.077 MeV rms = 0 eV
EGap: mean = 45.3511 MeV rms = 0 eV
LAbs: mean = 33.6513 cm rms = 0 fm
LGap: mean = 22.1697 cm rms = 0 fm
EAbs: mean = 188.96 MeV rms = 48.8659 MeV
EGap: mean = 46.7177 MeV rms = 12.7612 MeV
LAbs: mean = 46.7149 cm rms = 12.1118 cm
LGap: mean = 23.7187 cm rms = 6.51829 cm
----> Histograms and ntuples are saved
+41 -41
View File
@@ -8,33 +8,33 @@
-------
Examples AnaEx01 and AnaEx02 show the usage of histogram and tuple
manipulations using G4Analysis and ROOT compliant systems on the same
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
scenario. All analysis manipulations (histo booking, filling, saving histos
in a file, etc...) are located in one class : HistoManager, implementation of
which is different in each example. All the other classes are same in all
three examples.
This example shows the usage of histogram and tuple manipulations using
ROOT system. Please install ROOT before building this example:
This example shows the usage of histogram and tuple manipulations using
ROOT system. Please install ROOT before building this example:
http://root.cern.ch
The example is an adaptation of examples/novice/N03. It describes a simple
The example is an adaptation of examples/novice/N03. It describes a simple
sampling calorimeter setup.
1- Detector description
-----------------------
The calorimeter is a box made of a given number of layers. A layer
consists of an absorber plate and of a detection gap. The layer is
replicated.
Six parameters define the calorimeter :
- the material of the absorber,
- the thickness of an absorber plate,
- the material of the detection gap,
- the thickness of a gap,
- the number of layers,
- the transverse size of the calorimeter (the input face is a square).
- the transverse size of the calorimeter (the input face is a square).
The default geometry is constructed in DetectorConstruction class,
but all of the above parameters can be modified interactively via
the commands defined in the DetectorMessenger class.
@@ -51,28 +51,28 @@
2- Physics list
---------------
The particle's type and the physic processes which will be available
in this example are set in the FTFP_BERT physics list.
3- Action Initialization
------------------------
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
A newly introduced class, ActionInitialization,
instantiates and registers to Geant4 kernel all user action classes
which are defined thread-local and a run action class
which is defined both thread-local and global.
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
The thread-local action classes are defined in
ActionInitialization::Build()
and the global run action class is defined in
ActionInitialization::BuildForMaster().
Note that ActionInitialization::Build() is also used to
Note that ActionInitialization::Build() is also used to
instatiate user action clasess in sequential mode.
4- An event : PrimaryGeneratorAction
------------------------------------
The primary kinematic consists of a single particle which hits the
calorimeter perpendicular to the input face. The type of the particle
and its energy are set in the PrimaryGeneratorAction class, and can
@@ -80,36 +80,36 @@
5- Histograms
-------------
-------------
To produce histograms, ROOT system must be installed
AnaEx02 can produce 4 histograms :
EAbs : total energy deposit in absorber per event
EGap : total energy deposit in gap per event
LAbs : total track length of charged particles in absorber per event
LGap : total track length of charged particles in gap per event
EGap : total energy deposit in gap per event
LAbs : total track length of charged particles in absorber per event
LGap : total track length of charged particles in gap per event
And 2 Ntuples :
- Ntuple1:
- one row per event : EnergyAbs EnergyGap
- Ntuple2:
- one row per event : TrackLAbs TrackLGap
These histos and ntuples are booked in HistoManager and filled from
These histos and ntuples are booked in HistoManager and filled from
EventAction.
One can control the name of the histograms file :
default name : AnaEx02
format : root
See HistoManager constructor
6- How to build
---------------
---------------
An additional step is needed when building the example with GNUmake
due to using the extra shared directory:
due to using the extra shared directory:
% cd path_to_AnaEx02/AnaEx02
% gmake setup
% gmake
@@ -123,10 +123,10 @@
- Execute AnaEx02 in the 'interactive mode' with visualization:
% ./AnaEx02
and type in the commands from run.mac line by line:
and type in the commands from run.mac line by line:
Idle> /control/verbose 2
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> /run/beamOn 10
Idle> ...
Idle> exit
or
@@ -141,5 +141,5 @@
The AnaEx02.in macro is used in Geant4 testing.
@@ -35,6 +35,8 @@
#include "globals.hh"
#include <array>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class TFile;
@@ -50,28 +52,28 @@ class HistoManager
public:
HistoManager();
~HistoManager();
void Book();
void Save();
void FillHisto(G4int id, G4double bin, G4double weight = 1.0);
void Normalize(G4int id, G4double fac);
void Normalize(G4int id, G4double fac);
void FillNtuple(G4double energyAbs, G4double energyGap,
G4double trackLAbs, G4double trackLGap);
void PrintStatistic();
private:
TFile* fRootFile;
TH1D* fHisto[kMaxHisto];
TTree* fNtuple1;
TTree* fNtuple2;
G4double fEabs;
G4double fEgap;
G4double fLabs;
G4double fLgap;
void PrintStatistic();
private:
TFile* fRootFile = nullptr;
std::array<TH1D*, kMaxHisto> fHisto = {nullptr, nullptr, nullptr, nullptr};
TTree* fNtuple1 = nullptr;
TTree* fNtuple2 = nullptr;
G4double fEabs = 0.;
G4double fEgap = 0.;
G4double fLabs = 0.;
G4double fLgap = 0.;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+10 -10
View File
@@ -1,20 +1,20 @@
{
gROOT->Reset();
// Draw histos filled by Geant4 simulation
//
TFile f = TFile("AnaEx02.root");
// Draw histos filled by Geant4 simulation
//
TFile f = TFile("AnaEx02.root");
TCanvas* c1 = new TCanvas("c1", " ");
TH1D* hist1 = (TH1D*)f.Get("1");
hist1->Draw("HIST");
TH1D* hist2 = (TH1D*)f.Get("2");
hist2->Draw("HIST");
TH1D* hist3 = (TH1D*)f.Get("3");
c1->SetLogy(1);
c1->cd();
c1->Update();
hist3->Draw("HIST");
}
c1->Update();
hist3->Draw("HIST");
}
@@ -21,7 +21,7 @@ be used as a substitute for writing good git commit messages!
03-07-18 I. Hrivnacova (analysisShared-V10-04-00)
- Macro & commands review:
- Removed obsolete /N03 top command directory
- Added protection against warnings issued from ReinitializeGeometry() if
- Added protection against warnings issued from ReinitializeGeometry() if
called in PreInit phase
04-07-16 I. Hrivnacova (analysisShared-V10-02-01)
@@ -33,9 +33,9 @@ be used as a substitute for writing good git commit messages!
27-08-15 I. Hrivnacova (analysisShared-V10-01-00)
- Updated histogram ids in FillHiso (now starting from 0);
updated for changed function names in HistoManager classes
06-11-14 I. Hrivnacova (analysisShared-V10-00-01)
- Moved scripts from upper directory in shared
05-11-14 I. Hrivnacova (analysisShared-V10-00-00)
- Tagged version which will be included in AnaEx0N examples
@@ -41,15 +41,15 @@ class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization(DetectorConstruction* detector);
virtual ~ActionInitialization();
~ActionInitialization() override;
virtual void BuildForMaster() const;
virtual void Build() const;
void BuildForMaster() const override;
void Build() const override;
private:
DetectorConstruction* fDetector;
DetectorConstruction* fDetector = nullptr;
};
#endif
@@ -25,10 +25,6 @@
//
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -39,6 +35,8 @@
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "CLHEP/Units/SystemOfUnits.h"
class G4Box;
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -50,90 +48,82 @@ class DetectorMessenger;
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
virtual ~DetectorConstruction();
DetectorConstruction();
~DetectorConstruction() override;
public:
void SetAbsorberMaterial (G4String);
void SetAbsorberThickness(G4double);
G4VPhysicalVolume* Construct() override;
void SetGapMaterial (G4String);
void SetGapThickness(G4double);
void SetCalorSizeYZ(G4double);
void SetNbOfLayers (G4int);
virtual G4VPhysicalVolume* Construct();
void SetAbsorberMaterial (const G4String&);
void SetAbsorberThickness(G4double);
void SetGapMaterial (const G4String&);
void SetGapThickness(G4double);
void SetCalorSizeYZ(G4double);
void SetNbOfLayers (G4int);
void PrintCalorParameters();
G4double GetWorldSizeX() { return fWorldSizeX; }
G4double GetWorldSizeYZ() { return fWorldSizeYZ; }
G4double GetCalorThickness() { return fCalorThickness; }
G4double GetCalorSizeYZ() { return fCalorSizeYZ; }
G4int GetNbOfLayers() { return fNbOfLayers; }
G4Material* GetAbsorberMaterial() { return fAbsorberMaterial; }
G4double GetAbsorberThickness() { return fAbsorberThickness; }
G4Material* GetGapMaterial() { return fGapMaterial; }
G4double GetGapThickness() { return fGapThickness; }
const G4VPhysicalVolume* GetphysiWorld() { return fPhysiWorld; }
const G4VPhysicalVolume* GetAbsorber() { return fPhysiAbsorber; }
const G4VPhysicalVolume* GetGap() { return fPhysiGap; }
public:
void PrintCalorParameters();
G4double GetWorldSizeX() {return fWorldSizeX;};
G4double GetWorldSizeYZ() {return fWorldSizeYZ;};
G4double GetCalorThickness() {return fCalorThickness;};
G4double GetCalorSizeYZ() {return fCalorSizeYZ;};
G4int GetNbOfLayers() {return fNbOfLayers;};
G4Material* GetAbsorberMaterial() {return fAbsorberMaterial;};
G4double GetAbsorberThickness() {return fAbsorberThickness;};
G4Material* GetGapMaterial() {return fGapMaterial;};
G4double GetGapThickness() {return fGapThickness;};
const G4VPhysicalVolume* GetphysiWorld() {return fPhysiWorld;};
const G4VPhysicalVolume* GetAbsorber() {return fPhysiAbsorber;};
const G4VPhysicalVolume* GetGap() {return fPhysiGap;};
private:
G4Material* fAbsorberMaterial;
G4double fAbsorberThickness;
G4Material* fGapMaterial;
G4double fGapThickness;
G4int fNbOfLayers;
G4double fLayerThickness;
G4double fCalorSizeYZ;
G4double fCalorThickness;
G4Material* fDefaultMaterial;
G4double fWorldSizeYZ;
G4double fWorldSizeX;
G4Box* fSolidWorld; //pointer to the solid World
G4LogicalVolume* fLogicWorld; //pointer to the logical World
G4VPhysicalVolume* fPhysiWorld; //pointer to the physical World
void DefineMaterials();
void ComputeCalorParameters();
G4VPhysicalVolume* ConstructCalorimeter();
G4Box* fSolidCalor; //pointer to the solid Calor
G4LogicalVolume* fLogicCalor; //pointer to the logical Calor
G4VPhysicalVolume* fPhysiCalor; //pointer to the physical Calor
G4Box* fSolidLayer; //pointer to the solid Layer
G4LogicalVolume* fLogicLayer; //pointer to the logical Layer
G4VPhysicalVolume* fPhysiLayer; //pointer to the physical Layer
G4Box* fSolidAbsorber; //pointer to the solid Absorber
G4LogicalVolume* fLogicAbsorber; //pointer to the logical Absorber
G4VPhysicalVolume* fPhysiAbsorber; //pointer to the physical Absorber
G4Box* fSolidGap; //pointer to the solid Gap
G4LogicalVolume* fLogicGap; //pointer to the logical Gap
G4VPhysicalVolume* fPhysiGap; //pointer to the physical Gap
DetectorMessenger* fDetectorMessenger; //pointer to the Messenger
private:
void DefineMaterials();
void ComputeCalorParameters();
G4VPhysicalVolume* ConstructCalorimeter();
G4Material* fAbsorberMaterial = nullptr;
G4Material* fGapMaterial = nullptr;
G4Material* fDefaultMaterial = nullptr;
G4int fNbOfLayers = 10;
G4double fAbsorberThickness = 10.*CLHEP::mm;
G4double fGapThickness = 5.*CLHEP::mm;
G4double fCalorSizeYZ = 10.*CLHEP::cm;
G4double fCalorThickness = 0.; // will be computed
G4double fLayerThickness= 0.; // will be computed
G4double fWorldSizeYZ = 0.; // will be computed;
G4double fWorldSizeX = 0.; // will be computed;
G4Box* fSolidWorld = nullptr; //pointer to the solid World
G4LogicalVolume* fLogicWorld = nullptr; //pointer to the logical World
G4VPhysicalVolume* fPhysiWorld = nullptr; //pointer to the physical World
G4Box* fSolidCalor = nullptr; //pointer to the solid Calor
G4LogicalVolume* fLogicCalor = nullptr; //pointer to the logical Calor
G4VPhysicalVolume* fPhysiCalor = nullptr; //pointer to the physical Calor
G4Box* fSolidLayer = nullptr; //pointer to the solid Layer
G4LogicalVolume* fLogicLayer = nullptr; //pointer to the logical Layer
G4VPhysicalVolume* fPhysiLayer = nullptr; //pointer to the physical Layer
G4Box* fSolidAbsorber = nullptr; //pointer to the solid Absorber
G4LogicalVolume* fLogicAbsorber = nullptr; //pointer to the logical Absorber
G4VPhysicalVolume* fPhysiAbsorber = nullptr; //pointer to the physical Absorber
G4Box* fSolidGap = nullptr; //pointer to the solid Gap
G4LogicalVolume* fLogicGap = nullptr; //pointer to the logical Gap
G4VPhysicalVolume* fPhysiGap = nullptr; //pointer to the physical Gap
DetectorMessenger* fDetectorMessenger = nullptr; //pointer to the Messenger
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -141,10 +131,10 @@ class DetectorConstruction : public G4VUserDetectorConstruction
inline void DetectorConstruction::ComputeCalorParameters()
{
// Compute derived parameters of the calorimeter
fLayerThickness = fAbsorberThickness + fGapThickness;
fCalorThickness = fNbOfLayers*fLayerThickness;
fWorldSizeX = 1.2*fCalorThickness; fWorldSizeYZ = 1.2*fCalorSizeYZ;
fLayerThickness = fAbsorberThickness + fGapThickness;
fCalorThickness = fNbOfLayers*fLayerThickness;
fWorldSizeX = 1.2*fCalorThickness; fWorldSizeYZ = 1.2*fCalorSizeYZ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,7 +40,6 @@ class G4UIdirectory;
class G4UIcmdWithAString;
class G4UIcmdWithAnInteger;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -52,23 +47,22 @@ class DetectorMessenger: public G4UImessenger
{
public:
DetectorMessenger(DetectorConstruction* );
virtual ~DetectorMessenger();
virtual void SetNewValue(G4UIcommand*, G4String);
~DetectorMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetDir;
G4UIcmdWithAString* fAbsMaterCmd;
G4UIcmdWithAString* fGapMaterCmd;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd;
G4UIcmdWithADoubleAndUnit* fGapThickCmd;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd;
G4UIcmdWithAnInteger* fNbLayersCmd;
DetectorConstruction* fDetector = nullptr;
G4UIdirectory* fDetDir = nullptr;
G4UIcmdWithAString* fAbsMaterCmd = nullptr;
G4UIcmdWithAString* fGapMaterCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fGapThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd = nullptr;
G4UIcmdWithAnInteger* fNbLayersCmd = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,26 +48,28 @@ class EventAction : public G4UserEventAction
{
public:
EventAction(RunAction*, HistoManager*);
virtual ~EventAction();
~EventAction() override;
void BeginOfEventAction(const G4Event*) override;
void EndOfEventAction(const G4Event*) override;
virtual void BeginOfEventAction(const G4Event*);
virtual void EndOfEventAction(const G4Event*);
void AddAbs(G4double de, G4double dl) {fEnergyAbs += de; fTrackLAbs += dl;};
void AddGap(G4double de, G4double dl) {fEnergyGap += de; fTrackLGap += dl;};
private:
RunAction* fRunAct;
HistoManager* fHistoManager;
G4double fEnergyAbs, fEnergyGap;
G4double fTrackLAbs, fTrackLGap;
G4int fPrintModulo;
RunAction* fRunAct = nullptr;
HistoManager* fHistoManager = nullptr;
G4double fEnergyAbs = 0.;
G4double fEnergyGap = 0;
G4double fTrackLAbs = 0;
G4double fTrackLGap = 0;
G4int fPrintModulo = 100;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -25,10 +25,6 @@
//
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,14 +44,14 @@ class DetectorConstruction;
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction(DetectorConstruction*);
virtual ~PrimaryGeneratorAction();
PrimaryGeneratorAction(DetectorConstruction*);
~PrimaryGeneratorAction() override;
virtual void GeneratePrimaries(G4Event*);
void GeneratePrimaries(G4Event*) override;
private:
G4ParticleGun* fParticleGun; //pointer a to G4 class
DetectorConstruction* fDetector; //pointer to the geometry
G4ParticleGun* fParticleGun = nullptr; //pointer a to G4 class
DetectorConstruction* fDetector = nullptr; //pointer to the geometry
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -37,6 +37,7 @@
#define RunAction_h 1
#include "G4UserRunAction.hh"
#include "G4Accumulable.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,21 +49,25 @@ class RunAction : public G4UserRunAction
{
public:
RunAction(HistoManager*);
virtual ~RunAction();
~RunAction() override;
virtual void BeginOfRunAction(const G4Run*);
virtual void EndOfRunAction(const G4Run*);
void FillPerEvent(G4double, G4double, G4double, G4double);
void BeginOfRunAction(const G4Run*) override;
void EndOfRunAction(const G4Run*) override;
void FillPerEvent(G4double, G4double, G4double, G4double);
private:
HistoManager* fHistoManager;
HistoManager* fHistoManager = nullptr;
G4double fSumEAbs, fSum2EAbs;
G4double fSumEGap, fSum2EGap;
G4double fSumLAbs, fSum2LAbs;
G4double fSumLGap, fSum2LGap;
G4Accumulable<G4double> fSumEAbs = 0.;
G4Accumulable<G4double> fSum2EAbs = 0.;
G4Accumulable<G4double> fSumEGap = 0.;
G4Accumulable<G4double> fSum2EGap = 0.;
G4Accumulable<G4double> fSumLAbs = 0.;
G4Accumulable<G4double> fSum2LAbs = 0.;
G4Accumulable<G4double> fSumLGap = 0.;
G4Accumulable<G4double> fSum2LGap = 0.;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -47,13 +43,13 @@ class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction(DetectorConstruction*, EventAction*);
virtual ~SteppingAction();
~SteppingAction() override;
void UserSteppingAction(const G4Step*) override;
virtual void UserSteppingAction(const G4Step*);
private:
DetectorConstruction* fDetector;
EventAction* fEventAction;
DetectorConstruction* fDetector = nullptr;
EventAction* fEventAction = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -11,6 +11,6 @@ be used as a substitute for writing good git commit messages!
---
# History entries prior to 11.0
05-11-14 I. Hrivnacova (analysisScripts-V10-00-00)
- Tagged version which will be included in AnaEx0N examples
@@ -9,10 +9,10 @@ DIRNAME=$1
for FILE in `ls $DIRNAME/include`; do
rm -f include/$FILE
done
done
for FILE in `ls $DIRNAME/src`; do
rm -f src/$FILE
done
done
echo "... clean_files.sh from $1 finished"
@@ -37,22 +37,20 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization(DetectorConstruction* detector)
: G4VUserActionInitialization(),
fDetector(detector)
: fDetector(detector)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{}
ActionInitialization::~ActionInitialization() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
{
// Histo manager
HistoManager* histo = new HistoManager();
auto histo = new HistoManager();
// Actions
SetUserAction(new RunAction(histo));
}
@@ -62,20 +60,20 @@ void ActionInitialization::BuildForMaster() const
void ActionInitialization::Build() const
{
// Histo manager
HistoManager* histo = new HistoManager();
auto histo = new HistoManager();
// Actions
//
SetUserAction(new PrimaryGeneratorAction(fDetector));
RunAction* runAction = new RunAction(histo);
auto runAction = new RunAction(histo);
SetUserAction(runAction);
EventAction* eventAction = new EventAction(runAction, histo);
auto eventAction = new EventAction(runAction, histo);
SetUserAction(eventAction);
SteppingAction* steppingAction = new SteppingAction(fDetector, eventAction);
auto steppingAction = new SteppingAction(fDetector, eventAction);
SetUserAction(steppingAction);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -58,27 +54,14 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
:G4VUserDetectorConstruction(),
fAbsorberMaterial(0),fGapMaterial(0),fDefaultMaterial(0),
fSolidWorld(0),fLogicWorld(0),fPhysiWorld(0),
fSolidCalor(0),fLogicCalor(0),fPhysiCalor(0),
fSolidLayer(0),fLogicLayer(0),fPhysiLayer(0),
fSolidAbsorber(0),fLogicAbsorber(0),fPhysiAbsorber(0),
fSolidGap (0),fLogicGap (0),fPhysiGap (0),
fDetectorMessenger(0)
{
// default parameter values of the calorimeter
fAbsorberThickness = 10.*mm;
fGapThickness = 5.*mm;
fNbOfLayers = 10;
fCalorSizeYZ = 10.*cm;
ComputeCalorParameters();
// materials
DefineMaterials();
SetAbsorberMaterial("G4_Pb");
SetGapMaterial("G4_lAr");
// create commands for interactive definition of the calorimeter
fDetectorMessenger = new DetectorMessenger(this);
}
@@ -86,7 +69,9 @@ DetectorConstruction::DetectorConstruction()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{ delete fDetectorMessenger;}
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -98,24 +83,23 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineMaterials()
{
// use G4-NIST materials data base
//
G4NistManager* man = G4NistManager::Instance();
fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
man->FindOrBuildMaterial("G4_Pb");
man->FindOrBuildMaterial("G4_lAr");
{
// use G4-NIST materials data base
//
G4NistManager* man = G4NistManager::Instance();
fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
man->FindOrBuildMaterial("G4_Pb");
man->FindOrBuildMaterial("G4_lAr");
// print table
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
// print table
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
{
// Clean old geometry, if any
//
G4GeometryManager::GetInstance()->OpenGeometry();
@@ -125,126 +109,128 @@ G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
// complete the Calor parameters definition
ComputeCalorParameters();
//
//
// World
//
fSolidWorld = new G4Box("World", //its name
fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
fSolidWorld = new G4Box("World", //its name
fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
fLogicWorld = new G4LogicalVolume(fSolidWorld, //its solid
fDefaultMaterial, //its material
"World"); //its name
fPhysiWorld = new G4PVPlacement(0, //no rotation
fPhysiWorld = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicWorld, //its logical volume
fLogicWorld, //its logical volume
"World", //its name
0, //its mother volume
false, //no boolean operation
nullptr, //its mother volume
false, //no boolean operation
0); //copy number
//
// Calorimeter
//
fSolidCalor=0; fLogicCalor=0; fPhysiCalor=0;
fSolidLayer=0; fLogicLayer=0; fPhysiLayer=0;
if (fCalorThickness > 0.)
{ fSolidCalor = new G4Box("Calorimeter", //its name
fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);//size
fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
fDefaultMaterial, //its material
"Calorimeter"); //its name
fPhysiCalor = new G4PVPlacement(0, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicCalor, //its logical volume
"Calorimeter", //its name
fLogicWorld, //its mother volume
false, //no boolean operation
0); //copy number
//
// Layer
//
// Calorimeter
//
fSolidCalor = nullptr; fLogicCalor = nullptr; fPhysiCalor = nullptr;
fSolidLayer = nullptr; fLogicLayer = nullptr; fPhysiLayer = nullptr;
if (fCalorThickness > 0.) {
fSolidCalor = new G4Box("Calorimeter", //its name
fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
fDefaultMaterial, //its material
"Calorimeter"); //its name
fPhysiCalor = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicCalor, //its logical volume
"Calorimeter", //its name
fLogicWorld, //its mother volume
false, //no boolean operation
0); //copy number
//
// Layer
//
fSolidLayer = new G4Box("Layer", //its name
fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
fDefaultMaterial, //its material
"Layer"); //its name
if (fNbOfLayers > 1) {
fPhysiLayer = new G4PVReplica("Layer", //its name
fLogicLayer, //its logical volume
fLogicCalor, //its mother
kXAxis, //axis of replication
fNbOfLayers, //number of replica
fLayerThickness); //witdth of replica
}
else {
fPhysiLayer = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicLayer, //its logical volume
"Layer", //its name
fLogicCalor, //its mother volume
false, //no boolean operation
0); //copy number
}
}
//
fSolidLayer = new G4Box("Layer", //its name
fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
fDefaultMaterial, //its material
"Layer"); //its name
if (fNbOfLayers > 1)
fPhysiLayer = new G4PVReplica("Layer", //its name
fLogicLayer, //its logical volume
fLogicCalor, //its mother
kXAxis, //axis of replication
fNbOfLayers, //number of replica
fLayerThickness); //witdth of replica
else
fPhysiLayer = new G4PVPlacement(0, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicLayer, //its logical volume
"Layer", //its name
fLogicCalor, //its mother volume
false, //no boolean operation
0); //copy number
}
//
// Absorber
//
fSolidAbsorber=0; fLogicAbsorber=0; fPhysiAbsorber=0;
if (fAbsorberThickness > 0.)
{ fSolidAbsorber = new G4Box("Absorber", //its name
fAbsorberThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, //its solid
fAbsorberMaterial, //its material
fAbsorberMaterial->GetName());//name
fPhysiAbsorber = new G4PVPlacement(0, //no rotation
G4ThreeVector(-fGapThickness/2,0.,0.), //its position
fLogicAbsorber, //its logical volume
fAbsorberMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
//
fSolidAbsorber = nullptr; fLogicAbsorber = nullptr; fPhysiAbsorber = nullptr;
if (fAbsorberThickness > 0.) {
fSolidAbsorber = new G4Box("Absorber", //its name
fAbsorberThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, //its solid
fAbsorberMaterial, //its material
fAbsorberMaterial->GetName()); //name
fPhysiAbsorber = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(-fGapThickness/2,0.,0.), //its position
fLogicAbsorber, //its logical volume
fAbsorberMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
//
// Gap
//
fSolidGap=0; fLogicGap=0; fPhysiGap=0;
if (fGapThickness > 0.)
{ fSolidGap = new G4Box("Gap",
fGapThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicGap = new G4LogicalVolume(fSolidGap,
fGapMaterial,
fGapMaterial->GetName());
fPhysiGap = new G4PVPlacement(0, //no rotation
G4ThreeVector(fAbsorberThickness/2,0.,0.), //its position
fLogicGap, //its logical volume
fGapMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
PrintCalorParameters();
//
fSolidGap = nullptr; fLogicGap = nullptr; fPhysiGap = nullptr;
if (fGapThickness > 0.) {
fSolidGap = new G4Box("Gap",
fGapThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicGap = new G4LogicalVolume(fSolidGap,
fGapMaterial,
fGapMaterial->GetName());
fPhysiGap = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(fAbsorberThickness/2,0.,0.), //its position
fLogicGap, //its logical volume
fGapMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
PrintCalorParameters();
//
// Visualization attributes
//
fLogicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
auto simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
simpleBoxVisAtt->SetVisibility(true);
fLogicCalor->SetVisAttributes(simpleBoxVisAtt);
@@ -260,54 +246,47 @@ void DetectorConstruction::PrintCalorParameters()
{
G4cout << "\n------------------------------------------------------------"
<< "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ "
<< fAbsorberThickness/mm << "mm of " << fAbsorberMaterial->GetName()
<< fAbsorberThickness/mm << "mm of " << fAbsorberMaterial->GetName()
<< " + "
<< fGapThickness/mm << "mm of " << fGapMaterial->GetName() << " ] "
<< fGapThickness/mm << "mm of " << fGapMaterial->GetName() << " ] "
<< "\n------------------------------------------------------------\n";
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
{
// search the material by its name
G4Material* pttoMaterial =
G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (pttoMaterial)
{
fAbsorberMaterial = pttoMaterial;
if ( fLogicAbsorber )
{
fLogicAbsorber->SetMaterial(fAbsorberMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapMaterial(G4String materialChoice)
void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
{
// search the material by its name
G4Material* pttoMaterial =
G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (pttoMaterial)
{
fGapMaterial = pttoMaterial;
if ( fLogicGap )
{
fLogicGap->SetMaterial(fGapMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fAbsorberMaterial = material;
if (fLogicAbsorber != nullptr) {
fLogicAbsorber->SetMaterial(fAbsorberMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberThickness(G4double val)
void DetectorConstruction::SetGapMaterial(const G4String& materialChoice)
{
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fGapMaterial = material;
if ( fLogicGap != nullptr) {
fLogicGap->SetMaterial(fGapMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberThickness(G4double value)
{
// change Absorber thickness and recompute the calorimeter parameters
fAbsorberThickness = val;
fAbsorberThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -315,10 +294,10 @@ void DetectorConstruction::SetAbsorberThickness(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapThickness(G4double val)
void DetectorConstruction::SetGapThickness(G4double value)
{
// change Gap thickness and recompute the calorimeter parameters
fGapThickness = val;
fGapThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -326,10 +305,10 @@ void DetectorConstruction::SetGapThickness(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetCalorSizeYZ(G4double val)
void DetectorConstruction::SetCalorSizeYZ(G4double value)
{
// change the transverse size and recompute the calorimeter parameters
fCalorSizeYZ = val;
fCalorSizeYZ = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -337,9 +316,9 @@ void DetectorConstruction::SetCalorSizeYZ(G4double val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetNbOfLayers(G4int val)
void DetectorConstruction::SetNbOfLayers(G4int value)
{
fNbOfLayers = val;
fNbOfLayers = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.cc
/// \brief Implementation of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -45,57 +41,48 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
: G4UImessenger(),
fDetector(Det),
fDetDir(0),
fAbsMaterCmd(0),
fGapMaterCmd(0),
fAbsThickCmd(0),
fGapThickCmd(0),
fSizeYZCmd(0),
fNbLayersCmd(0)
{
: fDetector(Det)
{
G4bool broadcast = false;
fDetDir = new G4UIdirectory("/det/",broadcast);
fDetDir->SetGuidance("Detector control");
fAbsMaterCmd = new G4UIcmdWithAString("/det/setAbsMat",this);
fAbsMaterCmd->SetGuidance("Select Material of the Absorber.");
fAbsMaterCmd->SetParameterName("choice",false);
fAbsMaterCmd->SetParameterName("AbsMat",false);
fAbsMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapMaterCmd = new G4UIcmdWithAString("/det/setGapMat",this);
fGapMaterCmd->SetGuidance("Select Material of the Gap.");
fGapMaterCmd->SetParameterName("choice",false);
fGapMaterCmd->SetParameterName("GapMat",false);
fGapMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fAbsThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setAbsThick",this);
fAbsThickCmd->SetGuidance("Set Thickness of the Absorber");
fAbsThickCmd->SetParameterName("Size",false);
fAbsThickCmd->SetRange("Size>=0.");
fAbsThickCmd->SetParameterName("AbsThick",false);
fAbsThickCmd->SetRange("AbsThick>=0.");
fAbsThickCmd->SetUnitCategory("Length");
fAbsThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setGapThick",this);
fGapThickCmd->SetGuidance("Set Thickness of the Gap");
fGapThickCmd->SetParameterName("Size",false);
fGapThickCmd->SetRange("Size>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->SetParameterName("GapThick",false);
fGapThickCmd->SetRange("GapThick>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fSizeYZCmd = new G4UIcmdWithADoubleAndUnit("/det/setSizeYZ",this);
fSizeYZCmd->SetGuidance("Set tranverse size of the calorimeter");
fSizeYZCmd->SetParameterName("Size",false);
fSizeYZCmd->SetRange("Size>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->SetParameterName("SizeYZ",false);
fSizeYZCmd->SetRange("SizeYZ>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fNbLayersCmd = new G4UIcmdWithAnInteger("/det/setNbOfLayers",this);
fNbLayersCmd->SetGuidance("Set number of layers.");
fNbLayersCmd->SetParameterName("NbLayers",false);
fNbLayersCmd->SetRange("NbLayers>0 && NbLayers<500");
fNbLayersCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -103,34 +90,46 @@ DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
DetectorMessenger::~DetectorMessenger()
{
delete fNbLayersCmd;
delete fAbsMaterCmd; delete fGapMaterCmd;
delete fAbsThickCmd; delete fGapThickCmd;
delete fSizeYZCmd;
delete fAbsMaterCmd;
delete fGapMaterCmd;
delete fAbsThickCmd;
delete fGapThickCmd;
delete fSizeYZCmd;
delete fDetDir;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == fAbsMaterCmd ) {
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if( command == fAbsMaterCmd ) {
fDetector->SetAbsorberMaterial(newValue);
}
else if( command == fGapMaterCmd ) {
return;
}
if( command == fGapMaterCmd ) {
fDetector->SetGapMaterial(newValue);
return;
}
else if( command == fAbsThickCmd ) {
fDetector
->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
}
else if( command == fGapThickCmd ) {
if( command == fAbsThickCmd ) {
fDetector->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
return;
}
if( command == fGapThickCmd ) {
fDetector->SetGapThickness(fGapThickCmd->GetNewDoubleValue(newValue));
return;
}
else if( command == fSizeYZCmd ) {
if( command == fSizeYZCmd ) {
fDetector->SetCalorSizeYZ(fSizeYZCmd->GetNewDoubleValue(newValue));
}
else if( command == fNbLayersCmd ) {
return;
}
if( command == fNbLayersCmd ) {
fDetector->SetNbOfLayers(fNbLayersCmd->GetNewIntValue(newValue));
return;
}
}
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -43,30 +43,25 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction(RunAction* run, HistoManager* histo)
:G4UserEventAction(),
fRunAct(run),fHistoManager(histo),
fEnergyAbs(0.), fEnergyGap(0.),
fTrackLAbs(0.), fTrackLGap(0.),
fPrintModulo(0)
{
fPrintModulo = 100; }
: fRunAct(run),fHistoManager(histo)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{ }
EventAction::~EventAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event* evt)
{
{
G4int evtNb = evt->GetEventID();
if (evtNb%fPrintModulo == 0)
if (evtNb%fPrintModulo == 0) {
G4cout << "\n---> Begin of event: " << evtNb << G4endl;
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -76,17 +71,17 @@ void EventAction::EndOfEventAction(const G4Event*)
//accumulates statistic
//
fRunAct->FillPerEvent(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
//fill histograms
//
fHistoManager->FillHisto(0, fEnergyAbs);
fHistoManager->FillHisto(1, fEnergyGap);
fHistoManager->FillHisto(2, fTrackLAbs);
fHistoManager->FillHisto(3, fTrackLGap);
//fill ntuple
//
fHistoManager->FillNtuple(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,7 @@
//
/// \file PrimaryGeneratorAction.cc
/// \brief Implementation of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,10 +41,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
: G4VUserPrimaryGeneratorAction(),
fParticleGun(0),
fDetector(DC)
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* dc)
: fDetector(dc)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
@@ -56,8 +51,7 @@ PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition* particle
= particleTable->FindParticle(particleName="e-");
G4ParticleDefinition* particle = particleTable->FindParticle(particleName="e-");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.));
fParticleGun->SetParticleEnergy(500.*MeV);
@@ -78,7 +72,7 @@ PrimaryGeneratorAction::~PrimaryGeneratorAction()
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
//this function is called at the begining of event
//
//
fParticleGun->GeneratePrimaryVertex(anEvent);
}
@@ -36,101 +36,136 @@
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4AccumulableManager.hh"
#include "G4UnitsTable.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(HistoManager* histo)
: G4UserRunAction(),
fHistoManager(histo),
fSumEAbs(0.), fSum2EAbs(0.),
fSumEGap(0.), fSum2EGap(0.),
fSumLAbs(0.), fSum2LAbs(0.),
fSumLGap(0.), fSum2LGap(0.)
{}
: fHistoManager(histo)
{
// Register accumulable to the accumulable manager
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->RegisterAccumulable(fSumEAbs);
accumulableManager->RegisterAccumulable(fSum2EAbs);
accumulableManager->RegisterAccumulable(fSumEGap);
accumulableManager->RegisterAccumulable(fSum2EGap);
accumulableManager->RegisterAccumulable(fSumLAbs);
accumulableManager->RegisterAccumulable(fSum2LAbs);
accumulableManager->RegisterAccumulable(fSumLGap);
accumulableManager->RegisterAccumulable(fSum2LGap);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{}
RunAction::~RunAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
{
G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl;
//initialize cumulative quantities
//
fSumEAbs = fSum2EAbs =fSumEGap = fSum2EGap = 0.;
fSumLAbs = fSum2LAbs =fSumLGap = fSum2LGap = 0.;
// reset accumulables to their initial values
G4AccumulableManager::Instance()->Reset();
//histograms
//
fHistoManager->Book();
fHistoManager->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::FillPerEvent(G4double EAbs, G4double EGap,
G4double LAbs, G4double LGap)
G4double LAbs, G4double LGap)
{
//accumulate statistic
//
fSumEAbs += EAbs; fSum2EAbs += EAbs*EAbs;
fSumEGap += EGap; fSum2EGap += EGap*EGap;
fSumLAbs += LAbs; fSum2LAbs += LAbs*LAbs;
fSumLGap += LGap; fSum2LGap += LGap*LGap;
fSumLGap += LGap; fSum2LGap += LGap*LGap;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run* aRun)
{
G4int NbOfEvents = aRun->GetNumberOfEvent();
if (NbOfEvents == 0) return;
// Merge accumulables
G4AccumulableManager::Instance()->Merge();
G4int nofEvents = aRun->GetNumberOfEvent();
if (nofEvents == 0) {
// close open files
fHistoManager->Save();
return;
}
//compute statistics: mean and rms
//
fSumEAbs /= NbOfEvents; fSum2EAbs /= NbOfEvents;
G4double rmsEAbs = fSum2EAbs - fSumEAbs*fSumEAbs;
if (rmsEAbs >0.) rmsEAbs = std::sqrt(rmsEAbs); else rmsEAbs = 0.;
fSumEGap /= NbOfEvents; fSum2EGap /= NbOfEvents;
G4double rmsEGap = fSum2EGap - fSumEGap*fSumEGap;
if (rmsEGap >0.) rmsEGap = std::sqrt(rmsEGap); else rmsEGap = 0.;
fSumLAbs /= NbOfEvents; fSum2LAbs /= NbOfEvents;
G4double rmsLAbs = fSum2LAbs - fSumLAbs*fSumLAbs;
if (rmsLAbs >0.) rmsLAbs = std::sqrt(rmsLAbs); else rmsLAbs = 0.;
fSumLGap /= NbOfEvents; fSum2LGap /= NbOfEvents;
G4double rmsLGap = fSum2LGap - fSumLGap*fSumLGap;
if (rmsLGap >0.) rmsLGap = std::sqrt(rmsLGap); else rmsLGap = 0.;
auto sumEAbs = fSumEAbs.GetValue();
auto sum2EAbs = fSum2EAbs.GetValue();
sumEAbs /= nofEvents; sum2EAbs /= nofEvents;
auto rmsEAbs = sum2EAbs - sumEAbs*sumEAbs;
if (rmsEAbs >0.) {
rmsEAbs = std::sqrt(rmsEAbs);
} else {
rmsEAbs = 0.;
}
auto sumEGap = fSumEGap.GetValue();
auto sum2EGap = fSum2EGap.GetValue();
sumEGap /= nofEvents; sum2EGap /= nofEvents;
auto rmsEGap = sum2EGap - sumEGap*sumEGap;
if (rmsEGap >0.) {
rmsEGap = std::sqrt(rmsEGap);
} else {
rmsEGap = 0.;
}
auto sumLAbs = fSumLAbs.GetValue();
auto sum2LAbs = fSum2LAbs.GetValue();
sumLAbs /= nofEvents; sum2LAbs /= nofEvents;
auto rmsLAbs = sum2LAbs - sumLAbs*sumLAbs;
if (rmsLAbs >0.) {
rmsLAbs = std::sqrt(rmsLAbs);
} else {
rmsLAbs = 0.;
}
auto sumLGap = fSumLGap.GetValue();
auto sum2LGap = fSum2LGap.GetValue();
sumLGap /= nofEvents; sum2LGap /= nofEvents;
G4double rmsLGap = sum2LGap - sumLGap*sumLGap;
if (rmsLGap >0.) {
rmsLGap = std::sqrt(rmsLGap);
} else {
rmsLGap = 0.;
}
//print
//
G4cout
<< "\n--------------------End of Run------------------------------\n"
<< "\n mean Energy in Absorber : " << G4BestUnit(fSumEAbs,"Energy")
<< " +- " << G4BestUnit(rmsEAbs,"Energy")
<< "\n mean Energy in Gap : " << G4BestUnit(fSumEGap,"Energy")
<< "\n mean Energy in Absorber : " << G4BestUnit(sumEAbs,"Energy")
<< " +- " << G4BestUnit(rmsEAbs,"Energy")
<< "\n mean Energy in Gap : " << G4BestUnit(sumEGap,"Energy")
<< " +- " << G4BestUnit(rmsEGap,"Energy")
<< G4endl;
G4cout
<< "\n mean trackLength in Absorber : " << G4BestUnit(fSumLAbs,"Length")
<< " +- " << G4BestUnit(rmsLAbs,"Length")
<< "\n mean trackLength in Gap : " << G4BestUnit(fSumLGap,"Length")
<< "\n mean trackLength in Absorber : " << G4BestUnit(sumLAbs,"Length")
<< " +- " << G4BestUnit(rmsLAbs,"Length")
<< "\n mean trackLength in Gap : " << G4BestUnit(sumLGap,"Length")
<< " +- " << G4BestUnit(rmsLGap,"Length")
<< "\n------------------------------------------------------------\n"
<< G4endl;
//save histograms
//
fHistoManager->PrintStatistic();
fHistoManager->Save();
fHistoManager->Save();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,7 @@
//
/// \file SteppingAction.cc
/// \brief Implementation of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,34 +38,32 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction(DetectorConstruction* det,
EventAction* evt)
: G4UserSteppingAction(),
fDetector(det), fEventAction(evt)
{ }
SteppingAction::SteppingAction(DetectorConstruction* det, EventAction* evt)
: fDetector(det), fEventAction(evt)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::~SteppingAction()
{ }
SteppingAction::~SteppingAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction(const G4Step* aStep)
{
// get volume of the current step
G4VPhysicalVolume* volume
= aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
G4VPhysicalVolume* volume =
aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
// collect energy and track length step by step
G4double edep = aStep->GetTotalEnergyDeposit();
G4double stepl = 0.;
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.)
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.) {
stepl = aStep->GetStepLength();
if (volume == fDetector->GetAbsorber()) fEventAction->AddAbs(edep,stepl);
if (volume == fDetector->GetGap()) fEventAction->AddGap(edep,stepl);
}
if (volume == fDetector->GetAbsorber()) { fEventAction->AddAbs(edep,stepl); }
if (volume == fDetector->GetGap()) { fEventAction->AddGap(edep,stepl); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file analysis/AnaEx02/src/HistoManager.cc
/// \brief Implementation of the HistoManager class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,42 +41,35 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HistoManager::HistoManager()
:fRootFile(0),
fNtuple1(0), fNtuple2(0),
fEabs(0.), fEgap(0.) ,fLabs(0.), fLgap(0.)
{
// histograms
for (G4int k=0; k<kMaxHisto; k++) fHisto[k] = 0;
// ntuple
fNtuple1 = 0;
fNtuple2 = 0;
// // histograms
// for (G4int k=0; k<kMaxHisto; k++) fHisto[k] = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HistoManager::~HistoManager()
{
if (fRootFile) delete fRootFile;
delete fRootFile;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HistoManager::Book()
{
{
// Creating a tree container to handle histograms and ntuples.
// This tree is associated to an output file.
//
G4String fileName = "AnaEx02.root";
fRootFile = new TFile(fileName,"RECREATE");
if (! fRootFile) {
G4cout << " HistoManager::Book :"
if (fRootFile == nullptr) {
G4cout << " HistoManager::Book :"
<< " problem creating the ROOT TFile "
<< G4endl;
return;
}
// id = 0
fHisto[0] = new TH1D("EAbs", "Edep in absorber (MeV)", 100, 0., 800*CLHEP::MeV);
// id = 1
@@ -87,31 +80,34 @@ void HistoManager::Book()
fHisto[3] = new TH1D("LGap", "trackL in gap (mm)", 100, 0., 50*CLHEP::cm);
for ( G4int i=0; i<kMaxHisto; ++i ) {
if (! fHisto[i]) G4cout << "\n can't create histo " << i << G4endl;
}
if (fHisto[i] == nullptr) {
G4cout << "\n can't create histo " << i << G4endl;
}
}
// create 1st ntuple
fNtuple1 = new TTree("Ntuple1", "Edep");
fNtuple1->Branch("Eabs", &fEabs, "Eabs/D");
fNtuple1->Branch("Egap", &fEgap, "Egap/D");
// create 2nd ntuple
// create 2nd ntuple
fNtuple2 = new TTree("Ntuple2", "TrackL");
fNtuple2->Branch("Labs", &fLabs, "Labs/D");
fNtuple2->Branch("Lgap", &fLgap, "Lgap/D");
G4cout << "\n----> Output file is open in " << fileName << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HistoManager::Save()
{
if (! fRootFile) return;
{
if (fRootFile == nullptr) { return;
}
fRootFile->Write(); // Writing the histograms to the file
fRootFile->Close(); // and closing the tree (and the file)
G4cout << "\n----> Histograms and ntuples are saved\n" << G4endl;
}
@@ -125,7 +121,7 @@ void HistoManager::FillHisto(G4int ih, G4double xbin, G4double weight)
<< G4endl;
return;
}
if (fHisto[ih]) { fHisto[ih]->Fill(xbin, weight); }
if (fHisto[ih] != nullptr) { fHisto[ih]->Fill(xbin, weight); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -137,7 +133,9 @@ void HistoManager::Normalize(G4int ih, G4double fac)
<< " does not exist. (fac=" << fac << ")" << G4endl;
return;
}
if (fHisto[ih]) fHisto[ih]->Scale(fac);
if (fHisto[ih] != nullptr) {
fHisto[ih]->Scale(fac);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -150,8 +148,8 @@ void HistoManager::FillNtuple(G4double energyAbs, G4double energyGap,
fLabs = trackLAbs;
fLgap = trackLGap;
if (fNtuple1) fNtuple1->Fill();
if (fNtuple2) fNtuple2->Fill();
if (fNtuple1 != nullptr) { fNtuple1->Fill(); }
if (fNtuple2 != nullptr) { fNtuple2->Fill(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -159,17 +157,16 @@ void HistoManager::FillNtuple(G4double energyAbs, G4double energyGap,
void HistoManager::PrintStatistic()
{
G4cout << "\n ----> print histograms statistic \n" << G4endl;
for ( G4int i=0; i<kMaxHisto; ++i ) {
TH1D* h1 = fHisto[i];
const G4String name = h1->GetName();
for (auto h1 : fHisto) {
const G4String name = h1->GetName();
G4String unitCategory;
if (name[0] == 'E' ) unitCategory = "Energy";
if (name[0] == 'L' ) unitCategory = "Length";
if (name[0] == 'E' ) { unitCategory = "Energy"; }
if (name[0] == 'L' ) { unitCategory = "Length"; }
G4cout << name
<< ": mean = " << G4BestUnit(h1->GetMean(), unitCategory)
<< " rms = " << G4BestUnit(h1->GetRMS(), unitCategory )
<< ": mean = " << G4BestUnit(h1->GetMean(), unitCategory)
<< " rms = " << G4BestUnit(h1->GetRMS(), unitCategory )
<< G4endl;
}
}
@@ -0,0 +1,96 @@
///\file "analysis/AnaEx03/.README.txt"
///\brief Example AnaEx03 README page
/*! \page ExampleAnaEx03 Example AnaEx03
Example AnaEx03 demonstrates usage of analysis commands for file management
(new since Geant4 11.1), in particular writing histograms and ntuples in a file
multiple times.
It uses the same scenario (detector description, primary generator
and physics) as \link ExampleAnaEx01 AnaEx01 \endlink and \link ExampleAnaEx02 AnaEx02 \endlink.
In difference from these examples
the analysis manipulations (histograms and ntuples booking and filling)
are performed directly with G4AnalysisManager. The classes that are same
in all three examples are located in shared directory.
For detector description, primary generator, physics and the example output
see \link ExampleAnaEx01 README in AnaEx01 \endlink example.
\section AnaEx03_s1 Histograms, Ntuple:
The example produces the same 4 histograms and 2 ntuples as in AnaEx01.
These histos and ntuples are booked in the RunAction constructor and filled from
EventAction.
The file managent in this example, usually performed via calls to G4AnalysisManager
OpenFile(), Write() and CloseFile() in the code, is in this example performed
via UI commands in a macro:
\verbatim
/analysis/openFile
/analysis/write
/analysis/closeFile
\endverbatim
Note that the file does not need to be closed at each end of run and the histograms and ntuples
can be saved in the same file multiple time. In that case we need to reset the histograms
and ntuples data before a new run:
\verbatim
/analysis/reset
\endverbatim
We can define the default file type and set it to the analysis manager via
\verbatim
/analysis/setDefaultFileType root # or csv hdf5 xml
\endverbatim
The file names then need not to be provided with the file extension and the same macro
can be used with different output types.
It should be notes that using UI commands for writing histograms and ntuples in a file
multiple times is not necessary, the same can be achieved by calls to G4AnalysisManager
functions from the code using conditional statements.
\section AnaEx03_s2 Macros
- The AnaEx03.in macro performs 5 runs and produces 2 files: e-.root, containg data from first
3 runs, and proton.root, containing data from the next 2 runs.
The macro uses the defaultFileType parameter (alias), which default value, "root" is
defined in main.
- AnaEx03-csv.in, AnaEx03-hdf5.in, AnaEx03-root.in, AnaEx03-xml.in:
In these macros, the default value of the defaultFileType is overritten with
\verbatim
/control/alias defaultFileType cvs # or hdf5 root xml
\endverbatim
and then the AnaEx03.in macro is called.
\section AnaEx03_s3 How to run
- It is preferable to execute the exampole in the 'batch' mode from macro files:
\verbatim
% ./AnaEx03 AnaEx03.in
% ./AnaEx03 AnaEx03.in >& output
\endverbatim
- When executing AnaEx03 in the 'interactive mode' with visualization, be careful not
to forget to issue the /analysis/openFile command befor starting a run:
\verbatim
% ./AnaEx03
and type in the commands from AnaEx03[-xyz].mac line by line:
Idle> /analysis/openFile myFile
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> ...
Idle> /analysis/write
Idle> /analysis/closeFile
....
Idle> exit
\endverbatim
All AnaEx03-*.in macros are used in Geant4 testing.
*/
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx03 example
# with csv file type
#
/control/alias defaultFileType csv
/control/execute AnaEx03.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx03 example
# with hdf5 file type
#
/control/alias defaultFileType hdf5
/control/execute AnaEx03.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx03 example
# with root file type (default)
#
/control/alias defaultFileType root
/control/execute AnaEx03.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#
# Macro file for the test of AnaEx03 example
# with xml file type
#
/control/alias defaultFileType xml
/control/execute AnaEx03.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,99 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file analysis/AnaEx03/AnaEx03.cc
/// \brief Main program of the analysis/AnaEx03 example
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "FTFP_BERT.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv)
{
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = nullptr;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
// Construct the default run manager
//
auto* runManager = G4RunManagerFactory::CreateRunManager();
G4int nThreads = 4;
runManager->SetNumberOfThreads(nThreads);
// Set mandatory initialization classes
//
auto detector = new DetectorConstruction;
runManager->SetUserInitialization(detector);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization(detector));
// Initialize visualization
//
G4VisManager* visManager = new G4VisExecutive;
visManager->Initialize();
// Get the pointer to the User Interface manager
//
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if ( ui == nullptr ) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand("/control/alias defaultFileType root");
// define the default value for alias used in AnaEx03.in
UImanager->ApplyCommand(command+fileName);
}
else {
// interactive mode
UImanager->ApplyCommand("/control/execute init_vis.mac");
ui->SessionStart();
delete ui;
}
// Job termination
delete visManager;
delete runManager;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,58 @@
#
# Macro file for the test of AnaEx03 example
#
#
#/run/numberOfThreads 2
# reduce output in MT
/control/cout/ignoreThreadsExcept 0
# initialize
/run/initialize
# set file type via parameter passed from calling macro
# or use the default value "root" set in main
/analysis/setDefaultFileType {defaultFileType}
# open analysis file
/analysis/openFile e-
# e- 100MeV
/gun/particle e-
/gun/energy 100 MeV
/run/beamOn 10
/analysis/write
/analysis/reset
# e- 200MeV
/gun/energy 200 MeV
#
/run/beamOn 20
/analysis/write
/analysis/reset
#
# e- 300MeV
/gun/energy 300 MeV
#
/run/beamOn 30
/analysis/write
/analysis/closeFile
# open analysis file
/analysis/openFile proton
# proton 400MeV
/gun/particle proton
/gun/energy 400 MeV
/run/beamOn 40
/analysis/write
/analysis/reset
# proton 500MeV
/gun/energy 500 MeV
#
/run/beamOn 50
/analysis/write
/analysis/closeFile
#
@@ -0,0 +1,59 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.16...3.21)
project(AnaEx03)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
# to build a batch mode only executable
#
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
#----------------------------------------------------------------------------
# Setup Geant4 include directories and compile definitions
#
include(${Geant4_USE_FILE})
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/shared/include
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc
${PROJECT_SOURCE_DIR}/shared/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh
${PROJECT_SOURCE_DIR}/shared/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(AnaEx03 AnaEx03.cc
${sources} ${add_sources} ${fortran_sources}
${headers} ${add_headers})
target_link_libraries(AnaEx03 ${Geant4_LIBRARIES} ${HBOOK_LIBRARIES})
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build AnaEx03. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(AnaEx03_FILES
AnaEx03.in AnaEx03-csv.in AnaEx03-hdf5.in AnaEx03-root.in AnaEx03-xml.in init_vis.mac vis.mac
histo ntuple)
foreach(_file ${AnaEx03_FILES})
file(COPY ${PROJECT_SOURCE_DIR}/${_file} DESTINATION ${PROJECT_BINARY_DIR})
endforeach()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS AnaEx03 DESTINATION bin)
@@ -0,0 +1,33 @@
# --------------------------------------------------------------
# GNUmakefile for examples module. Gabriele Cosmo, 06/04/98.
# --------------------------------------------------------------
name := AnaEx03
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../../..
endif
.PHONY: setup clean_setup all
all: lib bin
setup:
@echo "Copying files from shared"
@./shared/scripts/copy_files.sh shared
clean_setup:
@echo "Removing files copied from shared"
@./shared/scripts/clean_files.sh shared
include $(G4INSTALL)/config/binmake.gmk
CPPFLAGS += -I./shared/include
visclean:
rm -f g4*.prim g4*.eps g4*.wrl
rm -f .DAWN_*
histclean:
rm ${G4WORKDIR}/tmp/${G4SYSTEM}/${G4TARGET}/HistoManager.o
@@ -0,0 +1,12 @@
# Example AnaEx03 History
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
## 2022-11-09 I. Hrivnacova (AnaEx03-V11-00-01)
- Fixed README files
## 2022-10-19 I. Hrivnacova (AnaEx03-V11-00-00)
- First version
+91
View File
@@ -0,0 +1,91 @@
--------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
AnaEx03
-------
Example AnaEx03 demonstrates usage of analysis commands for file management
(new since Geant4 11.1), in particular writing histograms and ntuples in a file
multiple times.
It uses the same scenario (detector description, primary generator
and physics) as AnaEx02 and AnaEx02. In difference from these examples
the analysis manipulations (histograms and ntuples booking and filling)
are performed directly with G4AnalysisManager. The classes that are same
in all three examples are located in shared directory.
For detector description, primary generator, physics and the example output
see README in AnaEx01 example.
Histograms, Ntuple:
--------------------
The example produces the same 4 histograms and 2 ntuples as in AnaEx01.
These histos and ntuples are booked in the RunAction constructor and filled from
EventAction.
The file managent in this example, usually performed via calls to G4AnalysisManager
OpenFile(), Write() and CloseFile() in the code, is in this example performed
via UI commands in a macro:
/analysis/openFile
/analysis/write
/analysis/closeFile
Note that the file need not to be closed at each end of run, but the histograms and ntuples
can be saved in the same file multiple time. In that case we need to reset the histograms
and ntuples data before a new run:
/analysis/reset
We can define the default file type and set it to the analysis manager via
/analysis/setDefaultFileType root # or csv hdf5 xml
The file names then need not to be provided with the file extension and the same macro
can be used with different output types.
It should be notes that using UI commands for writing histograms and ntuples in a file
multiple times is not necessary, the same can be achieved by calls to G4AnalysisManager
functions from the code using conditional statements.
Macros:
--------
The AnaEx03.in macro performs 5 runs and produces 2 files: e-.root, containg data from first
3 runs, and proton.root, containing data from the next 2 runs.
The macro uses the defaultFileType parameter (alias), which default value, "root" is
defined in main.
AnaEx03-csv.in, AnaEx03-hdf5.in, AnaEx03-root.in, AnaEx03-xml.in:
In these macros, the default value of the defaultFileType is overritten with
/control/alias defaultFileType cvs # or hdf5 root xml
and then the AnaEx03.in macro is called.
How to run
--------------
- It is preferable to execute the exampole in the 'batch' mode from macro files:
% ./AnaEx03 AnaEx03.in
% ./AnaEx03 AnaEx03.in >& output
- When executing AnaEx03 in the 'interactive mode' with visualization, be careful not
to forget to issue the /analysis/openFile command befor starting a run:
% ./AnaEx03
and type in the commands from AnaEx03[-xyz].mac line by line:
Idle> /analysis/openFile myFile
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> ...
Idle> /analysis/write
Idle> /analysis/closeFile
....
Idle> exit
All AnaEx03-*.in macros are used in Geant4 testing.
@@ -0,0 +1,2 @@
This directory will be used for saving histogram files
when running AnaEx01 example with the Csv output type
@@ -41,10 +41,10 @@ class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization(DetectorConstruction* detector);
virtual ~ActionInitialization();
~ActionInitialization() override;
virtual void BuildForMaster() const;
virtual void Build() const;
void BuildForMaster() const override;
void Build() const override;
private:
DetectorConstruction* fDetector;
@@ -52,4 +52,4 @@ class ActionInitialization : public G4VUserActionInitialization
#endif
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -47,27 +47,26 @@ class HistoManager;
class EventAction : public G4UserEventAction
{
public:
EventAction(RunAction*, HistoManager*);
virtual ~EventAction();
EventAction();
~EventAction() override;
void BeginOfEventAction(const G4Event*) override;
void EndOfEventAction(const G4Event*) override;
virtual void BeginOfEventAction(const G4Event*);
virtual void EndOfEventAction(const G4Event*);
void AddAbs(G4double de, G4double dl) {fEnergyAbs += de; fTrackLAbs += dl;};
void AddGap(G4double de, G4double dl) {fEnergyGap += de; fTrackLGap += dl;};
private:
RunAction* fRunAct;
HistoManager* fHistoManager;
G4double fEnergyAbs, fEnergyGap;
G4double fTrackLAbs, fTrackLGap;
G4int fPrintModulo;
G4double fEnergyAbs = 0;
G4double fEnergyGap = 0;
G4double fTrackLAbs = 0;
G4double fTrackLGap = 0;
G4int fPrintModulo = 100;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -28,7 +28,7 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,30 +42,20 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4Run;
class HistoManager;
class RunAction : public G4UserRunAction
{
public:
RunAction(HistoManager*);
virtual ~RunAction();
RunAction();
~RunAction() override;
virtual void BeginOfRunAction(const G4Run*);
virtual void EndOfRunAction(const G4Run*);
void FillPerEvent(G4double, G4double, G4double, G4double);
void BeginOfRunAction(const G4Run*) override;
void EndOfRunAction(const G4Run*) override;
private:
HistoManager* fHistoManager;
G4double fSumEAbs, fSum2EAbs;
G4double fSumEGap, fSum2EGap;
G4double fSumLAbs, fSum2LAbs;
G4double fSumLGap, fSum2LGap;
void PrintStatistic();
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,16 @@
# Macro file for the initialization of example B1
# in interactive session
#
# Set some default verbose
/control/verbose 2
/control/saveHistory
/run/verbose 2
#
# Change the default number of threads (in multi-threaded mode)
#/run/numberOfThreads 4
#
# Initialize kernel
/run/initialize
#
# Visualization setting
/control/execute vis.mac
@@ -0,0 +1,2 @@
This directory will be used for saving ntuple files
when running AnaEx01 example with the Csv output type
@@ -0,0 +1,27 @@
{
gROOT->Reset();
// Draw histos filled by Geant4 simulation
//
TFile f = TFile("e-.root");
TCanvas* c1 = new TCanvas("c1", " ");
c1->Divide(2,2);
TDirectory* dir = (TDirectory*)f.Get("histo");
c1->cd(1);
TH1D* hist1 = (TH1D*)dir->Get("EAbs");
hist1->Draw("HIST");
c1->cd(2);
TH1D* hist2 = (TH1D*)dir->Get("EGap");
hist2->Draw("HIST");
c1->cd(3);
TH1D* hist3 = (TH1D*)dir->Get("LAbs");
hist3->Draw("HIST");
c1->cd(4);
TH1D* hist4 = (TH1D*)dir->Get("LGap");
hist4->Draw("HIST");
}
@@ -0,0 +1,143 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef DetectorConstruction_h
#define DetectorConstruction_h 1
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "CLHEP/Units/SystemOfUnits.h"
class G4Box;
class G4LogicalVolume;
class G4VPhysicalVolume;
class G4Material;
class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction() override;
public:
G4VPhysicalVolume* Construct() override;
void SetAbsorberMaterial (const G4String&);
void SetAbsorberThickness(G4double);
void SetGapMaterial (const G4String&);
void SetGapThickness(G4double);
void SetCalorSizeYZ(G4double);
void SetNbOfLayers (G4int);
void PrintCalorParameters();
G4double GetWorldSizeX() { return fWorldSizeX; }
G4double GetWorldSizeYZ() { return fWorldSizeYZ; }
G4double GetCalorThickness() { return fCalorThickness; }
G4double GetCalorSizeYZ() { return fCalorSizeYZ; }
G4int GetNbOfLayers() { return fNbOfLayers; }
G4Material* GetAbsorberMaterial() { return fAbsorberMaterial; }
G4double GetAbsorberThickness() { return fAbsorberThickness; }
G4Material* GetGapMaterial() { return fGapMaterial; }
G4double GetGapThickness() { return fGapThickness; }
const G4VPhysicalVolume* GetphysiWorld() { return fPhysiWorld; }
const G4VPhysicalVolume* GetAbsorber() { return fPhysiAbsorber; }
const G4VPhysicalVolume* GetGap() { return fPhysiGap; }
private:
void DefineMaterials();
void ComputeCalorParameters();
G4VPhysicalVolume* ConstructCalorimeter();
G4Material* fAbsorberMaterial = nullptr;
G4Material* fGapMaterial = nullptr;
G4Material* fDefaultMaterial = nullptr;
G4int fNbOfLayers = 10;
G4double fAbsorberThickness = 10.*CLHEP::mm;
G4double fGapThickness = 5.*CLHEP::mm;
G4double fCalorSizeYZ = 10.*CLHEP::cm;
G4double fCalorThickness = 0.; // will be computed
G4double fLayerThickness= 0.; // will be computed
G4double fWorldSizeYZ = 0.; // will be computed;
G4double fWorldSizeX = 0.; // will be computed;
G4Box* fSolidWorld = nullptr; //pointer to the solid World
G4LogicalVolume* fLogicWorld = nullptr; //pointer to the logical World
G4VPhysicalVolume* fPhysiWorld = nullptr; //pointer to the physical World
G4Box* fSolidCalor = nullptr; //pointer to the solid Calor
G4LogicalVolume* fLogicCalor = nullptr; //pointer to the logical Calor
G4VPhysicalVolume* fPhysiCalor = nullptr; //pointer to the physical Calor
G4Box* fSolidLayer = nullptr; //pointer to the solid Layer
G4LogicalVolume* fLogicLayer = nullptr; //pointer to the logical Layer
G4VPhysicalVolume* fPhysiLayer = nullptr; //pointer to the physical Layer
G4Box* fSolidAbsorber = nullptr; //pointer to the solid Absorber
G4LogicalVolume* fLogicAbsorber = nullptr; //pointer to the logical Absorber
G4VPhysicalVolume* fPhysiAbsorber = nullptr; //pointer to the physical Absorber
G4Box* fSolidGap = nullptr; //pointer to the solid Gap
G4LogicalVolume* fLogicGap = nullptr; //pointer to the logical Gap
G4VPhysicalVolume* fPhysiGap = nullptr; //pointer to the physical Gap
DetectorMessenger* fDetectorMessenger = nullptr; //pointer to the Messenger
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void DetectorConstruction::ComputeCalorParameters()
{
// Compute derived parameters of the calorimeter
fLayerThickness = fAbsorberThickness + fGapThickness;
fCalorThickness = fNbOfLayers*fLayerThickness;
fWorldSizeX = 1.2*fCalorThickness; fWorldSizeYZ = 1.2*fCalorSizeYZ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,7 +40,6 @@ class G4UIdirectory;
class G4UIcmdWithAString;
class G4UIcmdWithAnInteger;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -52,23 +47,22 @@ class DetectorMessenger: public G4UImessenger
{
public:
DetectorMessenger(DetectorConstruction* );
virtual ~DetectorMessenger();
virtual void SetNewValue(G4UIcommand*, G4String);
~DetectorMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetDir;
G4UIcmdWithAString* fAbsMaterCmd;
G4UIcmdWithAString* fGapMaterCmd;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd;
G4UIcmdWithADoubleAndUnit* fGapThickCmd;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd;
G4UIcmdWithAnInteger* fNbLayersCmd;
DetectorConstruction* fDetector = nullptr;
G4UIdirectory* fDetDir = nullptr;
G4UIcmdWithAString* fAbsMaterCmd = nullptr;
G4UIcmdWithAString* fGapMaterCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fAbsThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fGapThickCmd = nullptr;
G4UIcmdWithADoubleAndUnit* fSizeYZCmd = nullptr;
G4UIcmdWithAnInteger* fNbLayersCmd = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -25,10 +25,6 @@
//
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,14 +44,14 @@ class DetectorConstruction;
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction(DetectorConstruction*);
virtual ~PrimaryGeneratorAction();
PrimaryGeneratorAction(DetectorConstruction*);
~PrimaryGeneratorAction() override;
virtual void GeneratePrimaries(G4Event*);
void GeneratePrimaries(G4Event*) override;
private:
G4ParticleGun* fParticleGun; //pointer a to G4 class
DetectorConstruction* fDetector; //pointer to the geometry
G4ParticleGun* fParticleGun = nullptr; //pointer a to G4 class
DetectorConstruction* fDetector = nullptr; //pointer to the geometry
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -47,13 +43,13 @@ class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction(DetectorConstruction*, EventAction*);
virtual ~SteppingAction();
~SteppingAction() override;
void UserSteppingAction(const G4Step*) override;
virtual void UserSteppingAction(const G4Step*);
private:
DetectorConstruction* fDetector;
EventAction* fEventAction;
DetectorConstruction* fDetector = nullptr;
EventAction* fEventAction = nullptr;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -9,10 +9,10 @@ DIRNAME=$1
for FILE in `ls $DIRNAME/include`; do
rm -f include/$FILE
done
done
for FILE in `ls $DIRNAME/src`; do
rm -f src/$FILE
done
done
echo "... clean_files.sh from $1 finished"
@@ -0,0 +1,327 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVReplica.hh"
#include "G4StateManager.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
{
ComputeCalorParameters();
// materials
DefineMaterials();
SetAbsorberMaterial("G4_Pb");
SetGapMaterial("G4_lAr");
// create commands for interactive definition of the calorimeter
fDetectorMessenger = new DetectorMessenger(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
{
return ConstructCalorimeter();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineMaterials()
{
// use G4-NIST materials data base
//
G4NistManager* man = G4NistManager::Instance();
fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
man->FindOrBuildMaterial("G4_Pb");
man->FindOrBuildMaterial("G4_lAr");
// print table
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
{
// Clean old geometry, if any
//
G4GeometryManager::GetInstance()->OpenGeometry();
G4PhysicalVolumeStore::GetInstance()->Clean();
G4LogicalVolumeStore::GetInstance()->Clean();
G4SolidStore::GetInstance()->Clean();
// complete the Calor parameters definition
ComputeCalorParameters();
//
// World
//
fSolidWorld = new G4Box("World", //its name
fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
fLogicWorld = new G4LogicalVolume(fSolidWorld, //its solid
fDefaultMaterial, //its material
"World"); //its name
fPhysiWorld = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicWorld, //its logical volume
"World", //its name
nullptr, //its mother volume
false, //no boolean operation
0); //copy number
//
// Calorimeter
//
fSolidCalor = nullptr; fLogicCalor = nullptr; fPhysiCalor = nullptr;
fSolidLayer = nullptr; fLogicLayer = nullptr; fPhysiLayer = nullptr;
if (fCalorThickness > 0.) {
fSolidCalor = new G4Box("Calorimeter", //its name
fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
fDefaultMaterial, //its material
"Calorimeter"); //its name
fPhysiCalor = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicCalor, //its logical volume
"Calorimeter", //its name
fLogicWorld, //its mother volume
false, //no boolean operation
0); //copy number
//
// Layer
//
fSolidLayer = new G4Box("Layer", //its name
fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
fDefaultMaterial, //its material
"Layer"); //its name
if (fNbOfLayers > 1) {
fPhysiLayer = new G4PVReplica("Layer", //its name
fLogicLayer, //its logical volume
fLogicCalor, //its mother
kXAxis, //axis of replication
fNbOfLayers, //number of replica
fLayerThickness); //witdth of replica
}
else {
fPhysiLayer = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(), //at (0,0,0)
fLogicLayer, //its logical volume
"Layer", //its name
fLogicCalor, //its mother volume
false, //no boolean operation
0); //copy number
}
}
//
// Absorber
//
fSolidAbsorber = nullptr; fLogicAbsorber = nullptr; fPhysiAbsorber = nullptr;
if (fAbsorberThickness > 0.) {
fSolidAbsorber = new G4Box("Absorber", //its name
fAbsorberThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, //its solid
fAbsorberMaterial, //its material
fAbsorberMaterial->GetName()); //name
fPhysiAbsorber = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(-fGapThickness/2,0.,0.), //its position
fLogicAbsorber, //its logical volume
fAbsorberMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
//
// Gap
//
fSolidGap = nullptr; fLogicGap = nullptr; fPhysiGap = nullptr;
if (fGapThickness > 0.) {
fSolidGap = new G4Box("Gap",
fGapThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
fLogicGap = new G4LogicalVolume(fSolidGap,
fGapMaterial,
fGapMaterial->GetName());
fPhysiGap = new G4PVPlacement(nullptr, //no rotation
G4ThreeVector(fAbsorberThickness/2,0.,0.), //its position
fLogicGap, //its logical volume
fGapMaterial->GetName(), //its name
fLogicLayer, //its mother
false, //no boulean operat
0); //copy number
}
PrintCalorParameters();
//
// Visualization attributes
//
fLogicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
auto simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
simpleBoxVisAtt->SetVisibility(true);
fLogicCalor->SetVisAttributes(simpleBoxVisAtt);
//
//always return the physical World
//
return fPhysiWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::PrintCalorParameters()
{
G4cout << "\n------------------------------------------------------------"
<< "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ "
<< fAbsorberThickness/mm << "mm of " << fAbsorberMaterial->GetName()
<< " + "
<< fGapThickness/mm << "mm of " << fGapMaterial->GetName() << " ] "
<< "\n------------------------------------------------------------\n";
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
{
// search the material by its name
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fAbsorberMaterial = material;
if (fLogicAbsorber != nullptr) {
fLogicAbsorber->SetMaterial(fAbsorberMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapMaterial(const G4String& materialChoice)
{
auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
if (material != nullptr) {
fGapMaterial = material;
if ( fLogicGap != nullptr) {
fLogicGap->SetMaterial(fGapMaterial);
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetAbsorberThickness(G4double value)
{
// change Absorber thickness and recompute the calorimeter parameters
fAbsorberThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetGapThickness(G4double value)
{
// change Gap thickness and recompute the calorimeter parameters
fGapThickness = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetCalorSizeYZ(G4double value)
{
// change the transverse size and recompute the calorimeter parameters
fCalorSizeYZ = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetNbOfLayers(G4int value)
{
fNbOfLayers = value;
if ( G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit ) {
G4RunManager::GetRunManager()->ReinitializeGeometry();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -25,10 +25,6 @@
//
/// \file DetectorMessenger.cc
/// \brief Implementation of the DetectorMessenger class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -45,57 +41,48 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
: G4UImessenger(),
fDetector(Det),
fDetDir(0),
fAbsMaterCmd(0),
fGapMaterCmd(0),
fAbsThickCmd(0),
fGapThickCmd(0),
fSizeYZCmd(0),
fNbLayersCmd(0)
{
: fDetector(Det)
{
G4bool broadcast = false;
fDetDir = new G4UIdirectory("/det/",broadcast);
fDetDir->SetGuidance("Detector control");
fAbsMaterCmd = new G4UIcmdWithAString("/det/setAbsMat",this);
fAbsMaterCmd->SetGuidance("Select Material of the Absorber.");
fAbsMaterCmd->SetParameterName("choice",false);
fAbsMaterCmd->SetParameterName("AbsMat",false);
fAbsMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapMaterCmd = new G4UIcmdWithAString("/det/setGapMat",this);
fGapMaterCmd->SetGuidance("Select Material of the Gap.");
fGapMaterCmd->SetParameterName("choice",false);
fGapMaterCmd->SetParameterName("GapMat",false);
fGapMaterCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fAbsThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setAbsThick",this);
fAbsThickCmd->SetGuidance("Set Thickness of the Absorber");
fAbsThickCmd->SetParameterName("Size",false);
fAbsThickCmd->SetRange("Size>=0.");
fAbsThickCmd->SetParameterName("AbsThick",false);
fAbsThickCmd->SetRange("AbsThick>=0.");
fAbsThickCmd->SetUnitCategory("Length");
fAbsThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fGapThickCmd = new G4UIcmdWithADoubleAndUnit("/det/setGapThick",this);
fGapThickCmd->SetGuidance("Set Thickness of the Gap");
fGapThickCmd->SetParameterName("Size",false);
fGapThickCmd->SetRange("Size>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->SetParameterName("GapThick",false);
fGapThickCmd->SetRange("GapThick>=0.");
fGapThickCmd->SetUnitCategory("Length");
fGapThickCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fSizeYZCmd = new G4UIcmdWithADoubleAndUnit("/det/setSizeYZ",this);
fSizeYZCmd->SetGuidance("Set tranverse size of the calorimeter");
fSizeYZCmd->SetParameterName("Size",false);
fSizeYZCmd->SetRange("Size>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->SetParameterName("SizeYZ",false);
fSizeYZCmd->SetRange("SizeYZ>0.");
fSizeYZCmd->SetUnitCategory("Length");
fSizeYZCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fNbLayersCmd = new G4UIcmdWithAnInteger("/det/setNbOfLayers",this);
fNbLayersCmd->SetGuidance("Set number of layers.");
fNbLayersCmd->SetParameterName("NbLayers",false);
fNbLayersCmd->SetRange("NbLayers>0 && NbLayers<500");
fNbLayersCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -103,34 +90,46 @@ DetectorMessenger::DetectorMessenger( DetectorConstruction* Det)
DetectorMessenger::~DetectorMessenger()
{
delete fNbLayersCmd;
delete fAbsMaterCmd; delete fGapMaterCmd;
delete fAbsThickCmd; delete fGapThickCmd;
delete fSizeYZCmd;
delete fAbsMaterCmd;
delete fGapMaterCmd;
delete fAbsThickCmd;
delete fGapThickCmd;
delete fSizeYZCmd;
delete fDetDir;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == fAbsMaterCmd ) {
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if( command == fAbsMaterCmd ) {
fDetector->SetAbsorberMaterial(newValue);
}
else if( command == fGapMaterCmd ) {
return;
}
if( command == fGapMaterCmd ) {
fDetector->SetGapMaterial(newValue);
return;
}
else if( command == fAbsThickCmd ) {
fDetector
->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
}
else if( command == fGapThickCmd ) {
if( command == fAbsThickCmd ) {
fDetector->SetAbsorberThickness(fAbsThickCmd->GetNewDoubleValue(newValue));
return;
}
if( command == fGapThickCmd ) {
fDetector->SetGapThickness(fGapThickCmd->GetNewDoubleValue(newValue));
return;
}
else if( command == fSizeYZCmd ) {
if( command == fSizeYZCmd ) {
fDetector->SetCalorSizeYZ(fSizeYZCmd->GetNewDoubleValue(newValue));
}
else if( command == fNbLayersCmd ) {
return;
}
if( command == fNbLayersCmd ) {
fDetector->SetNbOfLayers(fNbLayersCmd->GetNewIntValue(newValue));
return;
}
}
@@ -25,10 +25,7 @@
//
/// \file PrimaryGeneratorAction.cc
/// \brief Implementation of the PrimaryGeneratorAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,10 +41,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
: G4VUserPrimaryGeneratorAction(),
fParticleGun(0),
fDetector(DC)
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* dc)
: fDetector(dc)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
@@ -56,8 +51,7 @@ PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition* particle
= particleTable->FindParticle(particleName="e-");
G4ParticleDefinition* particle = particleTable->FindParticle(particleName="e-");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.));
fParticleGun->SetParticleEnergy(500.*MeV);
@@ -78,7 +72,7 @@ PrimaryGeneratorAction::~PrimaryGeneratorAction()
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
//this function is called at the begining of event
//
//
fParticleGun->GeneratePrimaryVertex(anEvent);
}
@@ -25,10 +25,7 @@
//
/// \file SteppingAction.cc
/// \brief Implementation of the SteppingAction class
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,34 +38,32 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction(DetectorConstruction* det,
EventAction* evt)
: G4UserSteppingAction(),
fDetector(det), fEventAction(evt)
{ }
SteppingAction::SteppingAction(DetectorConstruction* det, EventAction* evt)
: fDetector(det), fEventAction(evt)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::~SteppingAction()
{ }
SteppingAction::~SteppingAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction(const G4Step* aStep)
{
// get volume of the current step
G4VPhysicalVolume* volume
= aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
G4VPhysicalVolume* volume =
aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
// collect energy and track length step by step
G4double edep = aStep->GetTotalEnergyDeposit();
G4double stepl = 0.;
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.)
if (aStep->GetTrack()->GetDefinition()->GetPDGCharge() != 0.) {
stepl = aStep->GetStepLength();
if (volume == fDetector->GetAbsorber()) fEventAction->AddAbs(edep,stepl);
if (volume == fDetector->GetGap()) fEventAction->AddGap(edep,stepl);
}
if (volume == fDetector->GetAbsorber()) { fEventAction->AddAbs(edep,stepl); }
if (volume == fDetector->GetGap()) { fEventAction->AddGap(edep,stepl); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -28,7 +28,6 @@
/// \brief Implementation of the ActionInitialization class
#include "ActionInitialization.hh"
#include "HistoManager.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.hh"
#include "EventAction.hh"
@@ -37,45 +36,36 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization(DetectorConstruction* detector)
: G4VUserActionInitialization(),
fDetector(detector)
: fDetector(detector)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{}
ActionInitialization::~ActionInitialization() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
{
// Histo manager
HistoManager* histo = new HistoManager();
// Actions
SetUserAction(new RunAction(histo));
SetUserAction(new RunAction());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const
{
// Histo manager
HistoManager* histo = new HistoManager();
// Actions
//
SetUserAction(new PrimaryGeneratorAction(fDetector));
RunAction* runAction = new RunAction(histo);
SetUserAction(runAction);
EventAction* eventAction = new EventAction(runAction, histo);
SetUserAction(new RunAction());
auto eventAction = new EventAction();
SetUserAction(eventAction);
SteppingAction* steppingAction = new SteppingAction(fDetector, eventAction);
auto steppingAction = new SteppingAction(fDetector, eventAction);
SetUserAction(steppingAction);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -28,65 +28,60 @@
//
//
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "EventAction.hh"
#include "RunAction.hh"
#include "HistoManager.hh"
#include "G4AnalysisManager.hh"
#include "G4Event.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction(RunAction* run, HistoManager* histo)
:G4UserEventAction(),
fRunAct(run),fHistoManager(histo),
fEnergyAbs(0.), fEnergyGap(0.),
fTrackLAbs(0.), fTrackLGap(0.),
fPrintModulo(0)
{
fPrintModulo = 100; }
EventAction::EventAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{ }
EventAction::~EventAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event* evt)
{
{
G4int evtNb = evt->GetEventID();
if (evtNb%fPrintModulo == 0)
if (evtNb%fPrintModulo == 0) {
G4cout << "\n---> Begin of event: " << evtNb << G4endl;
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
// initialisation per event
fEnergyAbs = fEnergyGap = 0.;
fTrackLAbs = fTrackLGap = 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event*)
{
//accumulates statistic
//
fRunAct->FillPerEvent(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
//fill histograms
//
fHistoManager->FillHisto(0, fEnergyAbs);
fHistoManager->FillHisto(1, fEnergyGap);
fHistoManager->FillHisto(2, fTrackLAbs);
fHistoManager->FillHisto(3, fTrackLGap);
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
analysisManager->FillH1(0, fEnergyAbs);
analysisManager->FillH1(1, fEnergyGap);
analysisManager->FillH1(2, fTrackLAbs);
analysisManager->FillH1(3, fTrackLGap);
//fill ntuple
//
fHistoManager->FillNtuple(fEnergyAbs, fEnergyGap, fTrackLAbs, fTrackLGap);
}
// Fill 1st ntuple ( id = 0)
analysisManager->FillNtupleDColumn(0, 0, fEnergyAbs);
analysisManager->FillNtupleDColumn(0, 1, fEnergyGap);
analysisManager->AddNtupleRow(0);
// Fill 2nd ntuple ( id = 1)
analysisManager->FillNtupleDColumn(1, 0, fTrackLAbs);
analysisManager->FillNtupleDColumn(1, 1, fTrackLGap);
analysisManager->AddNtupleRow(1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,136 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file RunAction.cc
/// \brief Implementation of the RunAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "RunAction.hh"
#include "G4AnalysisManager.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction()
{
// Create or get analysis manager
// The choice of analysis technology is done via selection of a namespace
// in HistoManager.hh
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
analysisManager->SetDefaultFileType("root");
analysisManager->SetVerboseLevel(1);
// Only merge in MT mode to avoid warning when running in Sequential mode
#ifdef G4MULTITHREADED
analysisManager->SetNtupleMerging(true);
#endif
// Create directories
analysisManager->SetHistoDirectoryName("histo");
analysisManager->SetNtupleDirectoryName("ntuple");
// Create histograms.
// Histogram ids are generated automatically starting from 0.
// The start value can be changed by:
// analysisManager->SetFirstHistoId(1);
// id = 0
analysisManager->CreateH1("EAbs","Edep in absorber (MeV)", 100, 0., 800*MeV);
// id = 1
analysisManager->CreateH1("EGap","Edep in gap (MeV)", 100, 0., 100*MeV);
// id = 2
analysisManager->CreateH1("LAbs","trackL in absorber (mm)", 100, 0., 1*m);
// id = 3
analysisManager->CreateH1("LGap","trackL in gap (mm)", 100, 0., 50*cm);
// Create ntuples.
// Ntuples ids are generated automatically starting from 0.
// The start value can be changed by:
// analysisManager->SetFirstMtupleId(1);
// Create 1st ntuple (id = 0)
analysisManager->CreateNtuple("Ntuple1", "Edep");
analysisManager->CreateNtupleDColumn("Eabs"); // column Id = 0
analysisManager->CreateNtupleDColumn("Egap"); // column Id = 1
analysisManager->FinishNtuple();
// Create 2nd ntuple (id = 1)
//
analysisManager->CreateNtuple("Ntuple2", "TrackL");
analysisManager->CreateNtupleDColumn("Labs"); // column Id = 0
analysisManager->CreateNtupleDColumn("Lgap"); // column Id = 1
analysisManager->FinishNtuple();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run* run)
{
G4cout << "### Run " << run->GetRunID() << " start." << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run* /*run*/)
{
PrintStatistic();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::PrintStatistic()
{
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
G4cout << "\n ----> print histograms statistic \n" << G4endl;
for ( G4int i=0; i<analysisManager->GetNofH1s(); ++i ) {
G4String name = analysisManager->GetH1Name(i);
auto h1 = analysisManager->GetH1(i);
G4String unitCategory;
if (name[0U] == 'E' ) { unitCategory = "Energy"; }
if (name[0U] == 'L' ) { unitCategory = "Length"; }
// we use an explicit unsigned int type for operator [] argument
// to avoid problems with windows compiler
G4cout << name
<< ": mean = " << G4BestUnit(h1->mean(), unitCategory)
<< " rms = " << G4BestUnit(h1->rms(), unitCategory )
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,76 @@
# Macro file for the initialization phase of "exampleN03.cc"
# when running in interactive mode
#
# Sets some default verbose
#
/control/verbose 2
/run/verbose 2
#
# Use this open statement to create an OpenGL view:
/vis/open OGL 600x600-0+0
#
# Use this open statement to create a .prim file suitable for
# viewing in DAWN:
#/vis/open DAWNFILE
#
# Use this open statement to create a .heprep file suitable for
# viewing in HepRApp:
#/vis/open HepRepFile
#
# Use this open statement to create a .wrl file suitable for
# viewing in a VRML viewer:
#/vis/open VRML2FILE
#
# Disable auto refresh and quieten vis messages whilst scene and
# trajectories are established:
/vis/viewer/set/autoRefresh false
/vis/verbose errors
#
# Draw geometry:
/vis/drawVolume
#
# Specify view angle:
#/vis/viewer/set/viewpointThetaPhi 90. 0.
#
# Specify zoom value:
#/vis/viewer/zoom 2.
#
# Specify style (surface or wireframe):
#/vis/viewer/set/style wireframe
#
# Draw coordinate axes:
#/vis/scene/add/axes 0 0 0 1 m
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/vis/scene/add/trajectories smooth
/vis/modeling/trajectories/create/drawByCharge
/vis/modeling/trajectories/drawByCharge-0/default/setDrawStepPts true
/vis/modeling/trajectories/drawByCharge-0/default/setStepPtsSize 2
# (if too many tracks cause core dump => /tracking/storeTrajectory 0)
#
# Draw hits at end of event:
#/vis/scene/add/hits
#
# To draw only gammas:
#/vis/filtering/trajectories/create/particleFilter
#/vis/filtering/trajectories/particleFilter-0/add gamma
#
# To invert the above, drawing all particles except gammas,
# keep the above two lines but also add:
#/vis/filtering/trajectories/particleFilter-0/invert true
#
# Many other options are available with /vis/modeling and /vis/filtering.
# For example, to select colour by particle ID:
#/vis/modeling/trajectories/create/drawByParticleID
#/vis/modeling/trajectories/drawByParticleID-0/set e- blue
#
# To superimpose all of the events from a given run:
/vis/scene/endOfEventAction accumulate
#
# Re-establish auto refreshing and verbosity:
/vis/viewer/set/autoRefresh true
/vis/verbose warnings
#
# For file-based drivers, use this to create an empty detector view:
#/vis/viewer/flush
+15 -15
View File
@@ -5,7 +5,7 @@
/*! \page ExampleB1Con Example B1Con
Example of Convergence Tester
Example of Convergence Tester
Koi, Tatsumi \n
SLAC National Accelerator Laboratory / PPA \n
@@ -13,25 +13,25 @@ Example of Convergence Tester
This example shows how to use convergece tester in Geant4.
The aim of Convergence Tester
- After a Monte Carlo simulation, we get an answer. However how to estimate quality of the answer.
The answer is usually given in a form of average value.
But sometimes the value is strongly affected by single or a few events in the full calculation.
- After a Monte Carlo simulation, we get an answer. However how to estimate quality of the answer.
The answer is usually given in a form of average value.
But sometimes the value is strongly affected by single or a few events in the full calculation.
In such case, we must concern about quality of the value.
What we must remember is
- Large number of history does not valid result of simulation.
- Small Relative Error does not valid result of simulation
Convergence tester provides statistical information
Convergence tester provides statistical information
to assist establishing valid confidence intervals for Monte Carlo results for users.
Geometry and Physics are same to exampleB1. Please see \ref ExampleB1.
Geometry and Physics are same to exampleB1. Please see \ref ExampleB1.
Note that in this example, the classes with the code added for
the purpose of demonstration of the Convergence Tester start with a prefix
B1Con instead of B1 and also the executable and the test macro names are changed
in exampleB1Con and exampleB1Con.in.
in exampleB1Con and exampleB1Con.in.
Known problem:
Computing time of T cannot be gotten properly in current MT migration of example of B1Con. Therefore
Computing time of T cannot be gotten properly in current MT migration of example of B1Con. Therefore
FOM (=1/(R^2T) where R is relative error and T is computing time) relates numbers are unusable.
\verbatim
@@ -39,7 +39,7 @@ FOM (=1/(R^2T) where R is relative error and T is computing time) relates number
Output example
// Part I.A
// Basic statistics values
// Basic statistics values
G4ConvergenceTester Output Result of DOSE_TALLY
EFFICIENCY = 0.601
@@ -52,7 +52,7 @@ G4ConvergenceTester Output Result of DOSE_TALLY
FOM = 1238.68
// Part I.B
// If the largeset scored events happen at next to the last event,
// If the largeset scored events happen at next to the last event,
// then how much the event effects the statistics values of the calculation
THE LARGEST SCORE = 1.07301e-11 and it happend at 487th event
@@ -67,16 +67,16 @@ THE LARGEST SCORE = 1.07301e-11 and it happend at 487th event
MEAN distribution is RANDOM
r follows 1/std::sqrt(N)
r is monotonically decrease
r is monotonically decrease
r is less than 0.1. r = 0.0304622
VOV follows 1/std::sqrt(N)
VOV is monotonically decrease
VOV is monotonically decrease
FOM distribution is not RANDOM
SLOPE is not large enough
This result passes 6 / 8 Convergence Test.
// Part II
// Profile of statistics values in the history
// Profile of statistics values in the history
G4ConvergenceTester Output History of DOSE_TALLY
i/16 till_ith mean var sd r vov fom shift e r2eff r2int
@@ -108,6 +108,6 @@ Judith F. Briesmeister, Editor \n
LA-12625-M, Issued: March 1997, UC 705 and UC 700 \n
CHAPTER 2. GEOMETRY, DATA, PHYSICS, AND MATHEMATICS \n
VI. ESTIMATION OF THE MONTE CARLO PRECISION \n
*/
*/

Some files were not shown because too many files have changed in this diff Show More