Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
+10 -8
View File
@@ -1,6 +1,8 @@
#---Adding all advanced examples subdirectories explicitly
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
#---Adding all advanced examples subdirectories explicitly
cmake_minimum_required(VERSION 3.8...3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
#----------------------------------------------------------------------------
# some examples require Geant4 build with optional packages
@@ -15,15 +17,15 @@ add_subdirectory(brachytherapy)
if(Geant4_gdml_FOUND)
add_subdirectory(ChargeExchangeMC)
else()
message(STATUS "G4 Examples: GDML not installed --> ChargeExchangeMC example disabled")
else()
message(STATUS "G4 Examples: GDML not installed --> ChargeExchangeMC example disabled")
endif()
if(NOT Geant4_builtin_clhep_FOUND)
add_subdirectory(nanobeam)
else()
message(STATUS "G4 Examples: CLHEP external package not found --> nanobeam disabled")
endif()
endif()
add_subdirectory(composite_calorimeter)
@@ -31,7 +33,7 @@ if(ROOT_FOUND)
add_subdirectory(doiPET)
else()
message(STATUS "G4 Examples: ROOT package not found --> doiPET disabled")
endif()
endif()
add_subdirectory(eRosita)
add_subdirectory(gammaknife)
@@ -47,4 +49,4 @@ add_subdirectory(purging_magnet)
add_subdirectory(underground_physics)
add_subdirectory(xray_fluorescence)
add_subdirectory(STCyclotron)
add_subdirectory(HGCal_testbeam)
@@ -1,4 +1,7 @@
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
cmake_minimum_required(VERSION 3.8...3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
include(CMakeDependentOption)
set(name ChargeExchangeMC)
@@ -15,7 +18,7 @@ endif()
include(${Geant4_USE_FILE})
# Setup of ROOT ANALYSIS : optional.
# Setup of ROOT ANALYSIS : optional.
find_package(ROOT QUIET)
cmake_dependent_option(CEXMC_USE_HISTOGRAMING "Build example with analysis objects" ON "ROOT_FOUND" OFF)
@@ -28,7 +31,7 @@ option(CEXMC_USE_PERSISTENCY
(requires Boost Serialization library)" OFF)
if(CEXMC_USE_PERSISTENCY)
find_package(Boost REQUIRED serialization)
find_package(Boost REQUIRED serialization)
add_definitions(-DCEXMC_USE_PERSISTENCY)
list(APPEND EXTRA_LIBRARIES Boost::serialization)
message(STATUS "Library Boost::serialization was added to the linkage list")
@@ -79,14 +82,14 @@ option(CEXMC_DEBUG_TP
if(CEXMC_DEBUG_TP)
add_definitions(-DCEXMC_DEBUG_TP)
endif()
if(CEXMC_USE_HISTOGRAMING)
EXECUTE_PROCESS(COMMAND root-config --cflags OUTPUT_VARIABLE ROOT_CXX_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ROOT_CXX_FLAGS}")
EXECUTE_PROCESS(COMMAND root-config --libs OUTPUT_VARIABLE ROOT_LD_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_EXE_LINKER_FLAGS ${ROOT_LD_FLAGS})
endif(CEXMC_USE_HISTOGRAMING)
endif(CEXMC_USE_HISTOGRAMING)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${Geant4_INCLUDE_DIR})
file(GLOB sources ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc)
File diff suppressed because it is too large Load Diff
+13 -10
View File
@@ -7,8 +7,11 @@ cirrone@lns.infn.it
History file of the ChargeExchangeMC application
====================================================
02.11.2020 - B.Morgan, Tag ChargeExchangeMC-V10-06-01
Support same CMake version range as core Geant4
08.04.2020 - S. Guatelli, Tag ChargeExchangeMC-V10-06-00
Error removed from the main. CMakeList.txt updated.
Error removed from the main. CMakeList.txt updated.
Dependence to Qt Libraries when using ROOT demoved as obsolete.
02.09.2019 - S. Guatelli, Tag ChargeExchangeMC-V10-05-02
@@ -31,18 +34,18 @@ cirrone@lns.infn.it
Replace ROOT_INCLUDE_DIR with ROOT_INCLUDE_DIRS
31.10.2017 - L. Pandola, Tag ChargeExchangeMC-V10-03-06
Clean up preinit.mac, to avoid a cerr when
Clean up preinit.mac, to avoid a cerr when
ROOT is not available
26.10.2017 - L. Pandola, Tag ChargeExchangeMC-V10-03-05
Edit CMakeLists.txt such to copy mac/gmdl in the
Edit CMakeLists.txt such to copy mac/gmdl in the
build directory
25.10.2017 - L. Pandola, Tag ChargeExchangeMC-V10-03-04
Fix residual shadowing on gcc 4.9
23.10.2017 - A. Radkov, Tag ChargeExchangeMC-V10-03-03
Fix shadowed variabiles (and removed flag from
Fix shadowed variabiles (and removed flag from
CMakeLists.txt)
12.10.2017 - L. Pandola, Tag ChargeExchangeMC-V10-03-02
@@ -60,16 +63,16 @@ cirrone@lns.infn.it
Remove icons.mac. Automatically include since interfaces-V10-02-07
09.12.2014 - A. Radkov, Tag ChargeExchangeMC-V10-01-00
CERN ROOT histograming binding. Bug fix for online histogram
redrawing and easy online histogram showing from a dedicated
CERN ROOT histograming binding. Bug fix for online histogram
redrawing and easy online histogram showing from a dedicated
menu bar (in graphical mode).
06.10.2014 - L.Pandola, Tag: ChargeExchangeMC-V10-00-01
Edited CMakeLists.txt file to allow for the integration
in the CDash testing
in the CDash testing
12.12.2013 - A. Radkov & L. Pandola, Tag: ChargeExchangeMC-V10-00-00
Fix a few compiler warnings (shadowed variables, system of
12.12.2013 - A. Radkov & L. Pandola, Tag: ChargeExchangeMC-V10-00-00
Fix a few compiler warnings (shadowed variables, system of
units). FTFP_BERT replaces deprecated QGSP_BERT
22.11.2012 - L.Garnier Tag: ChargeExchangeMC-V09-05-05
@@ -86,7 +89,7 @@ cirrone@lns.infn.it
17.10.2012, L.Pandola & A.Radkov, Tag: ChargeExchangeMC-V09-05-01
- Fix to compile the code against Geant4 9.6
- Edit GNUmakefile such that the default version does not
- Edit GNUmakefile such that the default version does not
depend on boost
11.10.2012, G.Cosmo, Tag: ChargeExchangeMC-V09-05-00
@@ -0,0 +1,88 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.8...3.18 FATAL_ERROR)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(HGCal_testbeam)
#----------------------------------------------------------------------------
# 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()
#----------------------------------------------------------------------------
# Find ROOT (required package only for reading input particles from file)
#
find_package(ROOT QUIET NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
if (ROOT_FOUND)
message(STATUS "Found ROOT: ${ROOT_DIR}. Particles read from file can be used as generator.")
add_definitions(-DWITHROOT)
include_directories(${ROOT_INCLUDE_DIRS})
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
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(HGCal_testbeam hgcal_testbeam.cc ${sources} ${headers})
target_link_libraries(HGCal_testbeam ${Geant4_LIBRARIES})
if (ROOT_FOUND)
target_link_libraries(HGCal_testbeam ${ROOT_LIBRARIES})
set_target_properties(HGCal_testbeam PROPERTIES CXX_STANDARD 17)
endif()
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build HGCal)testbeam. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(HGCAL_SCRIPTS
init_vis.mac
run.mac
vis.mac
)
foreach(_script ${HGCAL_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
if (ROOT_FOUND)
configure_file(
${PROJECT_SOURCE_DIR}/readFromFile.mac
${PROJECT_BINARY_DIR}/readFromFile.mac
COPYONLY
)
endif()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS HGCal_testbeam DESTINATION bin)
@@ -0,0 +1,16 @@
# --------------------------------
# GNUmakefile for examples module.
# --------------------------------
name := HGCal_testbeam
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../..
endif
.PHONY: all
all: lib bin
include $(G4INSTALL)/config/binmake.gmk
+18
View File
@@ -0,0 +1,18 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Example HGCal_testbeam History file
---------------------------
This file should be used by the G4 example coordinator to briefly
summarize all major modifications introduced in the code and keep
track of all tags.
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
02-Nov-20 A. Zaborowska (exhgcaltb-V10-06-00)
- Create HGCal_testbeam example based on Thorben Quast application
+227
View File
@@ -0,0 +1,227 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Example HGCal_testbeam
----------------------
This example is based on the Geant4 standalone application developed
by Thorben Quast for the CMS HGCal studies:
https://github.com/ThorbenQuast/HGCal_TB_Geant4.
The goal of this example is to demonstrate a test beam setup used
in HEP experiments, and as a base for the validation studies and
comparison with experiment data.
It presents a test beam setup used in the HGCal studies in October
2018. It can be easily extended to other configurations.
Details on the High Granularity Calorimeter (HGCal) can be found
i.a. in the Technical Design Report:
https://cds.cern.ch/record/2293646/files/CMS-TDR-019.pdf
1. Detector description
-----------------------
Detector construction in this example assumes that the setup is
constructed with different elements placed one behind another along
z axis (beam axis).
There are 3 configurations user can choose from, and could be set
with UI command:
/HGCalTestbeam/setup/configuration <ID>
where <ID> by default is equal to 0, which means the HGCal testbeam
setup used in October 2018.
<ID> 1 builds the same calorimeter setup, but places in front of it
several beamline elements.
<ID> 2 builds a very simplistic test configuration.
Whenever a silicon wafer or SiPM is placed in the detector, a sensitive
volume is attached to it, and will be used to collect signal.
Silicon wafer is divided into cells (pixels), and each individual pixel
can collect signal.
In order to change the maximum step size allowed in silicon pixels:
/HGCalTestbeam/setup/stepSilicon <STEP>
where <STEP> is value of the max step size in micrometres. By default
<STEP> is equal to 30 um.
2. Signal
---------
Energy deposited within silicon pixels and SiPMs is registered in the
sensitive detectors. Each deposit is added individually to the vector
of hits, in order to allow the digitisation.
Digitisation is performed at the end of the event. It accumulates the
energy deposits within pixels, taking into account the time cut on the
arrival of signal (global time of energy deposit). By default no time
cut is applied which means all the deposits are counted. It can be set
using UI command:
/HGCalTestbeam/hits/timeCut <TIME>
where <TIME> is the maximum global time of the energy deposit that
would be counted into the signal within the pixel.
Another hit parameter is TOA (time of arrival) which is calculated
as time of the energy deposit which added to the digitised pixel energy
exceeds the threshold. By default the threshold is equal to 0, which
means that any hit will exceed the value, so TOA of pixel equals to
the time of the first energy deposit. It can be set using UI command:
/HGCalTestbeam/hits/toaThreshold <ENERGY_THRESHOLD>
where <ENERGY_THRESHOLD> indicates the threshold the sum of energy
needs to exceed to be counted as time of arrival.
Additionally, for silicon pixels, time of the last energy deposit
(within the time window) is recorded.
3. Output
---------
Output with event signal is stored in ntuple and saved to a ROOT file.
Its name can be set with UI command:
/HGCalTestbeam/output/file <NAME>
Created TTree "hits" contains following branches:
+---------------------------------+-----------------+------+-------------------------------------------+
| Branch | Type | Unit | Description |
+---------------------------------+-----------------+------+-------------------------------------------+
| event | int | - | |
| pdgID | vector<int> | - | PDG code of primary particles |
| beamEnergy | vector<double> | GeV | initial energy of primaries |
| beamX_cm | vector<double> | cm | initial X position of primaries |
| beamY_cm | vector<double> | cm | initial Y position of primaries |
| beamZ_cm | vector<double> | cm | initial Z position of primaries |
| siliconHits_ID | vector<int> | - | ID of hits in Si (=1e3*waferID+cellID) |
| siliconHits_x_cm | vector<double> | cm | X position of Si pixel |
| siliconHits_y_cm | vector<double> | cm | Y position of Si pixel |
| siliconHits_z_cm | vector<double> | cm | Z position of Si pixel |
| siliconHits_Edep_keV | vector<double> | keV | energy deposited within Si pixel |
| siliconHits_EdepNonIonizing_keV | vector<double> | keV | non-ionizing energy deposit (Si) |
| siliconHits_TOA_ns | vector<double> | ns | time of arrival for Si pixel |
| siliconHits_TOA_last_ns | vector<double> | ns | time of last arrival for Si pixel |
| siliconHits_type | vector<int> | - | hit type for Si pixel (=0) |
| SiPMHits_ID | vector<int> | - | ID of hits in SiPM (=1e3*sensorID+cellID) |
| SiPMHits_x_cm | vector<double> | cm | X position of SiPM |
| SiPMHits_y_cm | vector<double> | cm | Y position of SiPM |
| SiPMHits_z_cm | vector<double> | cm | Z position of SiPM |
| SiPMHits_Edep_keV | vector<double> | keV | energy deposited within SiPM |
| SiPMHits_EdepNonIonizing_keV | vector<double> | keV | non-ionizing energy deposit (SiPM) |
| SiPMHits_TOA_ns | vector<double> | ns | time of arrival for SiPM |
| SiPMHits_type | vector<int> | - | hit type for SiPM (= 1) |
| signalSum_HGCAL_GeV | double | GeV | sum of energy deposited in Si pixels |
| COGZ_HGCAL_cm | double | cm | energy-weighted shower depth in z |
| NHits_HGCAL | int | - | number of Si pixel hits |
| signalSum_AHCAL_GeV | double | GeV | sum of energy deposited in SiPMs |
| COGZ_AHCAL_cm | double | cm | energy-weighted shower depth in z |
| NHits_AHCAL | int | - | number of SiPM hits |
+---------------------------------+-----------------+------+-------------------------------------------+
4. Primary particle generator
-----------------------------
Particle gun is used as a default primary particle generator.
It can be controlled with standard UI commands (/gun/) and with
additional ones introduced by the messenger:
/HGCalTestbeam/generator/momentumSpread <VALUE>
to change constant particle energy to Gaussian distribution with
sigma expressed in units of the initial energy (e.g. <VALUE>=0.05
means sigma of 0.05 * E). By default it equals to 0 and constant
energy value is used.
/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>
to define type of beam position spread. By default none is used.
/HGCalTestbeam/generator/beamSpreadX <SIZE>
to define size of beam spread along x axis. It is sigma of a
Gaussian distribution, or half-width of a flat distribution.
/HGCalTestbeam/generator/beamSpreadY <SIZE>
to define size of beam spread along y axis. It is sigma of a
Gaussian distribution, or half-width of a flat distribution.
/HGCalTestbeam/generator/fBeamZ0 <POSITION>
to define beam position along z axis. By default edge of the
world volume is used.
Additionally, if installation was done with ROOT package (CMake
was able to locate it), an option of input read from the ROOT file
is enabled. It can be activated with
/HGCalTestbeam/generator/fReadInputFile true
/HGCalTestbeam/generator/fPathInputFile <FILE>
sets the path to the input file.
/HGCalTestbeam/generator/startFromEvent <N>
allows to start simulation from Nth event.
Please note that in current implementation input from file needs to be
executed in a non-multithreaded mode (or with 1 thread).
Input file needs to have following structure:
- TDirectory "VirtualDetector"
- TNtuple "HGCAL" with branches:
+---------+-------+------+-------------------------------+
| Branch | Type | Unit | Description |
+---------+-------+------+-------------------------------+
| EventID | float | - | ID of event |
| PDGid | float | - | Particle type (PDG code) |
| x | float | mm | Initial X position |
| y | float | mm | Initial Y position |
| Px | float | MeV | Initial momentum along X axis |
| Py | float | MeV | Initial momentum along Y axis |
| Pz | float | MeV | Initial momentum along Z axis |
+---------+-------+------+-------------------------------+
Several particles may belong to the same event, in which case all
of them are read from the input file.
Z position is set to Z position of the entrance of the HGCal detector.
5. How to run the example
-------------------------
Example can be run in interactive mode, with visualisation:
./HGCal_testbeam
It will execute init_vis.mac and vis.mac.
To run in a batch mode, specify the path to the macro:
./HGCal_testbeam run.mac
which will run 10 single-electron events, with beam energy of 30 GeV.
The beam position is smeared with Gaussian with x/y sigma of 1.5 cm.
The momentum is smeared with Gaussian with sigma of 5% (2.5 GeV).
Z beam position is set to -1 m.
Maximum step size in Si pixel is 20 um.
The name of the created file is output_eM_smeared_30GeV_10events.root.
6. Additional settings
----------------------
6.1. Particle input from ROOT file
----------------------------------
If ROOT is found by CMake, it allows to use ROOT file as the input to
the primary generator. See more in the description of "4. Primary
particle generator".
./HGCal_testbeam readFromFile.mac
Macro readFromFile.mac can be used but name of the input file should
be specified (not provided with the example). This mode is meant to
be used in the validation with experimental data with geant-val.
@@ -0,0 +1,131 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "FTFP_BERT.hh"
#include "FTFPCMS_BERT_EMM.hh"
#include "G4PhysListFactory.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv)
{
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = 0;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
// Choose the Random engine
G4Random::setTheEngine(new CLHEP::RanecuEngine);
// Initialization of Run manager
auto* runManager =
G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
// Set mandatory initialization classes
//
// Detector construction
runManager->SetUserInitialization(new DetectorConstruction());
// Physics List name defined via environment variable
// or the default FTFP_BERT is used
G4VModularPhysicsList* physicsList = nullptr;
G4String physName = "";
char* PLenv = std::getenv("PHYSLIST");
if (PLenv)
physName = G4String(PLenv);
if ("FTFP_BERT_EMM" == physName || "FTFPCMS_BERT_EMM" == physName)
physicsList = new FTFPCMS_BERT_EMM;
else if ("" == physName)
{
physName = "FTFP_BERT";
physicsList = new FTFP_BERT;
}
if (!physicsList)
{
G4PhysListFactory factory;
physicsList = factory.GetReferencePhysList(physName);
}
if (!physicsList)
{
G4ExceptionDescription msg;
msg << "Unknown physics list defined in environment variable PHYSLIST: " << PLenv << "\n";
msg<< "Consider extension of main to take it into account.\n";
G4Exception("HGCal_testbeam::main()", "UnknownPhysicsList", FatalException, msg);
}
physicsList->SetVerboseLevel(1);
runManager->SetUserInitialization(physicsList);
// User action initialization
runManager->SetUserInitialization(new ActionInitialization());
// Get the pointer to the User Interface manager
G4UImanager* UImanager = G4UImanager::GetUIpointer();
// Process macro or start UI session
//
if ( ! ui ) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
else {
// Initialize visualization
G4VisManager *visManager = new G4VisExecutive;
// G4VisExecutive can take a verbosity argument - see /vis/verbose guidance.
// G4VisManager* visManager = new G4VisExecutive("Quiet");
visManager->Initialize();
// interactive mode
//UImanager->ApplyCommand("/control/execute init_vis.mac");
UImanager->ApplyCommand("/control/execute init_vis.mac");
ui->SessionStart();
delete ui;
delete visManager;
}
// Job termination
// Free the store: user actions, physics_list and detector_description are
// owned and deleted by the run manager, so they should not be deleted
// in the main() program !
delete runManager;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -0,0 +1,48 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef ACTIONINITIALIZATION_HH
#define ACTIONINITIALIZATION_HH
#include "G4VUserActionInitialization.hh"
/**
* @brief Initialization of user actions.
*
* Initialises the primary generator, and user actions (event, run) to store
* output.
*
*/
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
virtual ~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
};
#endif /* ACTIONINITIALIZATION_HH */
@@ -0,0 +1,51 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef CMSEMSTANDARDPHYSICSHCAL_HH
#define CMSEMSTANDARDPHYSICSHCAL_HH
#include "G4VPhysicsConstructor.hh"
/**
* @brief EM physics
*
* Used in FTFPCMS_BERT_EMM physics list. Copy from test46.
*
*/
class CMSEmStandardPhysicsHcal : public G4VPhysicsConstructor {
public:
explicit CMSEmStandardPhysicsHcal(G4int ver);
virtual ~CMSEmStandardPhysicsHcal();
virtual void ConstructParticle();
virtual void ConstructProcess();
private:
G4int fVerbose = 0;
};
#endif /* CMSEMSTANDARDPHYSICSHCAL_HH */
@@ -0,0 +1,88 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION_HH
#define DETECTORCONSTRUCTION_HH
#include "G4VUserDetectorConstruction.hh"
#include "G4Types.hh"
#include <utility>
#include <vector>
class G4VPhysicalVolume;
class G4LogicalVolume;
class G4GenericMessenger;
class HGCalTBMaterials;
/**
* @brief Detector construction.
*
* Creates a detector with a configuration set by UI commands. By default a test
* module is build (few elements including a silicon sensor).
* Sensitive detectors are attached to silicon sensors.
*
*/
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
virtual ~DetectorConstruction();
virtual G4VPhysicalVolume *Construct();
virtual void ConstructSDandField();
private:
/// Define UI commands: configuration of detector (geometry setup), and
/// maximal step size in silicon
void DefineCommands();
/// Set detector setup configuration based on ID
/// @param[in] aValue ID of detector configuration
void SelectConfiguration(G4int aValue);
/// Set maximal size of step within silicon sensor
/// Can be changed by the UI command /HGCalTestbeam/setup/stepSilicon
/// @param[in] aValue Max step size
void SetStepSizeSilicon(G4double aValue);
/// Helper method placing the logical volumes from map of elements
void ConstructHGCal();
/// Pointer to the logical volume of the world
G4LogicalVolume *fLogicWorld = nullptr;
/// Pointer to the messenger for UI commands
G4GenericMessenger *fMessenger = nullptr;
/// Pointer to the class that defines materials and logical volumes of all
/// possible elements, to be placed according to the configuration setup
HGCalTBMaterials *fMaterials = nullptr;
/// Map of elements to be placed along z axis: name and distance to the
/// previous element is specified
std::vector<std::pair<G4String, G4double>> fElementsMap;
/// Viewpoint for the visualisation
G4double fVisViewpoint = 0;
/// Configuration of the detector setup
/// Can be changed by the UI command /HGCalTestbeam/setup/configuration
G4int fConfiguration = 0;
};
#endif /* DETECTORCONSTRUCTION_HH */
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION0_HH
#define DETECTORCONSTRUCTION0_HH
#include "G4String.hh"
#include "G4Types.hh"
#include <vector>
#include <utility>
/// Add module of silicon sensor with absorbers, readout, and support, for the
/// electromagnetic calorimeter (EE).
/// @param[in] aEEid ID of module in the setup (not all modules are identical)
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[in] aAirBefore How much air should be added before the current module
/// (before the first iron)
/// @param[in] aAirMid How much air should be added in the middle (before the
/// first PCB)
void add_EE(G4int aEEid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid);
/// Add module of scintillator sensor with absorbers, readout, and support, for
/// the hadronic calorimeter (FH).
/// @param[in] aFHid ID of module in the setup (not all modules are identical)
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[in] aAirBefore How much air should be added before the current module
/// (before the first iron)
/// @param[in] aAirMid How much air should be added in the middle (before the
/// first PCB)
void add_FH(G4int aFHid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid);
/// Define detector setup for test beam run in October 2018
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction0(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION0_HH */
@@ -0,0 +1,45 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION1_HH
#define DETECTORCONSTRUCTION1_HH
#include "G4String.hh"
#include "G4Types.hh"
#include <vector>
#include <utility>
/// Define detector setup for test beam run in October 2018
/// Include the beamline elements in the simulation.
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction1(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION1_HH */
@@ -0,0 +1,42 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION2_HH
#define DETECTORCONSTRUCTION2_HH
#include "G4Types.hh"
#include "G4String.hh"
#include <utility>
#include <vector>
/// Define test setup
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction2(std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION2_HH */
@@ -0,0 +1,129 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef EVENTACTION_HH
#define EVENTACTION_HH
#include "G4UserEventAction.hh"
#include "G4Types.hh"
#include <vector>
class G4GenericMessenger;
/**
* @brief Event action class
*
* Fills ntuples with information about hits in sensitive detectors.
*
*/
class EventAction : public G4UserEventAction {
public:
EventAction();
virtual ~EventAction();
virtual void BeginOfEventAction(const G4Event *event);
virtual void EndOfEventAction(const G4Event *event);
/// Vector of primary particles in an event: PDG type
std::vector<G4int> fPrimariesPDG;
/// Vector of primary particles in an event: particle energy (in GeV)
std::vector<G4double> fPrimariesEnergy;
/// Vector of primary particles in an event: vertex position x (in cm)
std::vector<G4double> fPrimariesX;
/// Vector of primary particles in an event: vertex position y (in cm)
std::vector<G4double> fPrimariesY;
/// Vector of primary particles in an event: vertex position z (in cm)
std::vector<G4double> fPrimariesZ;
/// Vector of hits in silicon sensors: hit ID
std::vector<G4int> fSiHitsID;
/// Vector of hits in silicon sensors: hit position x (in cm)
std::vector<G4double> fSiHitsX;
/// Vector of hits in silicon sensors: hit position y (in cm)
std::vector<G4double> fSiHitsY;
/// Vector of hits in silicon sensors: hit position z (in cm)
std::vector<G4double> fSiHitsZ;
/// Vector of hits in silicon sensors: hit energy (in keV)
std::vector<G4double> fSiHitsEdep;
/// Vector of hits in silicon sensors: hit non-ionizing energy (in keV)
std::vector<G4double> fSiHitsEdepNonIonising;
/// Vector of hits in silicon sensors: hit time of arrival (in ns)
/// calculated as global time of energy deposit which added to hit energy
/// exceeds the toa threshold (by default threshold is 0, so it is the first
/// deposit)
std::vector<G4double> fSiHitsTOA;
/// Vector of hits in silicon sensors: hit time of last arrival (in ns)
/// calculated as global time of energy deposit which is the last deposit
/// that fits within the digitisation time window (by default window is
/// undefined, so it is the last deposit)
std::vector<G4double> fSiHitsTOAlast;
/// Vector of hits in silicon sensors: hit type
/// Simulation defines only hits of type 0 (hexagonal cells, no calibration or
/// edge cell is constructed)
std::vector<G4int> fSiHitsType;
/// Vector of hits in SiPM: hit ID
std::vector<G4int> fSiPMhitsID;
/// Vector of hits in SiPM: hit position x (in cm)
std::vector<G4double> fSiPMhitsX;
/// Vector of hits in SiPM: hit position y (in cm)
std::vector<G4double> fSiPMhitsY;
/// Vector of hits in SiPM: hit position z (in cm)
std::vector<G4double> fSiPMhitsZ;
/// Vector of hits in SiPM: hit energy (in keV)
std::vector<G4double> fSiPMhitsEdep;
/// Vector of hits in SiPM: hit non-ionizing energy (in keV)
std::vector<G4double> fSiPMhitsEdepNonIonising;
/// Vector of hits in SiPM: hit time of last arrival (in ns)
/// calculated as global time of energy deposit which is the last deposit
/// that fits within the digitisation time window (by default window is
/// undefined, so it is the last deposit)
std::vector<G4double> fSiPMhitsTOA;
/// Vector of hits in silicon sensors: hit type
/// Simulation defines only hits of type 1
std::vector<G4int> fSiPMhitsType;
private:
/// Define UI commands: digitisation of hits with the time cut on deposits
/// (time window), and the energy threshold for the first deposit counted as
/// the time of arrival
void DefineCommands();
/// Pointer to the messenger for UI commands
G4GenericMessenger *fMessenger = nullptr;
/// Time window for hit digitisation (in ns)
/// By default undefined window indicates the last created deposit will set up
/// the time
/// Can be changed by the UI command /HGCalTestbeam/hits/timeCut
G4double fHitTimeCut = -1;
/// Time of arrival threshold (in keV)
/// Default value of 0 indicates the first created deposit will set up the
/// time, independent on the amount of deposited energy
/// Can be changed by the UI command /HGCalTestbeam/hits/toaThreshold
G4double fToaThreshold = 0;
};
#endif /* EVENTACTION_HH */
@@ -0,0 +1,47 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef FTFPCMS_BERT_EMM_HH
#define FTFPCMS_BERT_EMM_HH
#include "G4VModularPhysicsList.hh"
/**
* @brief FTFPCMS_BERT_EMM physics list
*
* FTFPCMS_BERT_EMM physics list. Copy from test46.
*
*/
class FTFPCMS_BERT_EMM : public G4VModularPhysicsList {
public:
explicit FTFPCMS_BERT_EMM(G4int ver = 1);
virtual ~FTFPCMS_BERT_EMM();
virtual void SetCuts();
};
#endif /* FTFPCMS_BERT_EMM_HH */
@@ -0,0 +1,210 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef HGCALTBMATERIALS_HH
#define HGCALTBMATERIALS_HH
#include "G4Types.hh"
#include "G4String.hh"
#include "CLHEP/Units/SystemOfUnits.h"
#include <map>
class G4Box;
class G4LogicalVolume;
class G4Material;
class G4SubtractionSolid;
/// Construction of a hexagon solid
/// @param[in] name Name of the solid
/// @param[in] cellThickness Thickness of the hexagon
/// @param[in] cellSideLength Length of a side of the haxagon
/// @return Solid
G4SubtractionSolid *HexagonSolid(G4String name, G4double cellThickness,
G4double cellSideLength);
/// Construction of a logical volume
/// @param[in] name Name of the solid
/// @param[in] cellThickness Thickness of the hexagon
/// @param[in] cellSideLength Length of a side of the haxagon
/// @param[in] material Material
/// @return Logical volume
G4LogicalVolume *HexagonLogical(G4String name, G4double cellThickness,
G4double cellSideLength, G4Material *material);
/**
* @brief HGCal material and elements definitions
*
* Defines materials used for HGCal test-beam.
* Creates logical volumes for every element that may be constructed and placed
* in the test beam.
*
*/
class HGCalTBMaterials {
public:
/// Create HGCal materials
HGCalTBMaterials();
/// Set visualisation attributes
void SetEventDisplayColorScheme();
/// Get length of the beam line (world)
inline G4double GetBeamLineLength() const { return fBeamLineLength; }
/// Get transverse size of the beam line (world)
inline G4double GetBeamLineXY() const { return fBeamLineXY; }
/// Get pointer to the air material
G4Material *GetAir() { return fMatAIR; }
/// Place logical volume
/// @param[in] aName Name of the logical volume
/// @param[in,out] aZ0 Position in front of the logical volume, incremented by
/// half the thickness for placement, and by another half thickness to return
/// the position just behind the placed volume
/// @param[in] aLogicMother Pointer to mother volume for placement
void PlaceItemInLogicalVolume(std::string aName, G4double &aZ0,
G4LogicalVolume *aLogicMother);
/// Get logical volume of silicon pixel (cell)
G4LogicalVolume *GetSiPixelLogical() { return this->fSiPixelLogical; }
/// Get logical volume of SiPM
G4LogicalVolume *GetAHCALSiPMlogical() { return this->fAHCALSiPMlogical; }
/// Get any logical volume by name
inline const G4LogicalVolume *GetLogicalVolume(G4String aName) {
return fLogicalVolumeMap[aName];
};
/// Get thickness of logical volume by name
inline G4double GetThickness(std::string aName) {
return fThicknessMap[aName];
};
private:
/// Define materisals used in HGCal test-beam
void DefineMaterials();
/// Define silicon wafer logical volume from silicon cells/pixels
void DefineSiWaferAndCells();
/// Define logical volumes for HGCal baseplates (CuW, Cu, PCB, Kapton layers)
void DefineHGCalBaseplates();
/// Define logical volumes for HGCal cases (Al, Steel)
void DefineHGCalCases();
/// Define logical volumes for HGCal electromagnetic part absorbers (Pb, Cu,
/// W)
void DefineHGCalEEAbsorbers();
/// Define logical volumes for HGCal hadronic part absorbers (Cu, Fe)
void DefineHGCalFHAbsorbers();
/// Define logical volumes for AHCAL SiPM
void DefineAHCALSiPM();
/// Define logical volumes for AHCAL absorbers
void DefineAHCALAbsorbers();
/// Define logical volumes for beamline elements (MCP, scintillators, DWC)
void DefineBeamLineElements();
/// Length of the beam line
G4double fBeamLineLength = 90 * CLHEP::m;
/// Transverse dimension of the beam line
G4double fBeamLineXY = 4 * CLHEP::m;
/// Rotation angle of silicon hexagon
G4double fAlpha;
/// Side length of silicon cell hexagon
G4double fSiPixelSideLength;
/// Thickness of silicon wafer hexagon
G4double fSiWaferThickness;
/// Side length of silicon wafer haxagon
G4double fSiWaferSideLength;
/// Transverse size of AHCAL SiPM
G4double fAHCALSiPMxy;
/// Box representing AHCAL SiPM
G4Box *fAHCALSiPMsolid;
/// Map of volume name to its thickness
std::map<G4String, G4double> fThicknessMap;
/// Map of volume name to its logical volume
std::map<G4String, G4LogicalVolume *> fLogicalVolumeMap;
/// Map of volume name to counter of placed copies
std::map<G4String, int> fCopyCounterMap;
/// Materials
G4Material *fMatVacuum;
G4Material *fMatAIR;
G4Material *fMatAr;
G4Material *fMatAl;
G4Material *fMatFe;
G4Material *fMatGlass;
G4Material *fMatSteel;
G4Material *fMatPb;
G4Material *fMatCu;
G4Material *fMatW;
G4Material *fMatSi;
G4Material *fMatKAPTON;
G4Material *fMatAu;
G4Material *fMatPCB;
G4Material *fMatQuartz;
G4Material *fMatPolystyrene;
G4Material *fMatCuW;
G4Material *fMatC;
G4Material *fMatH;
G4Material *fMatO;
G4Material *fMatMn;
G4Material *fMatCr;
G4Material *fMatNi;
G4Material *fMatPolyethylene;
G4Material *fMatFreon;
G4Material *fMatScintillator;
G4Material *fMatArCO2;
G4Material *fMatCl;
G4Material *fMatF;
/// Logical volumes
G4LogicalVolume *fSiPixelLogical;
G4LogicalVolume *fSiWaferLogical;
G4LogicalVolume *fCuWbaseplateLogical;
G4LogicalVolume *fCuWbaseplate550umLogical;
G4LogicalVolume *fCuWbaseplate610umLogical;
G4LogicalVolume *fCuWbaseplate710umLogical;
G4LogicalVolume *fCuBaseplateLogical;
G4LogicalVolume *fCuBaseplate25umLogical;
G4LogicalVolume *fCuBaseplate175umLogical;
G4LogicalVolume *fPCBbaseplateLogical;
G4LogicalVolume *fPCBbaseplateThinLogical;
G4LogicalVolume *fKaptonLayerLogical;
G4LogicalVolume *fAlCaseLogical;
G4LogicalVolume *fAlCaseThickLogical;
G4LogicalVolume *fAlChipLogical;
G4LogicalVolume *fSteelCaseLogical;
G4LogicalVolume *fSteelCaseThickLogical;
G4LogicalVolume *fPbAbsorberEElogical;
G4LogicalVolume *fFeAbsorberEElogical;
G4LogicalVolume *fCuAbsorberEElogical;
G4LogicalVolume *fWabsorberEElogical;
G4LogicalVolume *fW2mmAbsorberEEDESY2018Logical;
G4LogicalVolume *fW4mmAbsorberEEDESY2018Logical;
G4LogicalVolume *fCuAbsorberFHlogical;
G4LogicalVolume *fFeAbsorberFHlogical;
G4LogicalVolume *fAHCALSiPMlogical;
G4LogicalVolume *fAHCALSiPM2x2HUBlogical;
G4LogicalVolume *fAlAbsorberAHCALlogical;
G4LogicalVolume *fPCBAHCALlogical;
G4LogicalVolume *fFeAbsorberAHCALlogical;
G4LogicalVolume *fScintillatorLogical;
G4LogicalVolume *fScintillatorThinLogical;
G4LogicalVolume *fMCPlogical;
G4LogicalVolume *fDWClogical;
G4LogicalVolume *fDWCgasLogical;
G4LogicalVolume *fCK3logical;
};
#endif /* HGCALTBMATERIALS_HH */
@@ -0,0 +1,224 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef PRIMARYGENERATORACTION_HH
#define PRIMARYGENERATORACTION_HH
#include "G4String.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "CLHEP/Units/SystemOfUnits.h"
class G4ParticleGun;
class G4Event;
class G4Box;
class PrimaryGeneratorMessenger;
#ifdef WITHROOT
#include <RtypesCore.h>
class TFile;
class TTreeReader;
template <typename T> class TTreeReaderValue;
#endif
/**
* @brief Primary generator
*
* Primary generator action.
*
* By default particle gun is used. It can be controlled with standard UI
* commands (/gun/) and with additional ones introduced by the messenger.
* "/HGCalTestbeam/generator/momentumSpread <VALUE>" to change constant
* particle energy to Gaussian distribution with sigma expressed in units of the
* initial energy (e.g. value 0.05 means sigma of 0.05 * E).
* By default it equals to 0 and constant energy value is used.
* "/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>" to define type of
* beam position spread. By default none is used.
* "/HGCalTestbeam/generator/beamSpreadX <SIZE>" to define size of beam spread
* along x axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamSpreadY <SIZE>" to define size of beam spread
* along y axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/fBeamZ0 <POSITION>" to define beam position along z
* axis. By default edge of the world volume is used.
*
* If installation was done with ROOT package (CMake was able to locate it),
* an additional option of input read from the ROOT file is enabled.
* It can be activated with "/HGCalTestbeam/generator/fReadInputFile true".
* "/HGCalTestbeam/generator/fPathInputFile <FILE>" sets the path to the input
* file.
* "/HGCalTestbeam/generator/startFromEvent <N>" allows to start simulation from
* Nth event.
* Please note that in current implementation input from file needs to be
* executed in a non-multithreaded mode (or with 1 thread).
*
*/
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
public:
PrimaryGeneratorAction();
virtual ~PrimaryGeneratorAction();
virtual void GeneratePrimaries(G4Event *);
const G4ParticleGun *GetParticleGun() const { return fParticleGun; }
#ifdef WITHROOT
/// Open input file with list of particles
void OpenInput();
/// Set flag indicating that particles should be read from file
inline void SetIfUseInputFiles(G4bool aUseInputFiles) {
fReadInputFile = aUseInputFiles;
};
/// Set the flag indicating that particles should be read from file
inline G4bool GetIfUseInputFiles() { return fReadInputFile; }
/// Set the path to the input file
inline void SetInputFiles(G4String aInputFiles) {
fPathInputFile = aInputFiles;
};
/// Get the path to the input file
inline G4String GetInputFiles() const { return fPathInputFile; }
/// Set ID of the first event to be read for the simulation
inline void SetStartFromEvent(G4int aStartFromEvent) {
fStartFromEvent = aStartFromEvent;
};
/// Get ID of the first event to be read for the simulation
inline G4int GetStartFromEvent() const { return fStartFromEvent; }
#endif
/// Set sigma of the Gaussian distribution for the momentum spread
/// @param[in] aMomentumSpread sigma of Gaussian distribution expressed in
/// units of initial energy (e.g. 0.05 means sigma = 0.05 * E)
inline void SetMomentumSpread(G4double aMomentumSpread) {
fMomentumGaussianSpread = aMomentumSpread;
};
/// Get sigma of the Gaussian distribution for the momentum spread
inline G4double GetMomentumSpread() const { return fMomentumGaussianSpread; }
/// Set type of beam position spread
/// @param[in] aType Type of beam position spread: "none", "Gaussian" or
/// "flat". By default "none" is used.
inline void SetBeamSpreadType(G4String aType) {
if (aType == "none")
fBeamType = eNone;
if (aType == "Gaussian")
fBeamType = eGaussian;
if (aType == "flat")
fBeamType = eFlat;
}
/// Get type of beam position spread
inline G4String GetBeamSpreadType() const {
switch (fBeamType) {
case eNone:
return "none";
break;
case eGaussian:
return "Gaussian";
break;
case eFlat:
return "flat";
break;
}
return "";
}
/// Set size of beam position spread along X axis
/// @param[in] aBeamSpreadX Size of beam position spread. Sigma for Gaussian
/// distribution or half-width of flat distribution.
inline void SetBeamSpreadX(G4double aBeamSpreadX) {
fSigmaBeamX = aBeamSpreadX;
}
/// Get size of beam position spread along X axis
inline G4double GetBeamSpreadX() const { return fSigmaBeamX; }
/// Set size of beam position spread along Y axis
/// @param[in] aBeamSpreadY Size of beam position spread. Sigma for Gaussian
/// distribution or half-width of flat distribution.
inline void SetBeamSpreadY(G4double aBeamSpreadY) {
fSigmaBeamY = aBeamSpreadY;
}
/// Get size of beam position spread along Y axis
inline G4double GetBeamSpreadY() const { return fSigmaBeamY; }
/// Set initial beam position along Z axis
/// By default edge of world volume is used
inline void SetBeamZ0(G4double aBeamZ0) { fBeamZ0 = aBeamZ0; }
/// Get initial beam position along Z axis
inline G4double GetBeamZ0() const { return fBeamZ0; }
private:
/// Pointer to the particle gun
G4ParticleGun *fParticleGun;
/// Pointer to the world volume for initial beam position
G4Box *fEnvelopeBox;
/// Pointer to the messenger with custom UI commands
PrimaryGeneratorMessenger *fMessenger;
/// enum describing the beam position spread in transverse plane
enum eBeamType { eNone, eGaussian, eFlat };
/// Type of beam position spread in transverse dimension
eBeamType fBeamType = eBeamType::eNone;
/// Size of beam position spread along X axis
/// Sigma for Gaussian, and half-width for flat distribution
G4double fSigmaBeamX = 0;
/// Size of beam position spread along Y axis
/// Sigma for Gaussian, and half-width for flat distribution
G4double fSigmaBeamY = 0;
/// Initial beam position along Z axis
G4double fBeamZ0 = -999 * CLHEP::m;
/// Sigma of Gaussian momentum spread
G4double fMomentumGaussianSpread = 0;
#ifdef WITHROOT
/// Flag indicating if primaries should be read from file instead of using
/// the particle gun
G4bool fReadInputFile = false;
/// Path to the input file
G4String fPathInputFile = "";
/// ID of the first event in the file to be used in this simulation
G4int fStartFromEvent = 0;
/// Counter of event
G4int fEventCounter = -1;
/// Pointer to the input file
TFile *fInputFile = nullptr;
/// Pointer to the tree containing particles
TTreeReader *fHgcalReader = nullptr;
/// Reader of event ID
TTreeReaderValue<Float_t> *fHgcalEventId;
/// Reader of particle PDG
TTreeReaderValue<Float_t> *fHgcalPdgId;
/// Reader of particle X position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosX;
/// Reader of particle Y position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosY;
/// Reader of particle Z position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosZ;
/// Reader of particle X momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomX;
/// Reader of particle Y momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomY;
/// Reader of particle Z momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomZ;
#endif
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef PRIMARYGENERATORMMESSENGER_HH
#define PRIMARYGENERATORMMESSENGER_HH
#include "G4UImessenger.hh"
class G4UIdirectory;
class G4UIcmdWithABool;
class G4UIcmdWithAnInteger;
class G4UIcmdWithAString;
class G4UIcmdWithADouble;
class G4UIcmdWithADoubleAndUnit;
class PrimaryGeneratorAction;
/**
* @brief Primary generator messenger
*
* Defines UI commands to set up the primary generator.
*
* By default particle gun is used as the primary generator. It can be
* controlled with standard UI commands (/gun/).
*
* "/HGCalTestbeam/generator/momentumSpread <VALUE>" to change constant
* particle energy to Gaussian distribution with sigma expressed in units of the
* initial energy (e.g. value 0.05 means sigma of 0.05 * E).
* By default it equals to 0 and constant energy value is used.
* "/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>" to define type of
* beam position spread. By default none is used.
* "/HGCalTestbeam/generator/beamSpreadX <SIZE>" to define size of beam spread
* along x axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamSpreadY <SIZE>" to define size of beam spread
* along y axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamZ0 <POSITION>" to define beam position along z
* axis. By default edge of the world volume is used.
*
* If installation was done with ROOT package (CMake was able to locate it),
* an additional option of input read from the ROOT file is enabled.
* It can be activated with "/HGCalTestbeam/generator/readInputFile true".
* "/HGCalTestbeam/generator/pathInputFile <FILE>" sets the path to the input
* file.
* "/HGCalTestbeam/generator/startFromEvent <N>" allows to start simulation from
* Nth event.
* Please note that in current implementation input from file needs to be
* executed in a non-multithreaded mode (or with 1 thread).
*
*/
class PrimaryGeneratorMessenger : public G4UImessenger {
public:
explicit PrimaryGeneratorMessenger(PrimaryGeneratorAction *aPrimaryGeneratorAction);
~PrimaryGeneratorMessenger();
public:
void SetNewValue(G4UIcommand *command, G4String newValues);
G4String GetCurrentValue(G4UIcommand *command);
private:
/// Pointer to the primmary generator
PrimaryGeneratorAction *fPrimaryGenerator;
private:
/// Directory for UI commands
G4UIdirectory *fDirectory;
#ifdef WITHROOT
/// Command specyfing if primary event should be read from file
G4UIcmdWithABool *fReadInputCmd;
/// Command to set the path to the input file
G4UIcmdWithAString *fPathInputCmd;
/// Command to set ID of the first event to be read from the file
G4UIcmdWithAnInteger *fStartFromEventCmd;
#endif
/// Command to set the sigma of the Gaussian momentum spread
G4UIcmdWithADouble *fMomentumSpreadCmd;
/// Command to set the type of transverse beam position spread
G4UIcmdWithAString *fBeamSpreadTypeCmd;
/// Command to set the size of beam position spread along X axis
G4UIcmdWithADoubleAndUnit *fBeamSpreadXCmd;
/// Command to set the size of beam position spread along Y axis
G4UIcmdWithADoubleAndUnit *fBeamSpreadYCmd;
/// Command to set the initial beam position size along Z axis
G4UIcmdWithADoubleAndUnit *fBeamZ0Cmd;
};
#endif /*PRIMARYGENERATORMMESSENGER_HH */
@@ -0,0 +1,62 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef RUNACTION_HH
#define RUNACTION_HH
#include "G4UserRunAction.hh"
#include "G4String.hh"
class G4Run;
class EventAction;
class G4GenericMessenger;
/**
* @brief Run action
*
* Creates the output file with ntuple.
* Output name can be changed with UI command "/HGCalTestbeam/output/file
* <NAME>"
*
*/
class RunAction : public G4UserRunAction {
public:
explicit RunAction(EventAction *);
virtual ~RunAction();
virtual void BeginOfRunAction(const G4Run *);
virtual void EndOfRunAction(const G4Run *);
private:
/// Pointer to the event action to retrieve vectors
EventAction *fEventAction;
/// Name of the output file
G4String fOutputFileDir;
/// Pointer to the command messenger
G4GenericMessenger *fMessenger;
};
#endif /* RUNACTION_HH */
@@ -0,0 +1,137 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SIPMHIT_HHinline
#define SIPMHIT_HHinline
#include "G4THitsCollection.hh"
#include "G4VHit.hh"
#include "G4Types.hh"
#include "G4String.hh"
#include <vector>
/**
* @brief SiPM hit
*
* Stores information of energy deposited in the SiPM.
*
* Hits can be digitised, to take into account the time window for the deposits
* as well as to set the time information based on the energy threshold.
* By default no time window is used (all energy deposits are counted), as well
* as no energy threshold is used (time of the first energy deposit, however
* small, is counted as hit time).
*
*/
class SiPMHit : public G4VHit {
public:
/// Constructor
/// @param[in] aName Name of the pixel volume
/// @param[in] aCopyNoSensor ID of the sensor
/// @param[in] aCopyNoCell ID of the cell
SiPMHit(G4String aName, G4int aCopyNoSensor, G4int aCopyNoCell);
~SiPMHit(){};
/// Get hit ID calculated as 1000 * sensorID + cellID
G4int ID() { return 1000 * fCopyNumSensor + fCopyNumCell; }
/// Add non-zero energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdep(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdep.push_back(std::make_pair(aEnergy, aTime));
}
/// Add non-zero non-ionizing energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdepNonIonizing(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdepNonIonizing.push_back(std::make_pair(aEnergy, aTime));
}
/// Digitise hit
/// Calculate time of hit as global time of energy deposit which added
/// to hit energy exceeds the energy threshold. Take into account only
/// deposits with global time within the timeWindow.
/// @param[in] timeWindow Maximal global time for deposit, caounted from
/// the time of the first deposit
/// @param[in] toaThreshold Energy threshold, first deposit that adds to
/// the hit energy and exceeds the threshold is counted as time of
/// arrival.
void Digitise(const G4double timeWindow, const G4double toaThreshold);
/// Set hit position
/// @param[in] x X position
/// @param[in] y Y position
/// @param[in] z Z position
inline void SetPosition(G4double x, G4double y, G4double z) {
fPosX = x;
fPosY = y;
fPosZ = z;
}
/// Get hit X position
inline G4double GetX() const { return fPosX; }
/// Get hit Y position
inline G4double GetY() const { return fPosY; }
/// Get hit Z position
inline G4double GetZ() const { return fPosZ; }
/// Check if hit is valid
inline G4bool isValidHit() const { return fIsValidHit; }
/// Get hit energy
inline G4double GetEdep() const { return fEdepDigi; }
/// Get hit non-ionizing energy
inline G4double GetEdepNonIonizing() const { return fEdepNonIonizingDigi; }
/// Get time of arrival
inline G4double GetTOA() const { return fTimeOfArrival; }
private:
/// Name of the logical volume
G4String fVolumeName = "";
/// ID of the sensor
G4int fCopyNumCell = -1;
/// ID of the cell
G4int fCopyNumSensor = -1;
/// Position along x axis
G4double fPosX = -1;
/// Position along y axis
G4double fPosY = -1;
/// Position along z axis
G4double fPosZ = -1;
/// Vector of energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdep;
/// Vector of non-ionizing energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdepNonIonizing;
/// Flag indicating if hit is valid (digitised and with non-zero energy)
G4bool fIsValidHit = false;
/// Energy of the digitised hit
G4double fEdepDigi = -1;
/// Non-ionizing energy of the digitised hit
G4double fEdepNonIonizingDigi = -1;
/// Time of arrival of the digitised hit
G4double fTimeOfArrival = -1;
};
typedef G4THitsCollection<SiPMHit> SiPMHitCollection;
#endif /* SIPMHIT_HH */
@@ -0,0 +1,68 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SIPMSD_HH
#define SIPMSD_HH
#include "SiPMHit.hh"
#include "G4VSensitiveDetector.hh"
#include "G4Types.hh"
#include <map>
/**
* @brief Sensitive detector for SiPMs
*
* Processes step information and stores it in SiPM hits.
* Information is stored in units of:
* - keV for energy
* - cm for position
*
*/
class SiPMSD : public G4VSensitiveDetector {
public:
explicit SiPMSD(G4String name);
~SiPMSD();
/// Hits are processed and added to the temporary map of hit ID to hit
/// pointer. Energy is stored in units of keV, and position in cm.
G4bool ProcessHits(G4Step *step, G4TouchableHistory *ROhist);
void Initialize(G4HCofThisEvent *HCE);
/// Temporary map of hits is stored in hit collection, to be retrieved
/// for analysis by the event action
void EndOfEvent(G4HCofThisEvent *HCE);
private:
/// Hit collection stored in the event, filled in at the end of event based
/// on temporary hits
SiPMHitCollection *fHitCollection = nullptr;
/// ID of hit collection
G4int fHCID = -1;
/// Temporary map of hits (ID: hit) collected within one event
std::map<G4int, SiPMHit *> fTmpHits;
};
#endif /* SIPMSD_HH */
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SILICONPIXELHIT_HH
#define SILICONPIXELHIT_HH
#include "G4THitsCollection.hh"
#include "G4VHit.hh"
#include "G4Types.hh"
#include <vector>
/**
* @brief Silicon pixel hit
*
* Stores information of energy deposited in the silicon pixel.
*
* Hits can be digitised, to take into account the time window for the deposits
* as well as to set the time information based on the energy threshold.
* By default no time window is used (all energy deposits are counted), as well
* as no energy threshold is used (time of the first energy deposit, however
* small, is counted as hit time).
*
*/
class SiliconPixelHit : public G4VHit {
public:
/// Constructor
/// @param[in] aName Name of the pixel volume
/// @param[in] aCopyNumSensor ID of the sensor
/// @param[in] aCopyNumCell ID of the cell
SiliconPixelHit(G4String aName, G4int aCopyNumSensor, G4int aCopyNumCell);
~SiliconPixelHit(){};
/// Draw pixels
void Draw();
/// Get hit ID calculated as 1000 * sensorID + cellID
G4int ID() { return 1000 * fCopyNumSensor + fCopyNumCell; }
/// Add non-zero energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdep(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdep.push_back(std::make_pair(aEnergy, aTime));
}
/// Add non-zero non-ionizing energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdepNonIonizing(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdepNonIonizing.push_back(std::make_pair(aEnergy, aTime));
}
/// Digitise hit
/// Calculate time of hit as global time of energy deposit which added
/// to hit energy exceeds the energy threshold. Take into account only
/// deposits with global time within the time window.
/// @param[in] aTimeWindow Maximal global time for deposit, caounted from
/// the time of the first deposit
/// @param[in] aToaThreshold Energy threshold, first deposit that adds to
/// the hit energy and exceeds the threshold is counted as time of
/// arrival.
void Digitise(const G4double aTimeWindow, const G4double aToaThreshold);
/// Set hit position
/// @param[in] x X position
/// @param[in] y Y position
/// @param[in] z Z position
inline void SetPosition(G4double x, G4double y, G4double z) {
fPosX = x;
fPosY = y;
fPosZ = z;
}
/// Get hit X position
inline G4double GetX() const { return fPosX; }
/// Get hit Y position
inline G4double GetY() const { return fPosY; }
/// Get hit Z position
inline G4double GetZ() const { return fPosZ; }
/// Check if hit is valid
inline G4bool isValidHit() const { return fIsValidHit; }
/// Get hit energy
inline G4double GetEdep() const { return fEdepDigi; }
/// Get hit non-ionizing energy
inline G4double GetEdepNonIonizing() const { return fEdepNonIonizingDigi; }
/// Get time of arrival
inline G4double GetTOA() const { return fTimeOfArrival; }
/// Get time of arrival from the last energy deposit
inline G4double GetLastTOA() const { return fTimeOfArrivalLast; }
private:
/// Name of the logical volume
G4String fVolumeName = "";
/// ID of the sensor
G4int fCopyNumCell = -1;
/// ID of the cell
G4int fCopyNumSensor = -1;
/// Position along x axis
G4double fPosX = -1;
/// Position along y axis
G4double fPosY = -1;
/// Position along z axis
G4double fPosZ = -1;
/// Vector of energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdep;
/// Vector of non-ionizing energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdepNonIonizing;
/// Flag indicating if hit is valid (digitised and with non-zero energy)
G4bool fIsValidHit = false;
/// Energy of the digitised hit
G4double fEdepDigi = -1;
/// Non-ionizing energy of the digitised hit
G4double fEdepNonIonizingDigi = -1;
/// Time of arrival of the digitised hit
G4double fTimeOfArrival = -1;
/// Last time of arrival of the digitised hit
G4double fTimeOfArrivalLast = -1;
};
typedef G4THitsCollection<SiliconPixelHit> SiliconPixelHitCollection;
#endif /* SILICONPIXELHIT_HH */
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SILICONPIXELSD_HH
#define SILICONPIXELSD_HH
#include "G4VSensitiveDetector.hh"
#include "SiliconPixelHit.hh"
#include "G4Types.hh"
#include <map>
/**
* @brief Sensitive detector for silicon pixels
*
* Processes step information and stores it in silicon hits.
* Information is stored in units of:
* - keV for energy
* - cm for position
*
*/
class SiliconPixelSD : public G4VSensitiveDetector {
public:
explicit SiliconPixelSD(G4String name);
~SiliconPixelSD();
/// Hits are processed and added to the temporary map of hit ID to hit
/// pointer. Energy is stored in units of keV, and position in cm.
G4bool ProcessHits(G4Step *step, G4TouchableHistory *ROhist);
void Initialize(G4HCofThisEvent *HCE);
/// Temporary map of hits is stored in hit collection, to be retrieved
/// for analysis by the event action
void EndOfEvent(G4HCofThisEvent *HCE);
private:
/// Hit collection stored in the event, filled in at the end of event based
/// on temporary hits
SiliconPixelHitCollection *fHitCollection = nullptr;
/// ID of hit collection
G4int fHCID = -1;
/// Temporary map of hits (ID: hit) collected within one event
std::map<G4int, SiliconPixelHit *> fTmpHits;
};
#endif /* SILICONPIXELSD_HH */
@@ -0,0 +1,13 @@
# Macro file for the initialization of example HGCal_testbeam
# in interactive session
#
# Set some default verbose
/control/verbose 2
/control/saveHistory
/run/verbose 2
#
# Initialize kernel
/run/initialize
#
# Visualization setting
/control/execute vis.mac
@@ -0,0 +1,26 @@
# Macro file for sample run of the HGCal testbeam simulation
#
# Set verbosity levels
#/control/verbose 2
#/control/saveHistory
#/run/verbose 2
#/tracking/verbose 2
# Use only one thread
/run/numberOfThreads 1
# Initialize kernel
/run/initialize
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0
# Read input particles from file
/HGCalTestbeam/generator/readInputFile true
# Substitute <INPUTFILE.root> with name of the file
/HGCalTestbeam/generator/pathInputFile INPUTFILE.root
/HGCalTestbeam/generator/startFromEvent 0
/HGCalTestbeam/output/file output_inputFromFile_10events.root
/run/beamOn 10
+32
View File
@@ -0,0 +1,32 @@
# Macro file for sample run of the HGCal testbeam simulation
#
# Set verbosity levels
#/control/verbose 2
#/control/saveHistory
#/run/verbose 2
#/tracking/verbose 2
# Initialize kernel
/run/initialize
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0
# Electrons
/gun/energy 30 GeV
/gun/particle e-
# Smeared beam position and momentum
# 5% Gaussian spread of momentum
/HGCalTestbeam/generator/momentumSpread 0.05
# Gaussian spread of transverse beam position (sigma 1.5 cm)
/HGCalTestbeam/generator/beamSpread Gaussian # none flat
/HGCalTestbeam/generator/beamSpreadX 1.5 cm
/HGCalTestbeam/generator/beamSpreadY 1.5 cm
/HGCalTestbeam/generator/beamZ0 -1 m
# Choose max step in silicon pixel (in um)
/HGCalTestbeam/setup/stepSilicon 20
/HGCalTestbeam/output/file output_eM_smeared_30GeV_10events.root
/run/beamOn 10
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
EventAction *eventAction = new EventAction();
SetUserAction(new RunAction(eventAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
SetUserAction(new PrimaryGeneratorAction);
EventAction *eventAction = new EventAction();
SetUserAction(eventAction);
RunAction *runAction = new RunAction(eventAction);
SetUserAction(runAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,381 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "CMSEmStandardPhysicsHcal.hh"
#include "G4EmParameters.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4ComptonScattering.hh"
#include "G4GammaConversion.hh"
#include "G4PhotoElectricEffect.hh"
#include "G4CoulombScattering.hh"
#include "G4MuMultipleScattering.hh"
#include "G4UrbanMscModel.hh"
#include "G4WentzelVIModel.hh"
#include "G4eCoulombScatteringModel.hh"
#include "G4eMultipleScattering.hh"
#include "G4hMultipleScattering.hh"
#include "G4eBremsstrahlung.hh"
#include "G4eIonisation.hh"
#include "G4eplusAnnihilation.hh"
#include "G4MuBremsstrahlung.hh"
#include "G4MuIonisation.hh"
#include "G4MuPairProduction.hh"
#include "G4hBremsstrahlung.hh"
#include "G4hIonisation.hh"
#include "G4hPairProduction.hh"
#include "G4ionIonisation.hh"
#include "G4Alpha.hh"
#include "G4AntiLambdacPlus.hh"
#include "G4AntiOmegaMinus.hh"
#include "G4AntiProton.hh"
#include "G4AntiSigmaMinus.hh"
#include "G4AntiSigmaPlus.hh"
#include "G4AntiXiMinus.hh"
#include "G4AntiXicPlus.hh"
#include "G4BMesonMinus.hh"
#include "G4BMesonPlus.hh"
#include "G4DMesonMinus.hh"
#include "G4DMesonPlus.hh"
#include "G4Deuteron.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "G4GenericIon.hh"
#include "G4He3.hh"
#include "G4KaonMinus.hh"
#include "G4KaonPlus.hh"
#include "G4LambdacPlus.hh"
#include "G4MuonMinus.hh"
#include "G4MuonPlus.hh"
#include "G4OmegaMinus.hh"
#include "G4PionMinus.hh"
#include "G4PionPlus.hh"
#include "G4Positron.hh"
#include "G4Proton.hh"
#include "G4SigmaMinus.hh"
#include "G4SigmaPlus.hh"
#include "G4TauMinus.hh"
#include "G4TauPlus.hh"
#include "G4Triton.hh"
#include "G4XiMinus.hh"
#include "G4XicPlus.hh"
#include "G4BuilderType.hh"
#include "G4PhysicsListHelper.hh"
#include "G4RegionStore.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
CMSEmStandardPhysicsHcal::CMSEmStandardPhysicsHcal(G4int ver)
: G4VPhysicsConstructor("CMSEmStandard_emm"), fVerbose(ver) {
G4EmParameters *param = G4EmParameters::Instance();
param->SetDefaults();
param->SetVerbose(fVerbose);
param->SetApplyCuts(true);
param->SetMscRangeFactor(0.2);
param->SetMscStepLimitType(fMinimal);
SetPhysicsType(bElectromagnetic);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
CMSEmStandardPhysicsHcal::~CMSEmStandardPhysicsHcal() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void CMSEmStandardPhysicsHcal::ConstructParticle() {
// gamma
G4Gamma::Gamma();
// leptons
G4Electron::Electron();
G4Positron::Positron();
G4MuonPlus::MuonPlus();
G4MuonMinus::MuonMinus();
G4TauMinus::TauMinusDefinition();
G4TauPlus::TauPlusDefinition();
// mesons
G4PionPlus::PionPlusDefinition();
G4PionMinus::PionMinusDefinition();
G4KaonPlus::KaonPlusDefinition();
G4KaonMinus::KaonMinusDefinition();
G4DMesonMinus::DMesonMinusDefinition();
G4DMesonPlus::DMesonPlusDefinition();
G4BMesonMinus::BMesonMinusDefinition();
G4BMesonPlus::BMesonPlusDefinition();
// barions
G4Proton::Proton();
G4AntiProton::AntiProton();
G4SigmaMinus::SigmaMinusDefinition();
G4AntiSigmaMinus::AntiSigmaMinusDefinition();
G4SigmaPlus::SigmaPlusDefinition();
G4AntiSigmaPlus::AntiSigmaPlusDefinition();
G4XiMinus::XiMinusDefinition();
G4AntiXiMinus::AntiXiMinusDefinition();
G4OmegaMinus::OmegaMinusDefinition();
G4AntiOmegaMinus::AntiOmegaMinusDefinition();
G4LambdacPlus::LambdacPlusDefinition();
G4AntiLambdacPlus::AntiLambdacPlusDefinition();
G4XicPlus::XicPlusDefinition();
G4AntiXicPlus::AntiXicPlusDefinition();
// ions
G4Deuteron::Deuteron();
G4Triton::Triton();
G4He3::He3();
G4Alpha::Alpha();
G4GenericIon::GenericIonDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void CMSEmStandardPhysicsHcal::ConstructProcess() {
if (fVerbose > 0) {
G4cout << "### " << GetPhysicsName() << " Construct Processes " << G4endl;
}
// This EM builder takes default models of Geant4 10 EMV.
// Multiple scattering by Urban for all particles
// except e+e- below 100 MeV for which the Urban93 model is used
G4PhysicsListHelper *ph = G4PhysicsListHelper::GetPhysicsListHelper();
// muon & hadron bremsstrahlung and pair production
G4MuBremsstrahlung *mub = nullptr;
G4MuPairProduction *mup = nullptr;
G4hBremsstrahlung *pib = nullptr;
G4hPairProduction *pip = nullptr;
G4hBremsstrahlung *kb = nullptr;
G4hPairProduction *kp = nullptr;
G4hBremsstrahlung *pb = nullptr;
G4hPairProduction *pp = nullptr;
// muon & hadron multiple scattering
G4MuMultipleScattering *mumsc = nullptr;
G4MuMultipleScattering *pimsc = nullptr;
G4MuMultipleScattering *kmsc = nullptr;
G4MuMultipleScattering *pmsc = nullptr;
G4hMultipleScattering *hmsc = nullptr;
G4CoulombScattering *muss = nullptr;
G4CoulombScattering *piss = nullptr;
G4CoulombScattering *kss = nullptr;
G4CoulombScattering *pss = nullptr;
// high energy limit for e+- scattering models and bremsstrahlung
G4double highEnergyLimit = 100 * CLHEP::MeV;
G4Region *aRegion = G4RegionStore::GetInstance()->GetRegion("HcalRegion");
auto myParticleIterator = GetParticleIterator();
myParticleIterator->reset();
while ((*myParticleIterator)()) {
G4ParticleDefinition *particle = myParticleIterator->value();
G4String particleName = particle->GetParticleName();
if (particleName == "gamma") {
ph->RegisterProcess(new G4PhotoElectricEffect(), particle);
ph->RegisterProcess(new G4ComptonScattering(), particle);
ph->RegisterProcess(new G4GammaConversion(), particle);
} else if (particleName == "e-") {
G4eIonisation *eioni = new G4eIonisation();
eioni->SetStepFunction(0.8, 1.0 * CLHEP::mm);
G4eMultipleScattering *msc = new G4eMultipleScattering;
msc->SetStepLimitType(fMinimal);
G4UrbanMscModel *msc1 = new G4UrbanMscModel();
G4WentzelVIModel *msc2 = new G4WentzelVIModel();
G4UrbanMscModel *msc3 = new G4UrbanMscModel();
msc3->SetLocked(true);
msc1->SetHighEnergyLimit(highEnergyLimit);
msc2->SetLowEnergyLimit(highEnergyLimit);
msc3->SetHighEnergyLimit(highEnergyLimit);
msc->AddEmModel(0, msc1);
msc->AddEmModel(0, msc2);
msc->AddEmModel(-1, msc3, aRegion);
G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel();
G4CoulombScattering *ss = new G4CoulombScattering();
ss->SetEmModel(ssm, 1);
ss->SetMinKinEnergy(highEnergyLimit);
ssm->SetLowEnergyLimit(highEnergyLimit);
ssm->SetActivationLowEnergyLimit(highEnergyLimit);
ph->RegisterProcess(msc, particle);
ph->RegisterProcess(eioni, particle);
ph->RegisterProcess(new G4eBremsstrahlung(), particle);
ph->RegisterProcess(ss, particle);
} else if (particleName == "e+") {
G4eIonisation *eioni = new G4eIonisation();
eioni->SetStepFunction(0.8, 1.0 * CLHEP::mm);
G4eMultipleScattering *msc = new G4eMultipleScattering;
msc->SetStepLimitType(fMinimal);
G4UrbanMscModel *msc1 = new G4UrbanMscModel();
G4WentzelVIModel *msc2 = new G4WentzelVIModel();
G4UrbanMscModel *msc3 = new G4UrbanMscModel();
msc1->SetHighEnergyLimit(highEnergyLimit);
msc2->SetLowEnergyLimit(highEnergyLimit);
msc3->SetHighEnergyLimit(highEnergyLimit);
msc3->SetLocked(true);
msc->AddEmModel(0, msc1);
msc->AddEmModel(0, msc2);
msc->AddEmModel(-1, msc3, aRegion);
G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel();
G4CoulombScattering *ss = new G4CoulombScattering();
ss->SetEmModel(ssm, 1);
ss->SetMinKinEnergy(highEnergyLimit);
ssm->SetLowEnergyLimit(highEnergyLimit);
ssm->SetActivationLowEnergyLimit(highEnergyLimit);
ph->RegisterProcess(msc, particle);
ph->RegisterProcess(eioni, particle);
ph->RegisterProcess(new G4eBremsstrahlung(), particle);
ph->RegisterProcess(new G4eplusAnnihilation(), particle);
ph->RegisterProcess(ss, particle);
} else if (particleName == "mu+" || particleName == "mu-") {
if (nullptr == mub) {
mub = new G4MuBremsstrahlung();
mup = new G4MuPairProduction();
mumsc = new G4MuMultipleScattering();
mumsc->AddEmModel(0, new G4WentzelVIModel());
muss = new G4CoulombScattering();
}
ph->RegisterProcess(mumsc, particle);
ph->RegisterProcess(new G4MuIonisation(), particle);
ph->RegisterProcess(mub, particle);
ph->RegisterProcess(mup, particle);
ph->RegisterProcess(muss, particle);
} else if (particleName == "alpha" || particleName == "He3") {
ph->RegisterProcess(new G4hMultipleScattering(), particle);
ph->RegisterProcess(new G4ionIonisation(), particle);
} else if (particleName == "GenericIon") {
if (nullptr == hmsc) {
hmsc = new G4hMultipleScattering("ionmsc");
}
ph->RegisterProcess(hmsc, particle);
ph->RegisterProcess(new G4ionIonisation(), particle);
} else if (particleName == "pi+" || particleName == "pi-") {
if (nullptr == pib) {
pib = new G4hBremsstrahlung();
pip = new G4hPairProduction();
pimsc = new G4MuMultipleScattering();
pimsc->AddEmModel(0, new G4WentzelVIModel());
piss = new G4CoulombScattering();
}
ph->RegisterProcess(pimsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(pib, particle);
ph->RegisterProcess(pip, particle);
ph->RegisterProcess(piss, particle);
} else if (particleName == "kaon+" || particleName == "kaon-") {
if (nullptr == kb) {
kb = new G4hBremsstrahlung();
kp = new G4hPairProduction();
kmsc = new G4MuMultipleScattering();
kmsc->AddEmModel(0, new G4WentzelVIModel());
kss = new G4CoulombScattering();
}
ph->RegisterProcess(kmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(kb, particle);
ph->RegisterProcess(kp, particle);
ph->RegisterProcess(kss, particle);
} else if (particleName == "proton" || particleName == "anti_proton") {
if (nullptr == pb) {
pb = new G4hBremsstrahlung();
pp = new G4hPairProduction();
pmsc = new G4MuMultipleScattering();
pmsc->AddEmModel(0, new G4WentzelVIModel());
pss = new G4CoulombScattering();
}
ph->RegisterProcess(pmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(pb, particle);
ph->RegisterProcess(pp, particle);
ph->RegisterProcess(pss, particle);
} else if (particleName == "B+" || particleName == "B-" ||
particleName == "D+" || particleName == "D-" ||
particleName == "Ds+" || particleName == "Ds-" ||
particleName == "anti_He3" || particleName == "anti_alpha" ||
particleName == "anti_deuteron" ||
particleName == "anti_lambda_c+" ||
particleName == "anti_omega-" ||
particleName == "anti_sigma_c+" ||
particleName == "anti_sigma_c++" ||
particleName == "anti_sigma+" || particleName == "anti_sigma-" ||
particleName == "anti_triton" || particleName == "anti_xi_c+" ||
particleName == "anti_xi-" || particleName == "deuteron" ||
particleName == "lambda_c+" || particleName == "omega-" ||
particleName == "sigma_c+" || particleName == "sigma_c++" ||
particleName == "sigma+" || particleName == "sigma-" ||
particleName == "tau+" || particleName == "tau-" ||
particleName == "triton" || particleName == "xi_c+" ||
particleName == "xi-") {
if (nullptr == hmsc) {
hmsc = new G4hMultipleScattering("ionmsc");
}
ph->RegisterProcess(hmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
}
}
// Deexcitation
//
G4VAtomDeexcitation *de = new G4UAtomicDeexcitation();
G4LossTableManager::Instance()->SetAtomDeexcitation(de);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,194 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction.hh"
#include "HGCalTBMaterials.hh"
#include "SiPMSD.hh"
#include "SiliconPixelSD.hh"
#include "DetectorConstruction0.hh"
#include "DetectorConstruction1.hh"
#include "DetectorConstruction2.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"
#include "G4GenericMessenger.hh"
#include "G4LogicalVolume.hh"
#include "G4ProductionCuts.hh"
#include "G4RunManager.hh"
#include "G4SDManager.hh"
#include "G4UImanager.hh"
#include "G4UserLimits.hh"
#include "G4String.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: G4VUserDetectorConstruction(), fConfiguration(-1) {
DefineCommands();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume *DetectorConstruction::Construct() {
// definition of the fMaterials
fMaterials = new HGCalTBMaterials();
fMaterials->SetEventDisplayColorScheme();
/***** Definition of the world = beam line *****/
// World = Beam line
G4Box *solidWorld = new G4Box("World", 0.5 * fMaterials->GetBeamLineXY(),
0.5 * fMaterials->GetBeamLineXY(),
0.5 * fMaterials->GetBeamLineLength());
G4Material *world_mat = fMaterials->GetAir();
fLogicWorld = new G4LogicalVolume(solidWorld, world_mat, "World");
G4VPhysicalVolume *physWorld = new G4PVPlacement(
0, G4ThreeVector(0., 0., 0.), fLogicWorld, "World", 0, false, 0, true);
return physWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructHGCal() {
G4double z0 = -fMaterials->GetBeamLineLength() / 2.;
std::cout << "Constructing configuration " << fConfiguration << std::endl;
/***** START GENERIC PLACEMENT ALGORITHM FOR THE SETUP *****/
for (size_t item_index = 0; item_index < fElementsMap.size(); item_index++) {
std::string item_type = fElementsMap[item_index].first;
G4double dz = fElementsMap[item_index].second;
z0 += dz;
// places the item at inside the world at z0, z0 is incremented by the
// item's thickness
fMaterials->PlaceItemInLogicalVolume(item_type, z0, fLogicWorld);
}
G4RunManager::GetRunManager()->GeometryHasBeenModified();
G4UImanager *UImanager = G4UImanager::GetUIpointer();
UImanager->ApplyCommand("/vis/drawVolume");
UImanager->ApplyCommand("/vis/viewer/set/targetPoint 0 0 " +
std::to_string(fVisViewpoint / CLHEP::m) + " m");
UImanager->ApplyCommand("/vis/scene/add/trajectories smooth");
UImanager->ApplyCommand("/vis/scene/add/hits");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField() {
G4SDManager *sdman = G4SDManager::GetSDMpointer();
SiliconPixelSD *sensitiveSilicon = new SiliconPixelSD(
(fMaterials->GetSiPixelLogical()->GetName() + "_sensitive").c_str());
sdman->AddNewDetector(sensitiveSilicon);
fMaterials->GetSiPixelLogical()->SetSensitiveDetector(sensitiveSilicon);
SiPMSD *sensitiveSiPM = new SiPMSD(
(fMaterials->GetAHCALSiPMlogical()->GetName() + "_sensitive").c_str());
sdman->AddNewDetector(sensitiveSiPM);
fMaterials->GetAHCALSiPMlogical()->SetSensitiveDetector(sensitiveSiPM);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SelectConfiguration(G4int val) {
if (fConfiguration != -1) {
G4ExceptionDescription msg;
msg << "Configuration " << fConfiguration << " is already placed.\n"
<< "Configuration can be set only once. Please restart (and\n"
<< "edit your macro if necessary).\n";
G4Exception("DetectorConstruction::SelectConfiguration()", "MultipleConfig",
JustWarning, msg);
return;
}
fVisViewpoint = 0;
if (val == 0)
DetectorConstruction0(fElementsMap, fVisViewpoint);
else if (val == 1)
DetectorConstruction1(fElementsMap, fVisViewpoint);
else if (val == 2)
DetectorConstruction2(fElementsMap, fVisViewpoint);
else {
G4ExceptionDescription msg;
msg << "Configuration " << val << " is not implemented.\n"
<< "Choose between configuration 0, 1, and 2.\n";
G4Exception("DetectorConstruction::SelectConfiguration()", "WrongConfig",
JustWarning, msg);
return;
}
fConfiguration = val;
ConstructHGCal();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetStepSizeSilicon(G4double val) {
// setting the step size in silicon:
G4double maxTrackLength = val * 0.001 * CLHEP::mm;
fMaterials->GetSiPixelLogical()->SetUserLimits(
new G4UserLimits(0, maxTrackLength));
G4Region *reg = fMaterials->GetSiPixelLogical()->GetRegion();
G4ProductionCuts *cuts = new G4ProductionCuts;
cuts->SetProductionCut(maxTrackLength);
reg->SetProductionCuts(cuts);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineCommands() {
// define command directory using generic messenger class
fMessenger = new G4GenericMessenger(this, "/HGCalTestbeam/setup/",
"Configuration specifications");
// configuration command
auto &configCmd = fMessenger->DeclareMethod(
"configuration", &DetectorConstruction::SelectConfiguration,
"Select the configuration (0 for HGCal test beam, 1 for same HGCal"
" with beamline (upstream material), or 2 for simple test setup)");
configCmd.SetParameterName("index", true);
configCmd.SetDefaultValue("0");
auto &SiStepSizeCmd = fMessenger->DeclareMethod(
"stepSilicon", &DetectorConstruction::SetStepSizeSilicon,
"Maximum step size in silicon pixels, unit: microns");
SiStepSizeCmd.SetParameterName("size", true);
SiStepSizeCmd.SetDefaultValue("30.");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,227 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction0.hh"
#include "CLHEP/Units/SystemOfUnits.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void add_EE(G4int aEEid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid) {
aDzMap.push_back(std::make_pair("Fe_absorber_EE",
aAirBefore)); // aAirBefore AIR + 0.3 mm Fe
aDzMap.push_back(std::make_pair("Pb_absorber_EE", 0)); // 0 + 4.9mm Pb
aDzMap.push_back(std::make_pair("Fe_absorber_EE", 0)); // 0 + 0.3 mm Fe
aDzMap.push_back(std::make_pair("PCB", aAirMid)); // aAirMid AIR +1.3mm
aDzMap.push_back(std::make_pair("Cu_baseplate_175um", 0.)); // 0 + 0.175mm Cu
aDzMap.push_back(std::make_pair("Si_wafer", 0.)); // 0.3 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_25um", 0.)); // 0 + 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer", 0.)); // 0.075 mm
if (aEEid == 11 || aEEid == 12)
aDzMap.push_back(std::make_pair("Cu_baseplate", 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.)); // 1.2 mm
if (aEEid == 13)
aDzMap.push_back(std::make_pair("CuW_baseplate_550um", 0.)); // 0.55 mm
if (aEEid == 14)
aDzMap.push_back(std::make_pair("CuW_baseplate_610um", 0.)); // 0.61 mm
aDzMap.push_back(std::make_pair("Cu_absorber_EE", 0.)); // 6 mm
if (aEEid == 13)
aDzMap.push_back(std::make_pair("CuW_baseplate_610um", 0.)); // 0.61 mm
if (aEEid == 14)
aDzMap.push_back(std::make_pair("CuW_baseplate_710um", 0.)); // 0.71 mm
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.)); // 1.2 mm
if (aEEid == 11 || aEEid == 12)
aDzMap.push_back(std::make_pair("Cu_baseplate", 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("Kapton_layer", 0.)); // 0.075 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_25um", 0.)); // 0 + 0.025mm Cu
aDzMap.push_back(std::make_pair("Si_wafer", 0.)); // 0.3 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_175um", 0.)); // 0 + 0.175mm Cu
aDzMap.push_back(std::make_pair("PCB", 0)); // 1.3 mm
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void add_FH(G4int aFHid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid) {
std::string layout = "";
if (aFHid < 10)
layout = "_DAISY";
if (!(aFHid == 1 || aFHid == 7))
aDzMap.push_back(std::make_pair("Fe_absorber_FH",
aAirBefore)); // aAirBefore AIR + 40 mm Fe
aDzMap.push_back(
std::make_pair("PCB" + layout, aAirMid)); // aAirMid AIR + 1.3 mm
aDzMap.push_back(
std::make_pair("Cu_baseplate_175um" + layout, 0.)); // 0.175mm Cu
aDzMap.push_back(std::make_pair("Si_wafer" + layout, 0.)); // 0.3 mm
if (aFHid == 5) {
aDzMap.push_back(std::make_pair("PCB_thin" + layout, 0)); // 1.2 mm
}
if (aFHid != 5) {
aDzMap.push_back(
std::make_pair("Cu_baseplate_25um" + layout, 0.)); // 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer" + layout, 0.)); // 0.075 mm
}
if (aFHid == 6) {
aDzMap.push_back(
std::make_pair("Cu_baseplate_25um" + layout, 0.)); // 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer" + layout, 0.)); // 0.075 mm
}
if (aFHid != 5 && aFHid < 9)
aDzMap.push_back(std::make_pair("Cu_baseplate" + layout, 0.)); // 1.2 mm
if (aFHid == 9 || aFHid == 10)
aDzMap.push_back(std::make_pair("CuW_baseplate" + layout, 0.)); // 1.2 mm
if (aFHid != 10)
aDzMap.push_back(std::make_pair("Cu_baseplate" + layout, 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("Cu_absorber_FH", 0.)); // 6 * mm
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction0(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
aViewpoint = 0.75 * CLHEP::m;
// map means: position this material starting at z, where:
// z += <second>
// z = z0+ 0.5 * thickness[<first>]
// world (and beam) starts at -45 m
G4double firstOffset = 2.6 * CLHEP::cm;
// if no beamline is present - shift by beamline length 45.0015 m
if (aDzMap.size() == 0) {
firstOffset += 45.0015 * CLHEP::m;
}
aDzMap.push_back(std::make_pair("Al_case_thick", firstOffset)); // 5 mm Al
aDzMap.push_back(std::make_pair("Al_case", 0)); // 2.1 mm Al
// EE1
add_EE(1, aDzMap, 119.7 * CLHEP::mm, 4.7 * CLHEP::mm);
// EE2
add_EE(2, aDzMap, 7.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE3
add_EE(3, aDzMap, 7.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE4
add_EE(4, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE5
add_EE(5, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE6
add_EE(6, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE7
add_EE(7, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE8
add_EE(8, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE9
add_EE(9, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE10
add_EE(10, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE11
add_EE(11, aDzMap, 6.7 * CLHEP::mm, 5.5 * CLHEP::mm);
// EE12
add_EE(12, aDzMap, 9.5 * CLHEP::mm, 5.5 * CLHEP::mm);
// EE13
add_EE(13, aDzMap, 9.5 * CLHEP::mm, 3.145 * CLHEP::mm);
// EE14
add_EE(14, aDzMap, 10.09 * CLHEP::mm, 3.095 * CLHEP::mm);
aDzMap.push_back(std::make_pair("Steel_case_thick", 0)); // 40 mm
aDzMap.push_back(std::make_pair("Al_case", 44 * CLHEP::mm)); // 2.1 mm
// beginning of FH
aDzMap.push_back(std::make_pair("Steel_case", 0)); // 9 mm
// FH1
add_FH(1, aDzMap, 0, 8.8 * CLHEP::mm);
// FH2
add_FH(2, aDzMap, 8 * CLHEP::mm, 8.8 * CLHEP::mm);
// FH3
add_FH(3, aDzMap, 3 * CLHEP::mm, 13.8 * CLHEP::mm);
// FH4
add_FH(4, aDzMap, 5 * CLHEP::mm, 12.8 * CLHEP::mm);
// FH5
add_FH(5, aDzMap, 7 * CLHEP::mm, 9.8 * CLHEP::mm);
// FH6
add_FH(6, aDzMap, 6 * CLHEP::mm, 10.7 * CLHEP::mm);
// cases
aDzMap.push_back(std::make_pair("Steel_case", 4 * CLHEP::mm)); // 9 mm
aDzMap.push_back(std::make_pair("Fe_absorber_FH", 36 * CLHEP::mm)); // 40 mm
aDzMap.push_back(std::make_pair("Steel_case", 52 * CLHEP::mm)); // 9 mm
// FH7
add_FH(7, aDzMap, 0, 8.8 * CLHEP::mm);
// FH8
add_FH(8, aDzMap, 7 * CLHEP::mm, 16.8 * CLHEP::mm);
// FH9
add_FH(9, aDzMap, 9 * CLHEP::mm, 14.8 * CLHEP::mm);
// FH10
add_FH(10, aDzMap, 10 * CLHEP::mm, 18 * CLHEP::mm);
// FH11
add_FH(11, aDzMap, 8 * CLHEP::mm, 17 * CLHEP::mm);
// FH12
add_FH(12, aDzMap, 7 * CLHEP::mm, 17 * CLHEP::mm);
aDzMap.push_back(std::make_pair("Steel_case", 29 * CLHEP::mm));
// AHCAL
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 50.0 * CLHEP::cm));
for (int l = 0; l < 39; l++) {
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.5 * CLHEP::cm));
aDzMap.push_back(std::make_pair("AHCAL_SiPM_2x2HUB", 0.));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 0.5 * CLHEP::cm));
}
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 1.1 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 1.1 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.5 * CLHEP::cm));
aDzMap.push_back(std::make_pair("AHCAL_SiPM_2x2HUB", 0.));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 0.5 * CLHEP::cm));
}
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction1.hh"
#include "DetectorConstruction0.hh"
#include "CLHEP/Units/SystemOfUnits.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction1(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
// map means: position this material starting at z, where:
// z += <second>
// z = z0+ 0.5 * thickness[<first>]
// first define beamline elements
// WChambUpstream
// world (and beam) starts at -45 m
aDzMap.push_back(std::make_pair("DWC", 12.2825 * CLHEP::m)); // at -32.7175 m
aDzMap.push_back(std::make_pair("CK3", 0.0 * CLHEP::m)); // at -30.69 m
aDzMap.push_back(std::make_pair("DWC", 56.2 * CLHEP::cm)); // at -30.073 cm
aDzMap.push_back(std::make_pair("DWC", 101.5 * CLHEP::cm)); // at -2900.3 cm
aDzMap.push_back(std::make_pair("Scintillator_thin", 23.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 13.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 13.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 103.8 * CLHEP::cm));
aDzMap.push_back(std::make_pair("DWC", 34.8 * CLHEP::cm)); // at -2700.5 cm
// HaloCounters not implemented (as offset in X or Y)
// WChambDown
aDzMap.push_back(std::make_pair("DWC", 18.15 * CLHEP::m)); // at -880 cm
aDzMap.push_back(std::make_pair("DWC", 7.145 * CLHEP::m)); // at -160 cm
// S5
aDzMap.push_back(std::make_pair("Scintillator", 1.354 * CLHEP::m));
// S6
aDzMap.push_back(std::make_pair("Scintillator", 14 * CLHEP::cm));
// next use already defined HGCal configuration
DetectorConstruction0(aDzMap, aViewpoint);
}
@@ -0,0 +1,38 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction2.hh"
#include "CLHEP/Units/SystemOfUnits.h"
void DetectorConstruction2(std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
aViewpoint = 0;
aDzMap.push_back(std::make_pair("PCB", 45 * CLHEP::m));
aDzMap.push_back(std::make_pair("Si_wafer", 0.));
aDzMap.push_back(std::make_pair("Kapton_layer", 0.3 * CLHEP::mm));
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.));
aDzMap.push_back(std::make_pair("Cu_absorber_EE", 0.));
}
@@ -0,0 +1,196 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "EventAction.hh"
#include "SiPMHit.hh"
#include "SiliconPixelHit.hh"
#include "G4Event.hh"
#include "G4SDManager.hh"
#include "G4GenericMessenger.hh"
#include "g4root.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction() : G4UserEventAction() { DefineCommands(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event *) {
fPrimariesPDG.clear();
fPrimariesEnergy.clear();
fPrimariesX.clear();
fPrimariesY.clear();
fPrimariesZ.clear();
fSiHitsID.clear();
fSiHitsX.clear();
fSiHitsY.clear();
fSiHitsZ.clear();
fSiHitsEdep.clear();
fSiHitsEdepNonIonising.clear();
fSiHitsTOA.clear();
fSiHitsTOAlast.clear();
fSiHitsType.clear();
fSiPMhitsID.clear();
fSiPMhitsX.clear();
fSiPMhitsY.clear();
fSiPMhitsZ.clear();
fSiPMhitsEdep.clear();
fSiPMhitsEdepNonIonising.clear();
fSiPMhitsTOA.clear();
fSiPMhitsType.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event *event) {
// sanity check
if (event->GetNumberOfPrimaryVertex() == 0)
return;
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->FillNtupleIColumn(0, event->GetEventID());
// fill for all primary input particles
for (G4int iVertex = 0; iVertex < event->GetNumberOfPrimaryVertex();
iVertex++) {
auto vertex = event->GetPrimaryVertex(iVertex);
fPrimariesX.push_back(vertex->GetX0() / CLHEP::cm);
fPrimariesY.push_back(vertex->GetY0() / CLHEP::cm);
fPrimariesZ.push_back(vertex->GetZ0() / CLHEP::cm);
for (G4int iParticle = 0; iParticle < vertex->GetNumberOfParticle();
iParticle++) {
auto particle = vertex->GetPrimary(iParticle);
fPrimariesPDG.push_back(particle->GetPDGcode());
fPrimariesEnergy.push_back(particle->GetTotalEnergy() / CLHEP::GeV);
}
}
auto hce = event->GetHCofThisEvent();
auto sdManager = G4SDManager::GetSDMpointer();
G4int collId;
// HGCAL EE + FH
collId = sdManager->GetCollectionID("SiliconPixelHitCollection");
auto hc = hce->GetHC(collId);
if (!hc)
return;
double esumHGCAL = 0;
double cogzHGCAL = 0;
int NhitsHGCAL = 0;
for (unsigned int i = 0; i < hc->GetSize(); ++i) {
auto hit = static_cast<SiliconPixelHit *>(hc->GetHit(i));
hit->Digitise(fHitTimeCut / CLHEP::ns, fToaThreshold / CLHEP::keV);
if (hit->isValidHit()) {
fSiHitsID.push_back(hit->ID());
fSiHitsX.push_back(hit->GetX());
fSiHitsY.push_back(hit->GetY());
fSiHitsZ.push_back(hit->GetZ());
fSiHitsEdep.push_back(hit->GetEdep());
fSiHitsEdepNonIonising.push_back(hit->GetEdepNonIonizing());
fSiHitsTOA.push_back(hit->GetTOA());
fSiHitsTOAlast.push_back(hit->GetLastTOA());
fSiHitsType.push_back(0);
NhitsHGCAL++;
esumHGCAL += hit->GetEdep() * CLHEP::keV / CLHEP::MeV;
cogzHGCAL += hit->GetZ() * hit->GetEdep();
}
}
if (esumHGCAL > 0)
cogzHGCAL /= esumHGCAL;
analysisManager->FillNtupleDColumn(23, esumHGCAL / CLHEP::GeV);
analysisManager->FillNtupleDColumn(24, cogzHGCAL);
analysisManager->FillNtupleIColumn(25, NhitsHGCAL);
// AHCAL
collId = sdManager->GetCollectionID("SiPMHitCollection");
hc = hce->GetHC(collId);
if (!hc)
return;
double esumAHCAL = 0;
double cogzAHCAL = 0;
int NhitsAHCAL = 0;
for (unsigned int i = 0; i < hc->GetSize(); ++i) {
auto hit = static_cast<SiPMHit *>(hc->GetHit(i));
hit->Digitise(-1, 0);
if (hit->isValidHit()) {
fSiPMhitsID.push_back(hit->ID());
fSiPMhitsX.push_back(hit->GetX());
fSiPMhitsY.push_back(hit->GetY());
fSiPMhitsZ.push_back(hit->GetZ());
fSiPMhitsEdep.push_back(hit->GetEdep());
fSiPMhitsEdepNonIonising.push_back(hit->GetEdepNonIonizing());
fSiPMhitsTOA.push_back(hit->GetTOA());
fSiPMhitsType.push_back(1);
NhitsAHCAL++;
esumAHCAL += hit->GetEdep() * CLHEP::keV / CLHEP::MeV;
cogzAHCAL += hit->GetZ() * hit->GetEdep();
}
}
if (esumAHCAL > 0)
cogzAHCAL /= esumAHCAL;
analysisManager->FillNtupleDColumn(26, esumAHCAL / CLHEP::GeV);
analysisManager->FillNtupleDColumn(27, cogzAHCAL);
analysisManager->FillNtupleIColumn(28, NhitsAHCAL);
analysisManager->AddNtupleRow();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::DefineCommands() {
fMessenger = new G4GenericMessenger(this, "/HGCalTestbeam/hits/",
"Primary generator control");
// time cut command
auto &timeCutCmd = fMessenger->DeclarePropertyWithUnit(
"timeCut", "ns", fHitTimeCut,
"Size of time window for hit digitalisation");
timeCutCmd.SetParameterName("timeCut", true);
timeCutCmd.SetRange("timeCut>=-1");
timeCutCmd.SetDefaultValue("-1");
// toa threshold command
auto &toaThresholdCmd = fMessenger->DeclarePropertyWithUnit(
"toaThreshold", "keV", fToaThreshold, "Threshold for TOA activation");
toaThresholdCmd.SetParameterName("toaThreshold", true);
toaThresholdCmd.SetRange("toaThreshold>=0");
toaThresholdCmd.SetDefaultValue("0");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,78 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "FTFPCMS_BERT_EMM.hh"
#include "CMSEmStandardPhysicsHcal.hh"
#include "G4DecayPhysics.hh"
#include "G4EmExtraPhysics.hh"
#include "G4HadronElasticPhysics.hh"
#include "G4IonPhysics.hh"
#include "G4NeutronTrackingCut.hh"
#include "G4StoppingPhysics.hh"
#include "G4HadronPhysicsFTFP_BERT.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
FTFPCMS_BERT_EMM::FTFPCMS_BERT_EMM(G4int ver) {
defaultCutValue = 0.7 * CLHEP::mm;
SetVerboseLevel(ver);
G4cout << "You are using "
<< "FTFP_BERT_EMM " << G4endl;
// EM Physics
RegisterPhysics(new CMSEmStandardPhysicsHcal(ver));
// Synchroton Radiation & GN Physics
RegisterPhysics(new G4EmExtraPhysics(ver));
// Decays
RegisterPhysics(new G4DecayPhysics(ver));
// Hadron Elastic scattering
RegisterPhysics(new G4HadronElasticPhysics(ver));
RegisterPhysics(new G4HadronPhysicsFTFP_BERT(ver));
// Stopping Physics
RegisterPhysics(new G4StoppingPhysics(ver));
// Ion Physics
RegisterPhysics(new G4IonPhysics(ver));
// Neutron tracking cut
RegisterPhysics(new G4NeutronTrackingCut(ver));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
FTFPCMS_BERT_EMM::~FTFPCMS_BERT_EMM() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void FTFPCMS_BERT_EMM::SetCuts() { SetCutsWithDefault(); }
@@ -0,0 +1,840 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "HGCalTBMaterials.hh"
#include "G4Box.hh"
#include "G4Colour.hh"
#include "G4Element.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4PVPlacement.hh"
#include "G4RotationMatrix.hh"
#include "G4SubtractionSolid.hh"
#include "G4ThreeVector.hh"
#include "G4Tubs.hh"
#include "G4VisAttributes.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4SubtractionSolid *HexagonSolid(G4String aName, G4double aCellThickness,
G4double aCellSideLength) {
G4double fullCcellX = (2.) * aCellSideLength;
G4double fullCellY = std::sqrt(3.) * aCellSideLength;
G4Box *solidFullcell = new G4Box(aName, // its aName
0.5 * fullCcellX, 0.5 * fullCellY,
0.5 * aCellThickness); // its size
G4double deltaXDash = aCellSideLength;
G4double deltaYDash = std::sqrt(3) / 4 * aCellSideLength;
G4Box *solidCutcell = new G4Box(aName, // its aName
0.5 * deltaXDash, 0.5 * (deltaYDash),
1. * aCellThickness); // its size
G4double deltaTheta[4] = {30. * CLHEP::deg, 150. * CLHEP::deg, 210. * CLHEP::deg, 330. * CLHEP::deg};
G4double deltaThetaRot[4] = {60. * CLHEP::deg, 120. * CLHEP::deg, 240 * CLHEP::deg, 300 * CLHEP::deg};
G4double delta = std::sqrt(3) / 2 * aCellSideLength + deltaYDash / 2;
G4RotationMatrix *rot = new G4RotationMatrix;
rot->rotateZ(deltaThetaRot[0]);
std::vector<G4SubtractionSolid *> subtracted;
subtracted.push_back(
new G4SubtractionSolid("cellSubtracted", solidFullcell, solidCutcell, rot,
G4ThreeVector(std::cos(deltaTheta[0]) * delta,
std::sin(deltaTheta[0]) * delta, 0.)));
for (int i = 1; i < 4; i++) {
rot->rotateZ(-deltaThetaRot[i - 1]);
rot->rotateZ(deltaThetaRot[i]);
subtracted.push_back(new G4SubtractionSolid(
"cellSubtracted", subtracted[i - 1], solidCutcell, rot,
G4ThreeVector(std::cos(deltaTheta[i]) * delta, std::sin(deltaTheta[i]) * delta,
0.)));
}
delete rot;
return subtracted[3];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LogicalVolume *HexagonLogical(G4String aName, G4double aCellThickness,
G4double aCellSideLength,
G4Material *aMaterial) {
return new G4LogicalVolume(
HexagonSolid(aName, aCellThickness, aCellSideLength), // its solid
aMaterial, // its aMaterial
aName); // its aName
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineMaterials() {
/***** Definition of all available materials *****/
// Get nist aMaterial manager
G4NistManager *nist = G4NistManager::Instance();
fMatVacuum = nist->FindOrBuildMaterial("G4_Galactic");
fMatAIR = nist->FindOrBuildMaterial("G4_AIR");
fMatAr = nist->FindOrBuildMaterial("G4_Ar");
fMatAl = nist->FindOrBuildMaterial("G4_Al");
fMatFe = nist->FindOrBuildMaterial("G4_Fe");
fMatGlass = nist->FindOrBuildMaterial("G4_GLASS_PLATE");
fMatPb = nist->FindOrBuildMaterial("G4_Pb");
fMatCu = nist->FindOrBuildMaterial("G4_Cu");
fMatW = nist->FindOrBuildMaterial("G4_W");
fMatSi = nist->FindOrBuildMaterial("G4_Si");
fMatAu = nist->FindOrBuildMaterial("G4_Au");
fMatQuartz = nist->FindOrBuildMaterial("G4_SILICON_DIOXIDE");
fMatC = nist->FindOrBuildMaterial("G4_C");
fMatH = nist->FindOrBuildMaterial("G4_H");
fMatO = nist->FindOrBuildMaterial("G4_O");
fMatMn = nist->FindOrBuildMaterial("G4_Mn");
fMatCr = nist->FindOrBuildMaterial("G4_Cr");
fMatNi = nist->FindOrBuildMaterial("G4_Ni");
fMatPolyethylene = nist->FindOrBuildMaterial("G4_POLYETHYLENE");
fMatCl = nist->FindOrBuildMaterial("G4_Cl");
fMatF = nist->FindOrBuildMaterial("G4_F");
// AHCAL SiPMs
G4double a = 1.01 * CLHEP::g / CLHEP::mole;
G4Element *elH = new G4Element("Hydrogen", "H2", 1., a);
a = 12.01 * CLHEP::g / CLHEP::mole;
G4Element *elC = new G4Element("Carbon", "C", 6., a);
G4double density = 1.032 * CLHEP::g / CLHEP::cm3;
fMatPolystyrene = new G4Material("Polystyrene", density, 2);
fMatPolystyrene->AddElement(elC, 19);
fMatPolystyrene->AddElement(elH, 21);
// CuW alloy: 60% Cu, 40% W in mass
G4double CuFracInCuW = 0.75;
fMatCuW = new G4Material("CuW", 14.979 * CLHEP::g / CLHEP::cm3, 2);
fMatCuW->AddMaterial(fMatCu, CuFracInCuW);
fMatCuW->AddMaterial(fMatW, 1 - CuFracInCuW);
// PCB aMaterial
fMatPCB = new G4Material("PCB", 1.7 * CLHEP::g / CLHEP::cm3, 4);
fMatPCB->AddMaterial(fMatC, 0.13232243);
fMatPCB->AddMaterial(fMatH, 0.032572448);
fMatPCB->AddMaterial(fMatO, 0.48316123);
fMatPCB->AddMaterial(fMatSi, 0.35194389);
// Kapton aMaterial
fMatKAPTON = new G4Material("Kapton", 1.11 * CLHEP::g / CLHEP::cm3, 3);
fMatKAPTON->AddMaterial(fMatC, 0.59985105);
fMatKAPTON->AddMaterial(fMatH, 0.080541353);
fMatKAPTON->AddMaterial(fMatO, 0.31960759);
// steel
fMatSteel = new G4Material("StainlessSteel", 8.02 * CLHEP::g / CLHEP::cm3, 5);
fMatSteel->AddMaterial(fMatFe, 0.6996);
fMatSteel->AddMaterial(fMatC, 0.0004);
fMatSteel->AddMaterial(fMatMn, 0.01);
fMatSteel->AddMaterial(fMatCr, 0.19);
fMatSteel->AddMaterial(fMatNi, 0.1);
// Scintillator aMaterial
fMatScintillator = new G4Material("Scintillator", 1.032 * CLHEP::g / CLHEP::cm3, 2);
fMatScintillator->AddMaterial(fMatC, 0.91512109);
fMatScintillator->AddMaterial(fMatH, 0.084878906);
// DWC gas
fMatArCO2 = new G4Material("ArCO2", 1.729 * CLHEP::mg / CLHEP::cm3, 3);
fMatArCO2->AddMaterial(fMatAr, 0.475815);
fMatArCO2->AddMaterial(fMatC, 0.14306133);
fMatArCO2->AddMaterial(fMatO, 0.38112367);
fMatFreon = new G4Material("Freon-12", 4.93 * CLHEP::mg / CLHEP::cm3, 3);
fMatFreon->AddMaterial(fMatC, 0.099340816);
fMatFreon->AddMaterial(fMatCl, 0.58640112);
fMatFreon->AddMaterial(fMatF, 0.31425807);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::SetEventDisplayColorScheme() {
G4VisAttributes *visAttributes;
visAttributes = new G4VisAttributes(G4Colour(.0, 0.0, 0.0));
visAttributes->SetVisibility(false);
fSiWaferLogical->SetVisAttributes(visAttributes);
visAttributes = new G4VisAttributes(G4Colour(.3, 0.3, 0.3, 0.2));
visAttributes->SetVisibility(true);
fSiPixelLogical->SetVisAttributes(visAttributes);
visAttributes = new G4VisAttributes(G4Colour(0.4, 0.4, 0.4, 0.01));
visAttributes->SetVisibility(false);
fCuWbaseplateLogical->SetVisAttributes(visAttributes);
fCuWbaseplate550umLogical->SetVisAttributes(visAttributes);
fCuWbaseplate610umLogical->SetVisAttributes(visAttributes);
fCuWbaseplate710umLogical->SetVisAttributes(visAttributes);
fCuBaseplateLogical->SetVisAttributes(visAttributes);
fCuBaseplate25umLogical->SetVisAttributes(visAttributes);
fCuBaseplate175umLogical->SetVisAttributes(visAttributes);
fPCBbaseplateLogical->SetVisAttributes(visAttributes);
fPCBbaseplateThinLogical->SetVisAttributes(visAttributes);
fKaptonLayerLogical->SetVisAttributes(visAttributes);
fAlCaseLogical->SetVisAttributes(visAttributes);
fAlCaseThickLogical->SetVisAttributes(visAttributes);
fSteelCaseLogical->SetVisAttributes(visAttributes);
fSteelCaseThickLogical->SetVisAttributes(visAttributes);
fPbAbsorberEElogical->SetVisAttributes(visAttributes);
fFeAbsorberEElogical->SetVisAttributes(visAttributes);
fCuAbsorberEElogical->SetVisAttributes(visAttributes);
fWabsorberEElogical->SetVisAttributes(visAttributes);
fW2mmAbsorberEEDESY2018Logical->SetVisAttributes(visAttributes);
fW4mmAbsorberEEDESY2018Logical->SetVisAttributes(visAttributes);
fCuAbsorberFHlogical->SetVisAttributes(visAttributes);
fFeAbsorberFHlogical->SetVisAttributes(visAttributes);
fAHCALSiPMlogical->SetVisAttributes(visAttributes);
fAHCALSiPM2x2HUBlogical->SetVisAttributes(visAttributes);
fAlAbsorberAHCALlogical->SetVisAttributes(visAttributes);
fPCBAHCALlogical->SetVisAttributes(visAttributes);
fFeAbsorberAHCALlogical->SetVisAttributes(visAttributes);
fScintillatorLogical->SetVisAttributes(visAttributes);
fScintillatorThinLogical->SetVisAttributes(visAttributes);
fMCPlogical->SetVisAttributes(visAttributes);
fCK3logical->SetVisAttributes(visAttributes);
fDWClogical->SetVisAttributes(visAttributes);
fDWCgasLogical->SetVisAttributes(visAttributes);
fAlChipLogical->SetVisAttributes(visAttributes);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HGCalTBMaterials::HGCalTBMaterials() {
DefineMaterials();
DefineSiWaferAndCells();
DefineHGCalBaseplates();
DefineHGCalCases();
DefineHGCalEEAbsorbers();
DefineHGCalFHAbsorbers();
DefineAHCALSiPM();
DefineAHCALAbsorbers();
DefineBeamLineElements();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineSiWaferAndCells() {
/***** Definition of silicon (wafer) sensors *****/
// 300 microns thickness only
fSiPixelSideLength = 0.6496345 * CLHEP::cm;
fSiWaferThickness = 0.3 * CLHEP::mm;
fAlpha = 60. / 180. * CLHEP::pi;
fSiWaferSideLength = 11 * fSiPixelSideLength;
fSiWaferLogical = HexagonLogical("Si_wafer", fSiWaferThickness,
fSiWaferSideLength, fMatAIR);
// Silicon pixel setups
double dx = 2 * std::sin(fAlpha) * fSiPixelSideLength;
double dy = fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
fSiPixelLogical =
HexagonLogical("SiCell", fSiWaferThickness, fSiPixelSideLength, fMatSi);
int index = 1;
int nRows[11] = {7, 6, 7, 6, 5, 6, 5, 4, 5, 4, 3};
for (int nC = 0; nC < 11; nC++) {
for (int middle_index = 0; middle_index < nRows[nC]; middle_index++) {
new G4PVPlacement(
0,
G4ThreeVector(dy * (middle_index - nRows[nC] / 2. + 0.5), nC * dx / 2,
0.),
fSiPixelLogical, "SiCell", fSiWaferLogical, false, index++, true);
if (nC <= 0)
continue;
new G4PVPlacement(
0,
G4ThreeVector(dy * (middle_index - nRows[nC] / 2. + 0.5),
-nC * dx / 2, 0.),
fSiPixelLogical, "SiCell", fSiWaferLogical, false, index++, true);
}
}
fThicknessMap["Si_wafer"] = fSiWaferThickness;
fLogicalVolumeMap["Si_wafer"] = fSiWaferLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalBaseplates() {
/***** Definition of all baseplates *****/
// CuW
G4double CuWbaseplateThickness = 1.2 * CLHEP::mm;
G4double CuWbaseplatesideLength = 11 * fSiPixelSideLength;
fCuWbaseplateLogical = HexagonLogical("CuW_baseplate", CuWbaseplateThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate"] = CuWbaseplateThickness;
fLogicalVolumeMap["CuW_baseplate"] = fCuWbaseplateLogical;
G4double CuWbaseplate550umthickness = 0.55 * CLHEP::mm;
fCuWbaseplate550umLogical =
HexagonLogical("CuW_baseplate_550um", CuWbaseplate550umthickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_550um"] = CuWbaseplate550umthickness;
fLogicalVolumeMap["CuW_baseplate_550um"] = fCuWbaseplate550umLogical;
G4double CuWbaseplate610umThickness = 0.61 * CLHEP::mm;
fCuWbaseplate610umLogical =
HexagonLogical("CuW_baseplate_610um", CuWbaseplate610umThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_610um"] = CuWbaseplate610umThickness;
fLogicalVolumeMap["CuW_baseplate_610um"] = fCuWbaseplate610umLogical;
G4double CuWbaseplate710umThickness = 0.71 * CLHEP::mm;
fCuWbaseplate710umLogical =
HexagonLogical("CuW_baseplate_710um", CuWbaseplate710umThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_710um"] = CuWbaseplate710umThickness;
fLogicalVolumeMap["CuW_baseplate_710um"] = fCuWbaseplate710umLogical;
// Cu
G4double CuBaseplateThickness = 1.2 * CLHEP::mm;
G4double CuBaseplatesideLength = 11 * fSiPixelSideLength;
fCuBaseplateLogical = HexagonLogical("Cu_baseplate", CuBaseplateThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate"] = CuBaseplateThickness;
fLogicalVolumeMap["Cu_baseplate"] = fCuBaseplateLogical;
G4double CuBaseplate25umThickness = 0.025 * CLHEP::mm;
fCuBaseplate25umLogical =
HexagonLogical("Cu_baseplate_25um", CuBaseplate25umThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate_25um"] = CuBaseplate25umThickness;
fLogicalVolumeMap["Cu_baseplate_25um"] = fCuBaseplate25umLogical;
G4double CuBaseplate175umThickness = 0.175 * CLHEP::mm;
fCuBaseplate175umLogical =
HexagonLogical("Cu_baseplate_175um", CuBaseplate175umThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate_175um"] = CuBaseplate175umThickness;
fLogicalVolumeMap["Cu_baseplate_175um"] = fCuBaseplate175umLogical;
// PCB
G4double PCBbaseplateThickness = 1.3 * CLHEP::mm;
G4double PCBbaseplateSideLength = 11 * fSiPixelSideLength;
fPCBbaseplateLogical = HexagonLogical("PCB", PCBbaseplateThickness,
PCBbaseplateSideLength, fMatPCB);
fThicknessMap["PCB"] = PCBbaseplateThickness;
fLogicalVolumeMap["PCB"] = fPCBbaseplateLogical;
G4double PCBbaseplateThinThickness = 1.2 * CLHEP::mm;
fPCBbaseplateThinLogical = HexagonLogical(
"PCB_thin", PCBbaseplateThinThickness, PCBbaseplateSideLength, fMatPCB);
fThicknessMap["PCB_thin"] = PCBbaseplateThinThickness;
fLogicalVolumeMap["PCB_thin"] = fPCBbaseplateThinLogical;
// Kapton layer
G4double KaptonLayerThickness = 0.075 * CLHEP::mm;
G4double KaptonLayerSideLength = 11 * fSiPixelSideLength;
fKaptonLayerLogical = HexagonLogical("Kapton_layer", KaptonLayerThickness,
KaptonLayerSideLength, fMatKAPTON);
fThicknessMap["Kapton_layer"] = KaptonLayerThickness;
fLogicalVolumeMap["Kapton_layer"] = fKaptonLayerLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalCases() {
G4double AlCaseThickness = 2.1 * CLHEP::mm;
G4double AlCaseXY = 40 * CLHEP::cm;
G4Box *AlCaseSolid = new G4Box("Al_case", 0.5 * AlCaseXY, 0.5 * AlCaseXY,
0.5 * AlCaseThickness);
fAlCaseLogical = new G4LogicalVolume(AlCaseSolid, fMatAl, "Al_case");
fThicknessMap["Al_case"] = AlCaseThickness;
fLogicalVolumeMap["Al_case"] = fAlCaseLogical;
G4double AlCaseThickThickness = 5 * CLHEP::mm;
G4Box *AlCaseThickSolid =
new G4Box("Al_case_thick", 0.5 * AlCaseXY, 0.5 * AlCaseXY,
0.5 * AlCaseThickThickness);
fAlCaseThickLogical =
new G4LogicalVolume(AlCaseThickSolid, fMatAl, "Al_case_thick");
fThicknessMap["Al_case_thick"] = AlCaseThickThickness;
fLogicalVolumeMap["Al_case_thick"] = fAlCaseThickLogical;
G4double SteelCaseThickness = 9 * CLHEP::mm;
G4double SteelCaseXY = 60 * CLHEP::cm;
G4Box *SteelCaseSolid =
new G4Box("Steel_case", 0.5 * SteelCaseXY, 0.5 * SteelCaseXY,
0.5 * SteelCaseThickness);
fSteelCaseLogical = new G4LogicalVolume(SteelCaseSolid, fMatFe, "Steel_case");
fThicknessMap["Steel_case"] = SteelCaseThickness;
fLogicalVolumeMap["Steel_case"] = fSteelCaseLogical;
G4double SteelCaseThickThickness = 40 * CLHEP::mm;
G4Box *SteelCaseThickSolid =
new G4Box("Steel_case_thick", 0.5 * SteelCaseXY, 0.5 * SteelCaseXY,
0.5 * SteelCaseThickThickness);
fSteelCaseThickLogical =
new G4LogicalVolume(SteelCaseThickSolid, fMatFe, "Steel_case_thick");
fThicknessMap["Steel_case_thick"] = SteelCaseThickThickness;
fLogicalVolumeMap["Steel_case_thick"] = fSteelCaseThickLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalEEAbsorbers() {
// defintion of absorber plates in the EE part
G4double PbAbsorberEEthickness = 4.9 * CLHEP::mm;
G4double PbAbsorberEExy = 30 * CLHEP::cm;
G4Box *PbAbsorberEEsolid =
new G4Box("Pb_absorber_EE", 0.5 * PbAbsorberEExy, 0.5 * PbAbsorberEExy,
0.5 * PbAbsorberEEthickness);
fPbAbsorberEElogical =
new G4LogicalVolume(PbAbsorberEEsolid, fMatPb, "Pb_absorber_EE");
fThicknessMap["Pb_absorber_EE"] = PbAbsorberEEthickness;
fLogicalVolumeMap["Pb_absorber_EE"] = fPbAbsorberEElogical;
G4double FeAbsorberEEthickness = 0.3 * CLHEP::mm;
G4double FeAbsorberEExy = 30 * CLHEP::cm;
G4Box *FeAbsorberEEsolid =
new G4Box("Fe_absorber_EE", 0.5 * FeAbsorberEExy, 0.5 * FeAbsorberEExy,
0.5 * FeAbsorberEEthickness);
fFeAbsorberEElogical =
new G4LogicalVolume(FeAbsorberEEsolid, fMatFe, "Fe_absorber_EE");
fThicknessMap["Fe_absorber_EE"] = FeAbsorberEEthickness;
fLogicalVolumeMap["Fe_absorber_EE"] = fFeAbsorberEElogical;
G4double CuAbsorberEEthickness = 6 * CLHEP::mm;
G4double CuAbsorberEExy = 30 * CLHEP::cm;
G4Box *CuAbsorberEEsolid =
new G4Box("Cu_absorber_EE", 0.5 * CuAbsorberEExy, 0.5 * CuAbsorberEExy,
0.5 * CuAbsorberEEthickness);
fCuAbsorberEElogical =
new G4LogicalVolume(CuAbsorberEEsolid, fMatCu, "Cu_absorber_EE");
fThicknessMap["Cu_absorber_EE"] = CuAbsorberEEthickness;
fLogicalVolumeMap["Cu_absorber_EE"] = fCuAbsorberEElogical;
G4double WabsorberEEthickness = 2.8 * CLHEP::mm;
G4double WabsorberEExy = 30 * CLHEP::cm;
G4Box *WabsorberEEsolid =
new G4Box("W_absorber_EE", 0.5 * WabsorberEExy, 0.5 * WabsorberEExy,
0.5 * WabsorberEEthickness);
fWabsorberEElogical =
new G4LogicalVolume(WabsorberEEsolid, fMatW, "W_absorber_EE");
fThicknessMap["W_absorber_EE"] = WabsorberEEthickness;
fLogicalVolumeMap["W_absorber_EE"] = fWabsorberEElogical;
G4double W2mmAbsorberEEDESY2018thickness = 2. * CLHEP::mm;
G4double W2mmAbsorberEEDESY2018xy = 15 * CLHEP::cm;
G4Box *W2mmAbsorberEEDESY2018solid = new G4Box(
"W_2mm_absorber_EE_DESY2018", 0.5 * W2mmAbsorberEEDESY2018xy,
0.5 * W2mmAbsorberEEDESY2018xy, 0.5 * W2mmAbsorberEEDESY2018thickness);
fW2mmAbsorberEEDESY2018Logical = new G4LogicalVolume(
W2mmAbsorberEEDESY2018solid, fMatW, "W_2mm_absorber_EE_DESY2018");
fThicknessMap["W_2mm_absorber_EE_DESY2018"] = W2mmAbsorberEEDESY2018thickness;
fLogicalVolumeMap["W_2mm_absorber_EE_DESY2018"] =
fW2mmAbsorberEEDESY2018Logical;
G4double W4mmAbsorberEEDESY2018thickness = 4. * CLHEP::mm;
G4double W4mmAbsorberEEDESY2018xy = 15 * CLHEP::cm;
G4Box *W4mmAbsorberEEDESY2018solid = new G4Box(
"W_4mm_absorber_EE_DESY2018", 0.5 * W4mmAbsorberEEDESY2018xy,
0.5 * W4mmAbsorberEEDESY2018xy, 0.5 * W4mmAbsorberEEDESY2018thickness);
fW4mmAbsorberEEDESY2018Logical = new G4LogicalVolume(
W4mmAbsorberEEDESY2018solid, fMatW, "W_4mm_absorber_EE_DESY2018");
fThicknessMap["W_4mm_absorber_EE_DESY2018"] = W4mmAbsorberEEDESY2018thickness;
fLogicalVolumeMap["W_4mm_absorber_EE_DESY2018"] =
fW4mmAbsorberEEDESY2018Logical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalFHAbsorbers() {
// defintion of absorber plates in the FH part
G4double CuAbsorberFHthickness = 6 * CLHEP::mm;
G4double CuAbsorberFHxy = 50 * CLHEP::cm;
G4Box *CuAbsorberFHsolid =
new G4Box("Cu_absorber_FH", 0.5 * CuAbsorberFHxy, 0.5 * CuAbsorberFHxy,
0.5 * CuAbsorberFHthickness);
fCuAbsorberFHlogical =
new G4LogicalVolume(CuAbsorberFHsolid, fMatCu, "Cu_absorber_FH");
fThicknessMap["Cu_absorber_FH"] = CuAbsorberFHthickness;
fLogicalVolumeMap["Cu_absorber_FH"] = fCuAbsorberFHlogical;
G4double FeAbsorberFHthickness = 40 * CLHEP::mm;
G4double FeAbsorberFHxy = 50 * CLHEP::cm;
G4Box *FeAbsorberFHsolid =
new G4Box("Fe_absorber_FH", 0.5 * FeAbsorberFHxy, 0.5 * FeAbsorberFHxy,
0.5 * FeAbsorberFHthickness);
fFeAbsorberFHlogical =
new G4LogicalVolume(FeAbsorberFHsolid, fMatFe, "Fe_absorber_FH");
fThicknessMap["Fe_absorber_FH"] = FeAbsorberFHthickness;
fLogicalVolumeMap["Fe_absorber_FH"] = fFeAbsorberFHlogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineAHCALSiPM() {
G4double AHCALSiPMthickness = 5.4 * CLHEP::mm;
fAHCALSiPMxy = 3 * CLHEP::cm;
fAHCALSiPMsolid = new G4Box("AHCAL_SiPM", 0.5 * fAHCALSiPMxy,
0.5 * fAHCALSiPMxy, 0.5 * AHCALSiPMthickness);
fAHCALSiPMlogical =
new G4LogicalVolume(fAHCALSiPMsolid, fMatPolystyrene, "AHCAL_SiPM");
fThicknessMap["AHCAL_SiPM"] = AHCALSiPMthickness;
fLogicalVolumeMap["AHCAL_SiPM"] = fAHCALSiPMlogical;
G4double AHCALSiPM2x2HUBxy = 2 * 12 * fAHCALSiPMxy + 0.01 * CLHEP::mm;
G4double AHCALSiPM2x2HUBthickness = AHCALSiPMthickness + 0.01 * CLHEP::mm;
G4Box *AHCALSiPM2x2HUBsolid =
new G4Box("AHCAL_SiPM_2x2HUB", 0.5 * AHCALSiPM2x2HUBxy,
0.5 * AHCALSiPM2x2HUBxy, 0.5 * AHCALSiPM2x2HUBthickness);
fAHCALSiPM2x2HUBlogical =
new G4LogicalVolume(AHCALSiPM2x2HUBsolid, fMatAIR, "AHCAL_SiPM_2x2HUB");
fThicknessMap["AHCAL_SiPM_2x2HUB"] = AHCALSiPM2x2HUBthickness;
fLogicalVolumeMap["AHCAL_SiPM_2x2HUB"] = fAHCALSiPM2x2HUBlogical;
int copy_counter = 0;
for (float _dx = -11.5; _dx <= 11.5; _dx = _dx + 1.)
for (float _dy = -11.5; _dy <= 11.5; _dy = _dy + 1.)
new G4PVPlacement(
0, G4ThreeVector(_dx * fAHCALSiPMxy, _dy * fAHCALSiPMxy, 0),
fAHCALSiPMlogical, "AHCAL_SiPM", fAHCALSiPM2x2HUBlogical, false,
copy_counter++, true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineAHCALAbsorbers() {
G4double AlAbsorberAHCALthickness = 1 * CLHEP::mm;
G4double AlAbsorberAHCALxy = 2 * 12 * fAHCALSiPMxy;
G4Box *AlAbsorberAHCALsolid =
new G4Box("Al_absorber_AHCAL", 0.5 * AlAbsorberAHCALxy,
0.5 * AlAbsorberAHCALxy, 0.5 * AlAbsorberAHCALthickness);
fAlAbsorberAHCALlogical =
new G4LogicalVolume(AlAbsorberAHCALsolid, fMatAl, "Al_absorber_AHCAL");
fThicknessMap["Al_absorber_AHCAL"] = AlAbsorberAHCALthickness;
fLogicalVolumeMap["Al_absorber_AHCAL"] = fAlAbsorberAHCALlogical;
G4double PCBAHCALthickness = 1.2 * CLHEP::mm;
G4double PCBAHCALxy = 2 * 12 * fAHCALSiPMxy;
G4Box *PCBAHCALsolid = new G4Box("PCB_AHCAL", 0.5 * PCBAHCALxy,
0.5 * PCBAHCALxy, 0.5 * PCBAHCALthickness);
fPCBAHCALlogical = new G4LogicalVolume(PCBAHCALsolid, fMatPCB, "PCB_AHCAL");
fThicknessMap["PCB_AHCAL"] = PCBAHCALthickness;
fLogicalVolumeMap["PCB_AHCAL"] = fPCBAHCALlogical;
G4double FeAbsorberAHCALthickness = 17 * CLHEP::mm;
G4double FeAbsorberAHCALx = 80.8 * CLHEP::cm;
G4double FeAbsorberAHCALy = 65.7 * CLHEP::cm;
G4Box *FeAbsorberAHCALsolid =
new G4Box("Fe_absorber_AHCAL", 0.5 * FeAbsorberAHCALx,
0.5 * FeAbsorberAHCALy, 0.5 * FeAbsorberAHCALthickness);
fFeAbsorberAHCALlogical =
new G4LogicalVolume(FeAbsorberAHCALsolid, fMatFe, "Fe_absorber_AHCAL");
fThicknessMap["Fe_absorber_AHCAL"] = FeAbsorberAHCALthickness;
fLogicalVolumeMap["Fe_absorber_AHCAL"] = fFeAbsorberAHCALlogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineBeamLineElements() {
/***** Definition of beam line elements *****/
// scintillators
G4double scintillatorThickness = 2 * 2 * CLHEP::cm;
G4double scintillatorXY = 2 * 9.5 * CLHEP::cm;
G4Box *scintillatorSolid =
new G4Box("Scintillator", 0.5 * scintillatorXY, 0.5 * scintillatorXY,
0.5 * scintillatorThickness);
fScintillatorLogical =
new G4LogicalVolume(scintillatorSolid, fMatScintillator, "Scintillator");
fThicknessMap["Scintillator"] = scintillatorThickness;
fLogicalVolumeMap["Scintillator"] = fScintillatorLogical;
G4double fScintillatorThinThickness = 1 * CLHEP::cm;
G4Box *fScintillatorThinSolid =
new G4Box("Scintillator_thin", 0.5 * scintillatorXY, 0.5 * scintillatorXY,
0.5 * fScintillatorThinThickness);
fScintillatorThinLogical = new G4LogicalVolume(
fScintillatorThinSolid, fMatScintillator, "Scintillator_thin");
fThicknessMap["Scintillator_thin"] = fScintillatorThinThickness;
fLogicalVolumeMap["Scintillator_thin"] = fScintillatorThinLogical;
// MCPs = quartz disks
G4double MCPthickness = 10 * CLHEP::mm;
G4double MCPradius = 2 * CLHEP::cm;
G4Tubs *MCPsolid =
new G4Tubs("MCP", 0., MCPradius, MCPthickness, 0, 360 * CLHEP::degree);
fMCPlogical = new G4LogicalVolume(MCPsolid, fMatQuartz, "MCP");
fThicknessMap["MCP"] = MCPthickness;
fLogicalVolumeMap["MCP"] = fMCPlogical;
// CK3
G4double CK3thickness = 2 * CLHEP::m;
G4double CK3radius = 8.35 * CLHEP::cm;
G4Tubs *CK3solid =
new G4Tubs("CK3", 0., CK3radius, 0.5 * CK3thickness, 0, 360 * CLHEP::degree);
fCK3logical = new G4LogicalVolume(CK3solid, fMatFreon, "CK3");
fThicknessMap["CK3"] = CK3thickness;
fLogicalVolumeMap["CK3"] = fCK3logical;
// Aluminium circle for testing of chip impact
G4double AlChipXY = 1 * CLHEP::cm;
G4double AlChipThickness = 0.89 * CLHEP::mm; // corresponds to 1% X0
G4Box *AlChipSolid = new G4Box("Al_chip", 0.5 * AlChipXY, 0.5 * AlChipXY,
0.5 * AlChipThickness);
fAlChipLogical = new G4LogicalVolume(AlChipSolid, fMatAl, "Al_chip");
fThicknessMap["Al_chip"] = AlChipThickness;
fLogicalVolumeMap["Al_chip"] = fAlChipLogical;
// DWC related aMaterial
G4double DWCthickness = 2 * 27.5 * CLHEP::mm;
G4double DWCxy = 2 * 11 * CLHEP::cm;
G4Box *DWCsolid =
new G4Box("DWC", 0.5 * DWCxy, 0.5 * DWCxy, 0.5 * DWCthickness);
fDWClogical = new G4LogicalVolume(DWCsolid, fMatAIR, "DWC");
fThicknessMap["DWC"] = DWCthickness;
fLogicalVolumeMap["DWC"] = fDWClogical;
// WChambGas
G4double DWCgasThickness = 2 * 22.5 * CLHEP::mm;
G4double DWCgasXY = 2 * 8.5 * CLHEP::cm;
G4Box *DWCgasSolid = new G4Box("DWC_gas", 0.5 * DWCgasXY, 0.5 * DWCgasXY,
0.5 * DWCgasThickness);
fDWCgasLogical = new G4LogicalVolume(DWCgasSolid, fMatArCO2, "DWC_gas");
new G4PVPlacement(0, G4ThreeVector(0, 0., 0.), fDWCgasLogical, "DWC_gas",
fDWClogical, false, 0, true);
G4VisAttributes *visAttributes = new G4VisAttributes(G4Colour(.0, 0.0, 0.0));
visAttributes->SetVisibility(false);
// WChambWindow
G4double DWCwindowThickness = 0.025 * CLHEP::mm;
G4double DWCwindowXY = 2 * 5.5 * CLHEP::cm;
G4Box *DWCwindowSolid =
new G4Box("DWC_window", 0.5 * DWCwindowXY, 0.5 * DWCwindowXY,
0.5 * DWCwindowThickness);
auto DWCwindowLogical =
new G4LogicalVolume(DWCwindowSolid, fMatKAPTON, "DWC_window");
DWCwindowLogical->SetVisAttributes(visAttributes);
new G4PVPlacement(
0, G4ThreeVector(0, 0., 27.5 * CLHEP::mm - DWCwindowThickness / 2.),
DWCwindowLogical, "DWC_window_0", fDWClogical, true, 0, true);
new G4PVPlacement(
0, G4ThreeVector(0, 0., -(27.5 * CLHEP::mm - DWCwindowThickness / 2.)),
DWCwindowLogical, "DWC_window_1", fDWClogical, true, 1, true);
G4RotationMatrix *rotation = new G4RotationMatrix();
rotation->rotateZ(90 * CLHEP::deg);
// WChambAl1
G4double DWCal1thickness = 2 * 2.5 * CLHEP::mm;
G4double DWCal1x = 2 * 8.25 * CLHEP::cm;
G4double DWCal1y = 2 * 2.75 * CLHEP::cm;
G4Box *DWCal1solid =
new G4Box("DWC_al1", 0.5 * DWCal1x, 0.5 * DWCal1y, 0.5 * DWCal1thickness);
auto DWCal1logical = new G4LogicalVolume(DWCal1solid, fMatAl, "DWC_al1");
DWCal1logical->SetVisAttributes(visAttributes);
new G4PVPlacement(0,
G4ThreeVector(0.5 * DWCal1y, 0.5 * DWCal1x,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_0", fDWClogical, true, 0, true);
new G4PVPlacement(rotation,
G4ThreeVector(-0.5 * DWCal1x, 0.5 * DWCal1y,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_1", fDWClogical, true, 1, true);
new G4PVPlacement(0,
G4ThreeVector(-0.5 * DWCal1y, -0.5 * DWCal1x,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_2", fDWClogical, true, 2, true);
new G4PVPlacement(rotation,
G4ThreeVector(0.5 * DWCal1x, -0.5 * DWCal1y,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_3", fDWClogical, true, 3, true);
new G4PVPlacement(
0,
G4ThreeVector(0.5 * DWCal1y, 0.5 * DWCal1x,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_4", fDWClogical, true, 4, true);
new G4PVPlacement(
rotation,
G4ThreeVector(-0.5 * DWCal1x, 0.5 * DWCal1y,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_5", fDWClogical, true, 5, true);
new G4PVPlacement(
0,
G4ThreeVector(-0.5 * DWCal1y, -0.5 * DWCal1x,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_6", fDWClogical, true, 6, true);
new G4PVPlacement(
rotation,
G4ThreeVector(0.5 * DWCal1x, -0.5 * DWCal1y,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_7", fDWClogical, true, 7, true);
// WChambAl2
G4double DWCal2thickness = 2 * 2.25 * CLHEP::cm;
G4double DWCal2x = 2 * 10.75 * CLHEP::cm;
G4double DWCal2y = 2 * 2.5 * CLHEP::mm;
G4Box *DWCal2solid =
new G4Box("DWC_al2", 0.5 * DWCal2x, 0.5 * DWCal2y, 0.5 * DWCal2thickness);
auto DWCal2logical = new G4LogicalVolume(DWCal2solid, fMatAl, "DWC_al2");
DWCal2logical->SetVisAttributes(visAttributes);
new G4PVPlacement(0, G4ThreeVector(0.5 * DWCal2y, 0.5 * DWCal2x, 0),
DWCal2logical, "DWC_al2_0", fDWClogical, true, 0, true);
new G4PVPlacement(rotation, G4ThreeVector(-0.5 * DWCal2x, 0.5 * DWCal2y, 0),
DWCal2logical, "DWC_al2_1", fDWClogical, true, 1, true);
new G4PVPlacement(0, G4ThreeVector(-0.5 * DWCal2y, -0.5 * DWCal2x, 0),
DWCal2logical, "DWC_al2_2", fDWClogical, true, 2, true);
new G4PVPlacement(rotation, G4ThreeVector(0.5 * DWCal2x, -0.5 * DWCal2y, 0),
DWCal2logical, "DWC_al2_3", fDWClogical, true, 3, true);
// WChambGasVet
G4double DWCgasVetThickness = 2 * 2.5 * CLHEP::mm;
G4double DWCgasVetX = 2 * 7.25 * CLHEP::cm;
G4double DWCgasVetY = 2 * 1.25 * CLHEP::cm;
G4Box *DWCgasVetSolid = new G4Box("DWC_gasVet", 0.5 * DWCgasVetX,
0.5 * DWCgasVetY, 0.5 * DWCgasVetThickness);
auto DWCgasVetLogical =
new G4LogicalVolume(DWCgasVetSolid, fMatPolyethylene, "DWC_gasVet");
DWCgasVetLogical->SetVisAttributes(visAttributes);
new G4PVPlacement(0,
G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_0", fDWCgasLogical, true, 0,
true);
new G4PVPlacement(rotation,
G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_1", fDWCgasLogical, true, 1,
true);
new G4PVPlacement(0,
G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_2", fDWCgasLogical, true, 2,
true);
new G4PVPlacement(rotation,
G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_3", fDWCgasLogical, true, 3,
true);
new G4PVPlacement(0, G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX, 0),
DWCgasVetLogical, "DWC_gasVet_4", fDWCgasLogical, true, 4,
true);
new G4PVPlacement(
rotation, G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY, 0),
DWCgasVetLogical, "DWC_gasVet_5", fDWCgasLogical, true, 5, true);
new G4PVPlacement(0, G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX, 0),
DWCgasVetLogical, "DWC_gasVet_6", fDWCgasLogical, true, 6,
true);
new G4PVPlacement(
rotation, G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY, 0),
DWCgasVetLogical, "DWC_gasVet_7", fDWCgasLogical, true, 7, true);
new G4PVPlacement(
0,
G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_8", fDWCgasLogical, true, 8, true);
new G4PVPlacement(
rotation,
G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_9", fDWCgasLogical, true, 9, true);
new G4PVPlacement(
0,
G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_10", fDWCgasLogical, true, 10, true);
new G4PVPlacement(
rotation,
G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_11", fDWCgasLogical, true, 11, true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::PlaceItemInLogicalVolume(std::string aName,
G4double &aZ0,
G4LogicalVolume *aLogicMother) {
if (aName.find("_DAISY") != std::string::npos) {
aName.resize(aName.find("_DAISY"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
double dx_ = 2 * std::sin(fAlpha) * 11 * fSiPixelSideLength;
double dy_ = 11 * fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
int nRows_[3] = {1, 2, 1};
for (int nC = 0; nC < 3; nC++) {
for (int middle_index = 0; middle_index < nRows_[nC]; middle_index++) {
new G4PVPlacement(
0,
G4ThreeVector(dy_ * (middle_index - nRows_[nC] / 2. + 0.5),
-nC * dx_ / 2, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
if (nC <= 0)
continue;
new G4PVPlacement(
0,
G4ThreeVector(dy_ * (middle_index - nRows_[nC] / 2. + 0.5),
+nC * dx_ / 2, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
}
}
aZ0 += fThicknessMap[aName];
} else if (aName.find("_SUMMER2017TRIPLET") != std::string::npos) {
aName.resize(aName.find("_SUMMER2017TRIPLET"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
double dx_ = 2 * std::sin(fAlpha) * 11 * fSiPixelSideLength;
double dy_ = 11 * fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
int nRows_[2] = {1, 2};
for (int nC = 0; nC < 2; nC++) {
new G4PVPlacement(0,
G4ThreeVector(-dy_ * (0 - nRows_[nC] / 2. + 0.5),
-nC * dx_ / 2,
aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
if (nC <= 0)
continue;
new G4PVPlacement(0,
G4ThreeVector(-dy_ * (0 - nRows_[nC] / 2. + 0.5),
+nC * dx_ / 2,
aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
}
aZ0 += fThicknessMap[aName];
} else if (aName.find("_rot30") != std::string::npos) {
aName.resize(aName.find("_rot30"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
G4RotationMatrix *rot = new G4RotationMatrix;
rot->rotateZ(30 * CLHEP::deg);
new G4PVPlacement(rot,
G4ThreeVector(0, 0, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
aZ0 += fThicknessMap[aName];
} else {
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
new G4PVPlacement(0, G4ThreeVector(0, 0, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
aZ0 += fThicknessMap[aName];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,230 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "PrimaryGeneratorAction.hh"
#include "PrimaryGeneratorMessenger.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4RunManager.hh"
#include "Randomize.hh"
#ifdef WITHROOT
#include "G4MTRunManager.hh"
#include "G4Run.hh"
#include "TFile.h"
#include "TTreeReader.h"
#include "TTreeReaderValue.h"
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction()
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr),
fEnvelopeBox(nullptr) {
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
// default particle kinematic
G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition *particle =
particleTable->FindParticle(particleName = "e+");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
fParticleGun->SetParticleEnergy(30. * CLHEP::GeV);
fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., 0.));
fMessenger = new PrimaryGeneratorMessenger(this);
#ifdef WITHROOT
if (fReadInputFile)
OpenInput();
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifdef WITHROOT
void PrimaryGeneratorAction::OpenInput() {
if (fInputFile != nullptr) {
delete fInputFile;
fInputFile = nullptr;
}
fInputFile = new TFile(fPathInputFile, "READ");
if (fInputFile == nullptr || fInputFile->IsZombie()) {
G4ExceptionDescription msg;
msg << "Input file '" << fPathInputFile << "' cannot be opened.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()", "WrongInputName",
FatalErrorInArgument, msg);
}
auto fileDirectory =
dynamic_cast<TDirectory *>(fInputFile->Get("VirtualDetector"));
if (fileDirectory == nullptr) {
G4ExceptionDescription msg;
msg << "Input file '" << fPathInputFile
<< "' does not contain 'VirtualDetector' directory.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"WrongInputDirectory", FatalErrorInArgument, msg);
}
fHgcalReader = new TTreeReader("HGCAL", fileDirectory);
fHgcalEventId = new TTreeReaderValue<Float_t>(*fHgcalReader, "EventID");
fHgcalPdgId = new TTreeReaderValue<Float_t>(*fHgcalReader, "PDGid");
fHgcalPosX = new TTreeReaderValue<Float_t>(*fHgcalReader, "x");
fHgcalPosY = new TTreeReaderValue<Float_t>(*fHgcalReader, "y");
fHgcalMomX = new TTreeReaderValue<Float_t>(*fHgcalReader, "Px");
fHgcalMomY = new TTreeReaderValue<Float_t>(*fHgcalReader, "Py");
fHgcalMomZ = new TTreeReaderValue<Float_t>(*fHgcalReader, "Pz");
return;
}
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
delete fParticleGun;
#ifdef WITHROOT
delete fInputFile;
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent) {
#ifdef WITHROOT
if (fReadInputFile) {
// get primary particles from input file
if (fInputFile == nullptr) {
OpenInput();
}
Float_t currentEventId = -1;
while (fHgcalReader->Next()) {
// First particle - set event ID
if (currentEventId == -1) {
currentEventId = **fHgcalEventId;
fEventCounter++;
// check if event should be ignored (is before the start position)
if (fEventCounter < fStartFromEvent)
continue;
} else {
// check if event is to be skipped
if (fEventCounter < fStartFromEvent) {
if (currentEventId != **fHgcalEventId)
currentEventId = -1;
continue;
} else {
// check if current particle belongs to the next event
if (currentEventId != **fHgcalEventId)
break;
}
}
auto vertex = new G4PrimaryVertex(
G4ThreeVector(**fHgcalPosX, **fHgcalPosY, 32.5 * CLHEP::mm), 0 * CLHEP::s);
auto particleDefinition =
G4ParticleTable::GetParticleTable()->FindParticle(**fHgcalPdgId);
auto particle = new G4PrimaryParticle(particleDefinition);
G4ThreeVector momentum(**fHgcalMomX, **fHgcalMomY, **fHgcalMomZ);
particle->SetMomentumDirection(momentum.unit());
particle->SetKineticEnergy(momentum.mag());
vertex->SetPrimary(particle);
anEvent->AddPrimaryVertex(vertex);
}
// if no particles are left - terminate run
if (fEventCounter >= fStartFromEvent &&
anEvent->GetNumberOfPrimaryVertex() == 0) {
G4ExceptionDescription msg;
msg << "Input file does not contain any more events (current event ID = "
<< anEvent->GetEventID() << ").\n";
msg << "Run will be aborted with " << anEvent->GetEventID()
<< " events processed.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"EndOfInputFile", JustWarning, msg);
G4RunManager::GetRunManager()->AbortRun();
}
// warn if this is the last event and some events are left in the file
// unprocessed
if (G4RunManager::GetRunManager()
->GetCurrentRun()
->GetNumberOfEventToBeProcessed() == anEvent->GetEventID() + 1) {
G4ExceptionDescription msg;
msg << "Input file contains more events than requested in the run.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"UnusedEventsInInputFile", JustWarning, msg);
}
} else
#endif
{
// Beam position: z
// Use value set by UI command, or set it to edge of the world volume
if (fBeamZ0 == -999 * CLHEP::m) {
G4double worldDZ = 0;
if (!fEnvelopeBox) {
G4LogicalVolume *envLV =
G4LogicalVolumeStore::GetInstance()->GetVolume("World");
if (envLV)
fEnvelopeBox = dynamic_cast<G4Box *>(envLV->GetSolid());
}
if (fEnvelopeBox) {
worldDZ = fEnvelopeBox->GetZHalfLength();
fBeamZ0 = -worldDZ;
} else {
G4ExceptionDescription msg;
msg << "World volume of box shape not found.\n";
msg << "Perhaps you have changed geometry.\n";
msg << "The gun will be place at the center.";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"WorldVolume", JustWarning, msg);
}
}
// Beam position: x,y
switch (fBeamType) {
case eNone:
default:
fParticleGun->SetParticlePosition(G4ThreeVector(0, 0, fBeamZ0));
break;
case eGaussian:
fParticleGun->SetParticlePosition(
G4ThreeVector(G4RandGauss::shoot(0., fSigmaBeamX),
G4RandGauss::shoot(0., fSigmaBeamY), fBeamZ0));
break;
case eFlat:
fParticleGun->SetParticlePosition(
G4ThreeVector(G4RandFlat::shoot(-fSigmaBeamX, fSigmaBeamX),
G4RandFlat::shoot(-fSigmaBeamY, fSigmaBeamY), fBeamZ0));
break;
}
// Particle momentum
if (fMomentumGaussianSpread > 0) {
double energy = fParticleGun->GetParticleEnergy();
energy += G4RandGauss::shoot(0., fMomentumGaussianSpread) * energy;
fParticleGun->SetParticleEnergy(energy);
}
fParticleGun->GeneratePrimaryVertex(anEvent);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,180 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "PrimaryGeneratorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIdirectory.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorMessenger::PrimaryGeneratorMessenger(
PrimaryGeneratorAction *aPrimaryGeneratorAction)
: fPrimaryGenerator(aPrimaryGeneratorAction) {
fDirectory = new G4UIdirectory("/HGCalTestbeam/generator/");
fDirectory->SetGuidance("Primary generator control commands.");
#ifdef WITHROOT
fReadInputCmd =
new G4UIcmdWithABool("/HGCalTestbeam/generator/readInputFile", this);
fReadInputCmd->SetGuidance(
"If instead of particle gun, particle data should be read from file.");
fReadInputCmd->SetParameterName("ifInput", true);
fReadInputCmd->SetDefaultValue(false);
fPathInputCmd =
new G4UIcmdWithAString("/HGCalTestbeam/generator/pathInputFile", this);
fPathInputCmd->SetGuidance("Path to input file containing particle data.");
fPathInputCmd->SetParameterName("path", true);
fStartFromEventCmd =
new G4UIcmdWithAnInteger("/HGCalTestbeam/generator/startFromEvent", this);
fStartFromEventCmd->SetGuidance(
"From which event in the file HGCalTestbeam should be started.");
fStartFromEventCmd->SetParameterName("startFrom", true);
fStartFromEventCmd->SetDefaultValue(0);
#endif
fMomentumSpreadCmd =
new G4UIcmdWithADouble("/HGCalTestbeam/generator/momentumSpread", this);
fMomentumSpreadCmd->SetGuidance("For particle gun generator:");
fMomentumSpreadCmd->SetGuidance(
"Gaussian momentum spread relative to gun energy");
fMomentumSpreadCmd->SetGuidance("(e.g. 0.05 means 5% * gun energy))");
fMomentumSpreadCmd->SetParameterName("momentumSpread", true);
fMomentumSpreadCmd->SetRange("momentumSpread>=0");
fMomentumSpreadCmd->SetDefaultValue(0);
fBeamSpreadTypeCmd =
new G4UIcmdWithAString("/HGCalTestbeam/generator/beamSpread", this);
fBeamSpreadTypeCmd->SetGuidance("Type of beam profile spread.");
fBeamSpreadTypeCmd->SetParameterName("beamSpreadType", true);
fBeamSpreadTypeCmd->SetCandidates("none Gaussian flat");
fBeamSpreadTypeCmd->SetDefaultValue("none");
fBeamSpreadXCmd = new G4UIcmdWithADoubleAndUnit(
"/HGCalTestbeam/generator/beamSpreadX", this);
fBeamSpreadXCmd->SetGuidance("Defines sigma_X for Gaussian spread, or "
"half-side range for flat spread.");
fBeamSpreadXCmd->SetParameterName("sigmaBeamX", true, true);
fBeamSpreadXCmd->SetRange("sigmaBeamX>=0");
fBeamSpreadXCmd->SetDefaultUnit("cm");
fBeamSpreadXCmd->SetUnitCandidates("micron mm cm m km");
fBeamSpreadYCmd = new G4UIcmdWithADoubleAndUnit(
"/HGCalTestbeam/generator/beamSpreadY", this);
fBeamSpreadYCmd->SetGuidance("Defines sigma_Y for Gaussian spread, or "
"half-side range for flat spread.");
fBeamSpreadYCmd->SetParameterName("sigmaBeamY", true, true);
fBeamSpreadYCmd->SetRange("sigmaBeamY>=0");
fBeamSpreadYCmd->SetDefaultUnit("cm");
fBeamSpreadYCmd->SetUnitCandidates("micron mm cm m km");
fBeamZ0Cmd =
new G4UIcmdWithADoubleAndUnit("/HGCalTestbeam/generator/beamZ0", this);
fBeamZ0Cmd->SetGuidance(
"Beam position along the beam line (default: edge of the world volume).");
fBeamZ0Cmd->SetParameterName("z0", true, true);
fBeamZ0Cmd->SetDefaultUnit("cm");
fBeamZ0Cmd->SetUnitCandidates("micron mm cm m km");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorMessenger::~PrimaryGeneratorMessenger() {
delete fDirectory;
#ifdef WITHROOT
delete fReadInputCmd;
delete fPathInputCmd;
delete fStartFromEventCmd;
#endif
delete fMomentumSpreadCmd;
delete fBeamSpreadTypeCmd;
delete fBeamSpreadXCmd;
delete fBeamSpreadYCmd;
delete fBeamZ0Cmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorMessenger::SetNewValue(G4UIcommand *command,
G4String newValues) {
if (command == fMomentumSpreadCmd) {
fPrimaryGenerator->SetMomentumSpread(
fMomentumSpreadCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamSpreadTypeCmd) {
fPrimaryGenerator->SetBeamSpreadType(newValues);
} else if (command == fBeamSpreadXCmd) {
fPrimaryGenerator->SetBeamSpreadX(
fBeamSpreadXCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamSpreadYCmd) {
fPrimaryGenerator->SetBeamSpreadY(
fBeamSpreadYCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamZ0Cmd) {
fPrimaryGenerator->SetBeamZ0(fBeamZ0Cmd->GetNewDoubleValue(newValues));
}
#ifdef WITHROOT
else if (command == fReadInputCmd) {
fPrimaryGenerator->SetIfUseInputFiles(
fReadInputCmd->GetNewBoolValue(newValues));
} else if (command == fPathInputCmd) {
fPrimaryGenerator->SetInputFiles(newValues);
} else if (command == fStartFromEventCmd) {
fPrimaryGenerator->SetStartFromEvent(
fStartFromEventCmd->GetNewIntValue(newValues));
}
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4String PrimaryGeneratorMessenger::GetCurrentValue(G4UIcommand *command) {
G4String cv;
if (command == fMomentumSpreadCmd) {
cv = fMomentumSpreadCmd->ConvertToString(
fPrimaryGenerator->GetMomentumSpread());
} else if (command == fBeamSpreadTypeCmd) {
cv = fPrimaryGenerator->GetBeamSpreadType();
} else if (command == fBeamSpreadXCmd) {
cv = fBeamSpreadXCmd->ConvertToString(fPrimaryGenerator->GetBeamSpreadX());
} else if (command == fBeamSpreadYCmd) {
cv = fBeamSpreadYCmd->ConvertToString(fPrimaryGenerator->GetBeamSpreadY());
} else if (command == fBeamZ0Cmd) {
cv = fBeamZ0Cmd->ConvertToString(fPrimaryGenerator->GetBeamZ0());
}
#ifdef WITHROOT
else if (command == fReadInputCmd) {
cv =
fReadInputCmd->ConvertToString(fPrimaryGenerator->GetIfUseInputFiles());
} else if (command == fPathInputCmd) {
cv = fPrimaryGenerator->GetInputFiles();
}
#endif
return cv;
}
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "RunAction.hh"
#include "EventAction.hh"
#include "G4UserRunAction.hh"
#include "G4GenericMessenger.hh"
#include "G4String.hh"
#include "g4root.hh"
#include <iostream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(EventAction *eventAction)
: G4UserRunAction(), fEventAction(eventAction),
fOutputFileDir("sim_HGCalTB_G4Standalone") {
fMessenger =
new G4GenericMessenger(this, "/HGCalTestbeam/output/", "Output control");
// randomizePrimary command
auto &fileNameCommand = fMessenger->DeclareProperty("file", fOutputFileDir);
G4String guidance = "Define output file location.";
fileNameCommand.SetGuidance(guidance);
fileNameCommand.SetParameterName("filename", true);
fileNameCommand.SetDefaultValue("sim_HGCalTB_G4Standalone");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction() { delete G4AnalysisManager::Instance(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run *) {
// Create analysis manager
// The choice of analysis technology is done via selection of a namespaces
auto analysisManager = G4AnalysisManager::Instance();
G4cout << "Using " << analysisManager->GetType() << G4endl;
// Default settings
analysisManager->SetNtupleMerging(true);
analysisManager->SetVerboseLevel(1);
std::cout << "Output file is: " << fOutputFileDir << std::endl;
analysisManager->SetFileName(fOutputFileDir);
if (fEventAction) {
analysisManager->CreateNtuple("hits", "hits");
analysisManager->CreateNtupleIColumn("event"); // column Id = 0
analysisManager->CreateNtupleIColumn(
"pdgID", fEventAction->fPrimariesPDG); // column Id = 1
analysisManager->CreateNtupleDColumn(
"beamEnergy", fEventAction->fPrimariesEnergy); // column Id = 2
analysisManager->CreateNtupleDColumn(
"beamX_cm", fEventAction->fPrimariesX); // column Id = 3
analysisManager->CreateNtupleDColumn(
"beamY_cm", fEventAction->fPrimariesY); // column Id = 4
analysisManager->CreateNtupleDColumn(
"beamZ_cm", fEventAction->fPrimariesZ); // column Id = 5
analysisManager->CreateNtupleIColumn("siliconHits_ID",
fEventAction->fSiHitsID);
analysisManager->CreateNtupleDColumn("siliconHits_x_cm",
fEventAction->fSiHitsX);
analysisManager->CreateNtupleDColumn("siliconHits_y_cm",
fEventAction->fSiHitsY);
analysisManager->CreateNtupleDColumn("siliconHits_z_cm",
fEventAction->fSiHitsZ);
analysisManager->CreateNtupleDColumn("siliconHits_Edep_keV",
fEventAction->fSiHitsEdep);
analysisManager->CreateNtupleDColumn("siliconHits_EdepNonIonizing_keV",
fEventAction->fSiHitsEdepNonIonising);
analysisManager->CreateNtupleDColumn("siliconHits_TOA_ns",
fEventAction->fSiHitsTOA);
analysisManager->CreateNtupleDColumn("siliconHits_TOA_last_ns",
fEventAction->fSiHitsTOA);
analysisManager->CreateNtupleIColumn("siliconHits_type",
fEventAction->fSiHitsType);
analysisManager->CreateNtupleIColumn("SiPMHits_ID",
fEventAction->fSiPMhitsID);
analysisManager->CreateNtupleDColumn("SiPMHits_x_cm",
fEventAction->fSiPMhitsX);
analysisManager->CreateNtupleDColumn("SiPMHits_y_cm",
fEventAction->fSiPMhitsY);
analysisManager->CreateNtupleDColumn("SiPMHits_z_cm",
fEventAction->fSiPMhitsZ);
analysisManager->CreateNtupleDColumn("SiPMHits_Edep_keV",
fEventAction->fSiPMhitsEdep);
analysisManager->CreateNtupleDColumn(
"SiPMHits_EdepNonIonizing_keV", fEventAction->fSiPMhitsEdepNonIonising);
analysisManager->CreateNtupleDColumn("SiPMHits_TOA_ns",
fEventAction->fSiPMhitsTOA);
analysisManager->CreateNtupleIColumn("SiPMHits_type",
fEventAction->fSiPMhitsType);
analysisManager->CreateNtupleDColumn(
"signalSum_HGCAL_GeV"); // column Id = 23
analysisManager->CreateNtupleDColumn("COGZ_HGCAL_cm"); // column Id = 24
analysisManager->CreateNtupleIColumn("NHits_HGCAL"); // column Id = 25
analysisManager->CreateNtupleDColumn(
"signalSum_AHCAL_GeV"); // column Id = 26
analysisManager->CreateNtupleDColumn("COGZ_AHCAL_cm"); // column Id = 27
analysisManager->CreateNtupleIColumn("NHits_AHCAL"); // column Id = 28
analysisManager->FinishNtuple();
}
analysisManager->OpenFile();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run *) {
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->Write();
analysisManager->CloseFile();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,86 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiPMHit.hh"
#include <cstdlib>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiPMHit::SiPMHit(G4String aVolumeName, G4int aCopyNumSensor,
G4int aCopyNumCell)
: fVolumeName(aVolumeName), fCopyNumCell(aCopyNumCell),
fCopyNumSensor(aCopyNumSensor) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiPMHit::Digitise(const G4double aTimeWindow,
const G4double aToaThreshold) {
// process energy deposits
if (fEdep.size() == 0) {
fIsValidHit = false;
return;
}
std::sort(fEdep.begin(), fEdep.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
G4double firstHitTime = fEdep[0].second;
fEdepDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow < 0 || fEdep[i].second < firstHitTime + aTimeWindow)
fEdepDigi += fEdep[i].first;
#ifdef DEBUG
else
std::cout << "Rejecting hit (" << fEdep[i].first << " keV) at time "
<< fEdep[i].second << "(start: " << firstHitTime << ")"
<< std::endl;
#endif
if ((fTimeOfArrival == -1) && (fEdepDigi > aToaThreshold))
fTimeOfArrival = fEdep[i].second;
}
fIsValidHit = (fEdepDigi > 0);
// non ionizing part, does not contribute to TOAs
if (fEdepNonIonizing.size() == 0)
return;
std::sort(fEdepNonIonizing.begin(), fEdepNonIonizing.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
fEdepNonIonizingDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow == -1 ||
fEdepNonIonizing[i].second < firstHitTime + aTimeWindow)
fEdepNonIonizingDigi += fEdepNonIonizing[i].first;
}
}
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiPMSD.hh"
SiPMSD::SiPMSD(G4String name) : G4VSensitiveDetector("SiPMHitCollection") {
G4cout << "creating a sensitive detector with name: " << name << G4endl;
collectionName.insert("SiPMHitCollection");
}
SiPMSD::~SiPMSD() {}
void SiPMSD::Initialize(G4HCofThisEvent *HCE) {
fHitCollection = new SiPMHitCollection(GetName(), collectionName[0]);
if (fHCID < 0)
fHCID = GetCollectionID(0);
HCE->AddHitsCollection(fHCID, fHitCollection);
fTmpHits.clear();
}
void SiPMSD::EndOfEvent(G4HCofThisEvent *) {
for (auto it = fTmpHits.begin(); it != fTmpHits.end(); ++it)
fHitCollection->insert(it->second);
}
G4bool SiPMSD::ProcessHits(G4Step *step, G4TouchableHistory *) {
G4TouchableHandle touchable = step->GetPreStepPoint()->GetTouchableHandle();
G4int copyNumCell = touchable->GetVolume(0)->GetCopyNo();
G4int copyNumSensor = touchable->GetVolume(1)->GetCopyNo();
int tmp_ID = 1000 * copyNumSensor + copyNumCell;
if (fTmpHits.find(tmp_ID) == fTmpHits.end()) { // make new hit
G4String vol_name = touchable->GetVolume(0)->GetName();
fTmpHits[tmp_ID] = new SiPMHit(vol_name, copyNumSensor, copyNumCell);
G4double hitX = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().x()) /
CLHEP::cm;
G4double hitY = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().y()) /
CLHEP::cm;
G4double hitZ = touchable->GetVolume(1)->GetTranslation().z() / CLHEP::cm;
fTmpHits[tmp_ID]->SetPosition(hitX, hitY, hitZ); // in cm
}
G4double edep = step->GetTotalEnergyDeposit() / CLHEP::keV; // in keV
G4double edepNonIonizing = step->GetNonIonizingEnergyDeposit() / CLHEP::keV;
G4double timedep = step->GetPostStepPoint()->GetGlobalTime() / CLHEP::ns;
fTmpHits[tmp_ID]->AddEdep(edep, timedep);
fTmpHits[tmp_ID]->AddEdepNonIonizing(edepNonIonizing, timedep);
return true;
}
@@ -0,0 +1,112 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiliconPixelHit.hh"
#include "G4RotationMatrix.hh"
#include "G4SubtractionSolid.hh"
#include "G4Transform3D.hh"
#include "G4VVisManager.hh"
#include "G4VisAttributes.hh"
#include "HGCalTBMaterials.hh"
#include <cstdlib>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiliconPixelHit::SiliconPixelHit(G4String aVolumeName, G4int aCopyNumSensor,
G4int aCopyNumCell)
: fVolumeName(aVolumeName), fCopyNumCell(aCopyNumCell),
fCopyNumSensor(aCopyNumSensor) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelHit::Digitise(const G4double aTimeWindow,
const G4double aToaThreshold) {
// process energy deposits
if (fEdep.size() == 0) {
fIsValidHit = false;
return;
}
std::sort(fEdep.begin(), fEdep.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
G4double firstHitTime = fEdep[0].second;
fEdepDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow < 0 || fEdep[i].second < firstHitTime + aTimeWindow)
fEdepDigi += fEdep[i].first;
if (fEdepDigi > aToaThreshold) {
if (fTimeOfArrival == -1)
fTimeOfArrival = fEdep[i].second;
fTimeOfArrivalLast = fEdep[i].second;
}
}
fIsValidHit = (fEdepDigi > 0);
// non ionizing part, does not contribute to TOAs
if (fEdepNonIonizing.size() == 0)
return;
std::sort(fEdepNonIonizing.begin(), fEdepNonIonizing.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
fEdepNonIonizingDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow == -1 ||
fEdepNonIonizing[i].second < firstHitTime + aTimeWindow)
fEdepNonIonizingDigi += fEdepNonIonizing[i].first;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelHit::Draw() {
G4VVisManager *pVVisManager = G4VVisManager::GetConcreteInstance();
if (!(fEdepDigi > 0))
return;
if (pVVisManager) {
if (!pVVisManager->FilterHit(*this))
return;
G4Transform3D trans(G4RotationMatrix(),
G4ThreeVector(fPosX * CLHEP::cm, fPosY * CLHEP::cm, fPosZ * CLHEP::cm));
G4VisAttributes attribs;
auto solid = HexagonSolid("dummy", 0.3 * CLHEP::mm, 0.6496345 * CLHEP::cm);
G4Colour colour(1, 0, 0);
attribs.SetColour(colour);
attribs.SetForceSolid(true);
pVVisManager->Draw(*solid, attribs, trans);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,92 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiliconPixelSD.hh"
#include "G4String.hh"
SiliconPixelSD::SiliconPixelSD(G4String name)
: G4VSensitiveDetector("SiliconPixelHitCollection") {
G4cout << "creating a sensitive detector with name: " << name << G4endl;
collectionName.insert("SiliconPixelHitCollection");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiliconPixelSD::~SiliconPixelSD() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelSD::Initialize(G4HCofThisEvent *HCE) {
fHitCollection = new SiliconPixelHitCollection(GetName(), collectionName[0]);
if (fHCID < 0)
fHCID = GetCollectionID(0);
HCE->AddHitsCollection(fHCID, fHitCollection);
fTmpHits.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelSD::EndOfEvent(G4HCofThisEvent *) {
for (auto it = fTmpHits.begin(); it != fTmpHits.end(); ++it)
fHitCollection->insert(it->second);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool SiliconPixelSD::ProcessHits(G4Step *step, G4TouchableHistory *) {
G4TouchableHandle touchable = step->GetPreStepPoint()->GetTouchableHandle();
G4int copyNumCell = touchable->GetVolume(0)->GetCopyNo();
G4int copyNumSensor = touchable->GetVolume(1)->GetCopyNo();
int tmp_ID = 1000 * copyNumSensor + copyNumCell;
if (fTmpHits.find(tmp_ID) == fTmpHits.end()) { // make new hit
G4String vol_name = touchable->GetVolume(0)->GetName();
fTmpHits[tmp_ID] =
new SiliconPixelHit(vol_name, copyNumSensor, copyNumCell);
G4double hitX = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().x()) /
CLHEP::cm;
G4double hitY = (touchable->GetVolume(1)->GetTranslation().y() +
touchable->GetVolume(0)->GetTranslation().y()) /
CLHEP::cm;
G4double hitZ = touchable->GetVolume(1)->GetTranslation().z() / CLHEP::cm;
fTmpHits[tmp_ID]->SetPosition(hitX, hitY, hitZ); // in cm
}
G4double edep = step->GetTotalEnergyDeposit() / CLHEP::keV; // in keV
G4double edepNonIonizing = step->GetNonIonizingEnergyDeposit() / CLHEP::keV;
G4double timedep = step->GetPostStepPoint()->GetGlobalTime() / CLHEP::ns;
fTmpHits[tmp_ID]->AddEdep(edep, timedep);
fTmpHits[tmp_ID]->AddEdepNonIonizing(edepNonIonizing, timedep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+94
View File
@@ -0,0 +1,94 @@
# Macro file for the visualization settings of the HGCal testbeam simulation
#
# Use these open statements to open selected visualization
#
# Use this open statement to create an OpenGL view:
/vis/open OGL 800x600-0+0
#
# Use this open statement to create an OpenInventor view:
#/vis/open OI
#
# 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
#
#
# Specify view angle:
/vis/viewer/set/hiddenMarker true
/vis/viewer/set/viewpointThetaPhi -45 30
/vis/viewer/zoom 2
#
# Specify style (surface, wireframe, auxiliary edges,...)
/vis/viewer/set/style surface
/vis/viewer/set/auxiliaryEdge true
/vis/viewer/set/lineSegmentsPerCircle 100
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/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)
#
#
# To draw only gammas:
/vis/filtering/trajectories/create/particleFilter particleFilter-0
/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
#
# Momentum selection for the drawing
/vis/filtering/trajectories/create/attributeFilter
/vis/filtering/trajectories/attributeFilter-0/setAttribute IMag
/vis/filtering/trajectories/attributeFilter-0/addInterval 10. MeV 1000 GeV
/vis/modeling/trajectories/create/drawByAttribute
/vis/modeling/trajectories/drawByAttribute-0/setAttribute IMag
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval1 1 MeV 10 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval2 10 MeV 100 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval3 100 MeV 200 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval4 200.0 MeV 500 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval5 500 MeV 0.9 GeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval6 0.9 GeV 10000 GeV
/vis/modeling/trajectories/drawByAttribute-0/interval1/setLineColourRGBA 0.1 0.1 0.1 0.3
/vis/modeling/trajectories/drawByAttribute-0/interval2/setLineColourRGBA 1 0.3 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval3/setLineColourRGBA 1 1 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval4/setLineColourRGBA 0 1 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval5/setLineColourRGBA 1 0 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval6/setLineColourRGBA 0 0 1 1
# Make the background white
/vis/viewer/set/background 1 1 1 1.0
# Make the "World" box invisible
/vis/geometry/set/visibility World 0 false
# 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
# Change the display limits
/vis/ogl/set/displayListLimit 500000
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0
@@ -0,0 +1,93 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.8...3.18 FATAL_ERROR)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(ICRPphantoms)
#----------------------------------------------------------------------------
# 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
${Geant4_INCLUDE_DIR}
${GDML_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(ICRP110phantoms ICRP110phantoms.cc ${sources} ${headers})
target_link_libraries(ICRP110phantoms ${Geant4_LIBRARIES} )
# Depend on data for runtime
add_dependencies(ICRP110phantoms ICRPdata)
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build human_phantom. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(ICRPphantoms_SCRIPTS
female.in female_head.in female_trunk.in male.in male_head.in male_trunk.in vis.mac primary.mac ColourMap.dat openGLVis.mac
# ICRPdata/Data.dat
# "ICRPdata/ICRP110_g4dat/AF/*.g4dat"
# "ICRPdata/ICRP110_g4dat/AM/*.g4dat"
)
foreach(_script ${ICRPphantoms_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
#set(ICRPphantoms_DATADIR
# ICRPdata
#)
#file(COPY ${PROJECT_SOURCE_DIR}/${ICRPphantoms_DATADIR} DESTINATION
# ${PROJECT_BINARY_DIR})
include(ExternalProject)
ExternalProject_Add(ICRPdata
SOURCE_DIR ${PROJECT_BINARY_DIR}/ICRPdata
URL https://cern.ch/geant4-data/datasets/examples/advanced/ICRP110Phantoms/ICRPdata.tar.gz
URL_MD5 f4d83f38c9d952430ec6a0a4a07a9f21
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
#----------------------------------------------------------------------------
# Add program to the project targets
# (this avoids the need of typing the program name after make)
#
add_custom_target(ICRPphantoms DEPENDS phantom)
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS ICRP110phantoms DESTINATION bin)
@@ -0,0 +1,55 @@
53
air 1. 0. 1. 0.
teeth 1. 1. 1. 1.
bone 1. 1. 1. 1.
humeri_upper 1. 1. 1. 1.
humeri_lower 1. 1. 1. 1.
arm_lower 1. 1. 0. 0.
hand 1. 1. 0. 0.
clavicle 1. 1. 1. 1.
cranium 1. 1. 1. 1.
femora_upper 1. 1. 1. 1.
femora_lower 1. 1. 1. 1.
leg_lower 1. 1. 0. 0.
foot 1. 1. 0. 0.
mandible 1. 1. 1. 1.
pelvis 1. 1. 1. 1.
ribs 1. 1. 1. 1.
scapulae 1. 1. 1. 1.
spine_cervical 1. 1. 1. 1.
spine_thoratic 1. 1. 1. 1.
spine_lumbar 1. 1. 1. 1.
sacrum 1. 1. 1. 1.
sternum 1. 1. 1. 1.
hf_upper 1. 1. 0. 0.
hf_lower 1. 1. 0. 0.
med_lowerarm 1. 1. 0. 0.
med_lowerleg 1. 1. 0. 0.
cartilage 1. 1. 0. 0.
skin 1. 1. 0. 0.
blood 1. 0. 0. 0.
muscle 1. 0. 0. 0.
liver 0. 0. 1. 1.
pancreas 1. 1. 0. 1.
brain 1. 0. 0. 1.
heart 1. 0. 0. 1.
eye 0.5 0.5 0.5 1.
kidney 1. 1. 0. 1.
stomach 0. 1. 0. 1.
intestine_sml 1. 0. 1. 1.
intestine_lrg 0.5 0.5 0.5 1.
spleen 1. 1. 0. 0.
thyroid 1. 1. 0. 1.
bladder 1. 1. 0. 1.
ovaries_testes 1. 0. 0. 1.
adrenals 1. 1. 0. 0.
oesophagus 1. 1. 0. 0.
misc 1. 1. 0. 0.
uterus_prostate 0. 1. 1. 1.
lymph 1. 1. 0. 0.
breast_glandular 1. 1. 0. 1.
breast_adipose 1. 1. 0. 0.
lung 1. 0.5 0. 1.
gastro_content 1. 1. 0. 0.
urine 1. 1. 0. 0.
@@ -0,0 +1,27 @@
# $Id: GNUmakefile 70025 2013-05-22 08:43:05Z gcosmo $
# --------------------------------------------------------------
# GNUmakefile for examples module.
# --------------------------------------------------------------
name := phantom
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../..
endif
.PHONY: all
all: lib bin
##CPPFLAGS += `aida-config --include`
##LDFLAGS += `aida-config --lib`
##LOADLIBS += `aida-config --lib`
CPPFLAGS += -I${ROOTSYS}/include
EXTRALIBS = $(shell root-config --glibs)
include $(G4INSTALL)/config/binmake.gmk
#visclean:
# rm -f g4*.prim g4*.eps g4*.wrl
# rm -f .DAWN_*
@@ -0,0 +1,16 @@
-------------------------------------------------------------------
-------------------------------------------------------------------
=========================================================
Geant4 - ICRP110Phantoms example
=========================================================
Category History file
---------------------
15.11.2020 - S. Guatelli; ICRP110Phantoms-V10-06-01
Migration to G4RunManagerFactory
27.10.2020 - S. Guatelli; ICRP110Phantoms-V10-06-00
New advanced example modelling ICRP110 phantom models
@@ -0,0 +1,93 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Authors: S.Guatelli, Matthew Large and A. Malaroda, University of Wollongong
//
#include "G4UImanager.hh"
#include "G4UIsession.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "ICRP110PhantomConstruction.hh"
#include "ICRP110PhantomActionInitialization.hh"
#include "G4ScoringManager.hh"
#include "ICRP110UserScoreWriter.hh"
#include "QGSP_BIC_HP.hh"
#include "G4RunManagerFactory.hh"
int main(int argc,char** argv)
{
auto* runManager = G4RunManagerFactory::CreateRunManager();
G4int nThreads = 4;
runManager->SetNumberOfThreads(nThreads);
// Activate UI-command base scorer
G4ScoringManager* scorerManager = G4ScoringManager::GetScoringManager();
scorerManager -> SetVerboseLevel(1);
//====================================================================
// Un-comment this line for user defined score writer
scorerManager -> SetScoreWriter(new ICRP110UserScoreWriter());
//====================================================================
// Set mandatory initialization classes
ICRP110PhantomConstruction* userPhantom = new ICRP110PhantomConstruction();
runManager -> SetUserInitialization(userPhantom);
runManager -> SetUserInitialization(new QGSP_BIC_HP());
// runManager -> SetUserInitialization(new ICRP110PhantomPhysicsList);
G4VisManager* visManager = new G4VisExecutive;
visManager -> Initialize();
ICRP110PhantomActionInitialization* actions = new ICRP110PhantomActionInitialization();
runManager -> SetUserInitialization(actions);
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if (argc==1) // Define UI session for interactive mode.
{
G4cout << " UI session starts ..." << G4endl;
G4UIExecutive* ui = new G4UIExecutive(argc, argv);
UImanager -> ApplyCommand("/control/execute vis.mac");
ui -> SessionStart();
delete ui;
}
else // Batch mode
{
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager -> ApplyCommand(command+fileName);
}
delete visManager;
delete runManager;
return 0;
}
@@ -0,0 +1,286 @@
=======================================================================
Geant4 - ICRP110_HumanPhantoms Example
=======================================================================
The ICRP110_HumanPhantoms example is developed and mantained by Susanna Guatelli, Matthew Large and Alessandra Malaroda,
Centre For Medical Radiation Physics (CMRP), University of Wollongong, NSW, Australia.
Contacts:
- susanna@uow.edu.au
- mjl970@uowmail.edu.au
- malaroda@uow.edu.au
The example is based on the extended/medical/DICOM example
The authors acknowledge that this application of the ICRP110 human phantoms have been implemented in Geant4 with the kind permission of
the International Commission on Radiological Protection (ICRP).
----------------------------------------------------------------------------------------------------
--------------------------------------> Introduction <----------------------------------------------
----------------------------------------------------------------------------------------------------
This application models the ICRP110 reference computational human phantoms [1] in a Geant4 simulation and calculates
the dose in individual voxels and in entire organs.
The human male phantom, provided kindly by the ICRP, is created from a whole-body clinical CT image set of a 38yr old
individual with height 176 cm and mass approximately 70 kg. Similarly, the human female phantom was created from a set of
whole body CT images of a 43yr old individual with height 163 cm and weight 60 kg. The CT scans were acquired with both
individuals laying supine and with arms resting parallel alongside the body. Both sets of CT data were then scaled to
closely approximate the ICRP adult Reference Male and Reference Female, defined in previous ICRP publications [2, 3].
[1] HG Menzel, C Clement, and P DeLuca. ICRP publication 110. "Realistic reference phantoms:
an icrp/icru joint effort: A report of adult reference computational phantoms", Annals of the
ICRP, 39(2):1, 2009. URL: http://www.icrp.org/publication.asp?id=icrp%20publication%20110.
[2] Valetin J 2002 Basic anatomical and physiological data for use in radiological protection:
reference values: ICRP Publication 89 Ann. ICRP vol. 32 (Oxford: Elsevier) pp 1-277.
[3] Valetin J 2007 The 2007 recommendations of the international commission on radiological
protection Ann. ICRP vol 37 (Oxford: Elsevier) pp 1-133.
The table below summarises the key features of the male and female voxelised human phantoms.
PROPERTY AM AF
_____________________________________
Height (m) 1.76 1.63
Mass(Kg) 73.0 60.0
Slice Thickness(mm) 8.0 4.84
Voxel in-plane- 2.137 1.775
-resolution (mm)
Voxels along x 254 299
(i.e. columns)
Voxels along y 127 137
(i.e. rows)
Number of Slices 222 348
(i.e. along z)
______________________________________
----------------------------------------------------------------------------------------------------
------------------------------> Application Sub-Folder Structure <----------------------------------
----------------------------------------------------------------------------------------------------
- '/src': where the source .cc files are stored
- '/include': where header .hh files are stored
- '/ICRPdata': where the phantom data files (*.dat) and slice files are stored.
It is downloaded automatically from URL https://cern.ch/geant4-data/datasets/examples/advanced/ICRP110Phantoms/ICRPdata.tar.gz
during the configuration via cmake.
Phantom data files containing the voxelisation of each phantom, as well as files
containing the definitions of the phantom organs and materials used within geant4
code can be found in the folder /ICRPdata.
All data files used for this phantom were obtained from the ICRP's website on publication 110 under "Supplementary Data"
- https://www.icrp.org/publication.asp?id=ICRP%20Publication%20110.
----------------------------------------------------------------------------------------------------
----------------------------------> ICRP110Phantoms Data <------------------------------------------
----------------------------------------------------------------------------------------------------
Within the '/ICRPdata' directory, the following sub-directories are contained:
-> /ICRPdata/ : contains '*Data.dat' files which list the number of phantom slices to
simulate and the order in which to stack the phantom slices.
-> /ICRPdata/ICRP110_g4dat/AM/ : contains the individual male phantom slice files.
-> /ICRPdata/ICRP110_g4dat/AF/ : contains the individual female phantom slice files.
-> /ICRPdata/ICRP110_g4dat/P110_data_V1.2
The final directory contains the raw ICRP110 phantom data as obtained from the ICRP110 publication website [1];
5 files within folders for the AM and AF phantoms are given. These files are described as follows in the
supplementary data's included README file.
The array of organ identification numbers (in ASCII format); the file names are:
AM.dat
AF.dat
A list of individually segmented structures, their identification numbers, and assigned media (Appendix A in ICRP110); the file names are:
AM_organs.dat
AF_organs.dat
A list of the media, their elemental compositions and densities (Appendix B in ICRP110);
the file names are:
AM_media.dat
AF_media.dat
The mass ratios of bone constituents (trabecular bone, red and yellow bone marrow) in the spongiosa regions;
the file names are:
AM_spongiosa.dat
AF_spongiosa.dat
The mass ratios of blood in various body tissues; the file names are:
AM_blood.dat
AF_blood.dat
The primary data files AM.dat and AF.dat contain an array of organ identification numbers ranging from 0 to 141.
Each number respresents the organ associated with each voxel within the phantom. Within these files, the organ IDs
are listed slice by slice, within each slice row by row, within each row column by column. That means, the column
index changes fastest, then the row index, then the slice index - in other words, the phantom voxels first increase
along x, then along y and finally along z. Slice numbers increase from the toes up to the vertex of the body;
row numbers increase from front to back; and column numbers increase from right to left side.
For use in this application, the original AM.dat and AF.dat files containing the organ identification numbers of
all voxels of the phantom were sub-divided into many files with each representing a single phantom slice along z.
As such, each file represents a 2D phantom slice containing x,y voxel positions and organ identification numbers
of each voxel. This allows for subsections of the phantom to be simulated as required by the user, removing the
need to simulate the entire phantom every time when this may not nessecrily be needed by the user. This also will
allow for reductions in the simulation time depending on what portion of the total phantom is simulated by the user.
This feature was achieved via a code developed by Dr Alessandra Malaroda, University of Wollongong, Australia in 2017.
The AM human phantom is voxelised in x,y,z with 254 x 127 x 222 voxels with dimensions 2.137 x 2.137 x 8 mm.
The AF human phantom is voxelised in x,y,z with 299 x 137 x 348 voxels with dimensions 1.775 x 1.775 x 4.84 mm.
----------------------------------------------------------------------------------------------------
---------------------------------------> How to compile and run <-----------------------------------
----------------------------------------------------------------------------------------------------
- Create a build folder for the phantom run
% mkdir build/
- Navigate to inside the build folder and initialise Geant4
% cmake ../
The ICRP110 phantom data will be automatically downloaded from https://cern.ch/geant4-data/datasets/examples/advanced/ICRP110Phantoms/ICRPdata.tar.gz
- Compile and link to generate the executable (in your CMAKE build directory):
% make
- Execute the application in 'interactive' mode with visualization:
% ./ICRP110phantoms
- Execute the application in 'batch' mode from macro files:
% ./ICRP110phantoms female_head.in
-----------------------------
AVAILABLE MACRO FILES
-----------------------------
For the users convinience, macro files have been created which are designed to construct partial head
and trunk phantoms for both the male and female models. These macro files can be called upon in batch
mode when executing the application as specified above. If the user wishes to construct a completed/full
male or female phantom, the macros male.in and female.in can be called upon, respectively.
- male_head.in/female_head.in : Creates a partial head phantom for the male and female, respectively.
- male_trunk.in/female_trunk.in : Creates a partial trunk phantom for the male and female, respectively.
- male.in : Creates full male ICRP110 phantom. This can be modified along with 'ICRPdata/MaleData.dat'
if the user wishes to create their own custom partial phantom section.
- female.in : Creates full female ICRP110 phantom. This can be modified along with
'ICRPdata/FemaleData.dat' if the user wishes to create their own custom partial phantom section.
- openGLVis.mac : macro for visualisation with openGL.
- vis.mac (default) : Executed by default when the simulation is run in 'interactive' mode.
- primary.mac : Contains the definition of the primary radiation field.
At the very top of the various '.in' macro files (pre-initialization), there are a series of commands
which define the sex and section of the phantom to create. These commands are listed below:
o /phantom/setPhantomSex <option> : Passes sex of phantom to Detector Construction
o /phantom/setScoreWriterSex <option> : Passes sex of phantom to User Score Writer
o /phantom/setPhantomSection <option> : Passes section of phantom to Detector Construction
o /phantom/setScoreWriterSection <option> Passes section of phantom to User Score Writer
Available options for the first 2 commands are: male or female.
Avalable options for the last 2 commands are: head, trunk or full.
In the event that the macro called upon by the user when executing the application in 'batch' mode
does not contain these commands (default case), the application sets phantom sex to female and the section as the head.
WARNING: the phantom model can be chosen only in the initialization phase of the simulation!!!
It cannot be changed during the run session. This feature will be implemented in the next future.
----------------------------------------------------------------------------------------------------
----------------------------------> Creating a Custom Phantom <------------------------------------
----------------------------------------------------------------------------------------------------
If the user wishes to construct a customised section of the phantom (i.e. a single slice, the legs, etc),
he/she has to create a specific macro or edit the ones provided. The recommended method for a custom male
phantom is outlined as follows.
The user should edit the macro 'male.in' and the data file
'MaleData.dat'. Firstly, in 'FemaleData.dat', there are 2 simple ways in which the user can
select a custom range of phantom slices to simulate:
1. The very first entry of each Data.dat indicates how many slices to simulate.
Changing this number will determine the number of slices to construct.
2. Further down in the Data.dat files (beginning at line 61) is the name of the first slice to simulate, followed
by successive slices. Changing the slice file orders here will allow various subsections of the human
phantom to be simulated. As an indication the following phantom subsections have been identified for the
male phantom below.
--> AM_Slice1.g4dat to AM_Slice20.g4dat: Feet to ankles
--> AM_Slice21.g4dat to AM_Slice121.g4dat: Ankles to hips
--> AM_Slice169.g4dat: Single chest slice with good visualisation
of lungs, ribs, heart.
--> AM_Slice182.g4dat to AM_Slice222.g4dat: Neck and Head
NOTE: o Always order phantom slices beginning with the lowest number and increasing
in slice number going down the .dat files.
o Always use consecutive/adjacent slices when simulating multiple slices.
o The default number of slices for both male and female phantoms is set to 10
and starts at the feet of each phantom.
Once the user customises the MaleData.dat/FemaleData.dat (for example starting from the full phantoms macros),
he/she has also to fix appropriately the scoring mesh in male.in/female.in.
----------------------------------------------------------------------------------------------------
------------------------------> Scoring Mesh and the User Score Writer <----------------------------
----------------------------------------------------------------------------------------------------
The macro primary.mac defines the radiation beam type, energy, direction and geometry. The UI commands of the
General Particle Source should be used to change the radiation field. The macros male.in and female.in contain
the /run/beamOn command and can call upon the radiation beam definition through the UI command
'/control/execute primary.mac'.
Within male.in and female.in, a scoring mesh is defined which records the dose deposition within each individual
phantom voxel. The size of the scoring mesh is defined in line 54 of the male.in/female.in files, and must be defined
to match the constructed phantom dimensions (whole or partial) defined in the according '/ICRPdata/*Data.dat' file.
The mesh dimensions are defined as half-dimensions in x,y,z - meaning a defined scoring mesh x-dimension of 100mm will construct
a scoring mesh spanning from -100mm to +100mm in the geometrical world in which the phantom lies. Furthermore, for the completed
male phantom which has dimensions along x,y,z of 542.798 x 271.399 x 1776 mm, the scoring mesh half-dimensions should be defined
as 271.399 x 135.6995 x 888. mm. The number of bins or divisions to segment the mesh into is then defined in line 51. These
should match the number of phantom voxels in x,y,z which are defined in the MaleData.dat and FemaleData.dat files in the '/ICRPdata'
directory.
If the user edits the MaleData.dat or FemaleData.dat files to change the number of z-slices simulated in a run, they must also edit
the scoring mesh dimensions and number of bins to ensure it correctly scores their defined phantom. To do so, the user will typically
only have to edit lines 54 and 55 of the male.in or female.in macro files.
After completion of a simulation run, the phantom mesh records the deposited dose in each phantom voxel and outputs the data to a text file named
"PhantomMesh_Dose.txt". This text file lists the x,y,z positional number of the voxel in the phantom and the dose recorded within that voxel (in Gy).
The output PhantomMesh_Dose.txt file is created by the User Score Writer class defined in the source code ICRP110UserScoreWriter.cc. In the same class the dose
in the voxels is analysed and associated to organs.
A final output file "OrganDoses.out" is then created which contains the total dose delivered to each organ.
----------------------------------------------------------------------------------------------------
----------------------------------------> Further Info <--------------------------------------------
----------------------------------------------------------------------------------------------------
-------> ColourMap.dat <--------
This file located in the build directory assigns G4colours to the 53 phantom materials.
The user may edit these as they wish for visualistion purposes.
----------> Physics <-----------
The QGSP_BIC_HP Physics List is adopted. The user may want to change the
cut of production of secondary particles.
-----> Primary particles <------
The G4 General Particle Source (gps) is used to generate primary radiation field.
Macro primary.mac contains the definition of the primary radiation field.
@@ -0,0 +1,85 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex female
/phantom/setScoreWriterSex female
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection full
/phantom/setScoreWriterSection full
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (1.775, 1.775, 4.84)mm #
# and there are 299 voxels along x, 137 along y and 348 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths. #
# #
# If the user is not building all 348 z-slices of the phantom, has to change #
# the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for #
# the fully constructed female phantom with 348 single slices in z. #
# #
#################################################################################
/score/mesh/boxSize 265.3625 121.5875 842.16 mm
/score/mesh/nBin 299 137 348
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
/score/quantity/doseDeposit doseDeposit
#score/quantity/energyDeposit energyDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 1000
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,85 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex female
/phantom/setScoreWriterSex female
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection head
/phantom/setScoreWriterSection head
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (1.775, 1.775, 4.84)mm #
# and there are 299 voxels along x, 137 along y and 348 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths. #
# #
# If the user is not building all 348 z-slices of the phantom, has to change #
# the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for #
# a female partial head phantom with 45 single slices in z. #
# #
#################################################################################
/score/mesh/boxSize 265.3625 121.5875 108.9 mm
/score/mesh/nBin 299 137 45
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
/score/quantity/doseDeposit doseDeposit
#score/quantity/energyDeposit energyDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 100
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,85 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex female
/phantom/setScoreWriterSex female
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection trunk
/phantom/setScoreWriterSection trunk
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (1.775, 1.775, 4.84)mm #
# and there are 299 voxels along x, 137 along y and 348 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths. #
# #
# If the user is not building all 348 z-slices of the phantom, has to change #
# the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for #
# the partial trunk female phantom with 100 single slices in z. #
# #
#################################################################################
/score/mesh/boxSize 265.3625 121.5875 242.0 mm
/score/mesh/nBin 299 137 100
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
/score/quantity/doseDeposit doseDeposit
#score/quantity/energyDeposit energyDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 100
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,48 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, Matthew Large and A. Malaroda, University of Wollongong
//
#ifndef ICRP110PhantomActionInitialization_h
#define ICRP110PhantomActionInitialization_h 1
#include "G4VUserActionInitialization.hh"
#include "ICRP110PhantomAnalysisManager.hh"
class G4GeneralParticleSource;
class ICRP110PhantomActionInitialization: public G4VUserActionInitialization
{
public:
ICRP110PhantomActionInitialization();
virtual ~ICRP110PhantomActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
};
#endif
@@ -0,0 +1,32 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
// Original code from the extended/analysis examples
#ifndef ICRP110PhantomAnalysisManager_HH
#define ICRP110PhantomAnalysisManager_HH
#include "g4root.hh"
#endif
@@ -0,0 +1,90 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#ifndef ICRP110PhantomConstruction_H
#define ICRP110PhantomConstruction_H 1
#include "G4VUserDetectorConstruction.hh"
#include "ICRP110PhantomMessenger.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4PSDoseDeposit3D.hh"
#include "G4SDManager.hh"
#include "globals.hh"
#include <map>
class G4VPhysicalVolume;
class ICRP110PhantomMaterial_Female;
class ICRP110PhantomMaterial_Male;
class G4Material;
class ICRP110PhantomConstruction : public G4VUserDetectorConstruction
{
public:
ICRP110PhantomConstruction();
~ICRP110PhantomConstruction();
G4VPhysicalVolume* Construct();
inline G4int GetNumberVoxelX(){return fNVoxelX;};
inline G4int GetNumberVoxelY() {return fNVoxelY;};
inline G4int GetNumberVoxelZ() {return fNVoxelZ;};
void SetPhantomSex(G4String);
void SetPhantomSection(G4String);
private:
void ReadPhantomData(const G4String& sex, const G4String& section);
void ReadPhantomDataFile(const G4String& sex, const G4String& fname, G4int);
ICRP110PhantomMaterial_Female* fMaterial_Female;
ICRP110PhantomMaterial_Male* fMaterial_Male;
ICRP110PhantomMessenger* fMessenger;
// std::vector<G4Material*> fMaterials;
G4int fNVoxelX;
G4int fNVoxelY;
G4int fNVoxelZ;
G4double fVoxelHalfDimX;
G4double fVoxelHalfDimY;
G4double fVoxelHalfDimZ;
G4double fMinX;
G4double fMaxX;
G4double fMinY;
G4double fMaxY;
G4double fMinZ;
G4double fMaxZ;
G4int fNoFiles;
G4int fNVoxels;
size_t* fMateIDs; // index of material of each voxel
G4String fSex;
G4String fSection;
};
#endif
@@ -0,0 +1,103 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//
#ifndef ICRP110PhantomMaterial_Female_H
#define ICRP110PhantomMaterial_Female_H 1
#include "globals.hh"
class G4Material;
class ICRP110PhantomMaterial_Female
{
public:
ICRP110PhantomMaterial_Female();
~ ICRP110PhantomMaterial_Female();
public:
void DefineMaterials();
G4Material* GetMaterial(G4String); //returns the material
private:
G4Material* fLung;
G4Material* fTeeth;
G4Material* fBone;
G4Material* fHumeri_upper;
G4Material* fHumeri_lower;
G4Material* fArm_lower;
G4Material* fHand;
G4Material* fClavicle;
G4Material* fCranium;
G4Material* fFemora_upper;
G4Material* fFemora_lower;
G4Material* fLeg_lower;
G4Material* fFoot;
G4Material* fMandible;
G4Material* fPelvis;
G4Material* fRibs;
G4Material* fScapulae;
G4Material* fSpine_cervical;
G4Material* fSpine_lumbar;
G4Material* fSpine_thoratic;
G4Material* fSacrum;
G4Material* fSternum;
G4Material* fHf_upper;
G4Material* fHf_lower;
G4Material* fMed_lowerleg;
G4Material* fMed_lowerarm;
G4Material* fCartilage;
G4Material* fSkin;
G4Material* fBlood;
G4Material* fMuscle;
G4Material* fLiver;
G4Material* fPancreas;
G4Material* fBrain;
G4Material* fHeart;
G4Material* fEye;
G4Material* fKidney;
G4Material* fStomach;
G4Material* fIntestine_sml;
G4Material* fIntestine_lrg;
G4Material* fSpleen;
G4Material* fThyroid;
G4Material* fBladder;
G4Material* fOvaries_testes;
G4Material* fAdrenals;
G4Material* fOesophagus;
G4Material* fMisc;
G4Material* fUterus_prostate;
G4Material* fLymph;
G4Material* fBreast_glandular;
G4Material* fBreast_adipose;
G4Material* fGastro_content;
G4Material* fUrine;
};
#endif
@@ -0,0 +1,103 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//
#ifndef ICRP110PhantomMaterial_Male_H
#define ICRP110PhantomMaterial_Male_H 1
#include "globals.hh"
class G4Material;
class ICRP110PhantomMaterial_Male
{
public:
ICRP110PhantomMaterial_Male();
~ ICRP110PhantomMaterial_Male();
public:
void DefineMaterials();
G4Material* GetMaterial(G4String); //returns the material
private:
G4Material* fLung;
G4Material* fTeeth;
G4Material* fBone;
G4Material* fHumeri_upper;
G4Material* fHumeri_lower;
G4Material* fArm_lower;
G4Material* fHand;
G4Material* fClavicle;
G4Material* fCranium;
G4Material* fFemora_upper;
G4Material* fFemora_lower;
G4Material* fLeg_lower;
G4Material* fFoot;
G4Material* fMandible;
G4Material* fPelvis;
G4Material* fRibs;
G4Material* fScapulae;
G4Material* fSpine_cervical;
G4Material* fSpine_lumbar;
G4Material* fSpine_thoratic;
G4Material* fSacrum;
G4Material* fSternum;
G4Material* fHf_upper;
G4Material* fHf_lower;
G4Material* fMed_lowerleg;
G4Material* fMed_lowerarm;
G4Material* fCartilage;
G4Material* fSkin;
G4Material* fBlood;
G4Material* fMuscle;
G4Material* fLiver;
G4Material* fPancreas;
G4Material* fBrain;
G4Material* fHeart;
G4Material* fEye;
G4Material* fKidney;
G4Material* fStomach;
G4Material* fIntestine_sml;
G4Material* fIntestine_lrg;
G4Material* fSpleen;
G4Material* fThyroid;
G4Material* fBladder;
G4Material* fOvaries_testes;
G4Material* fAdrenals;
G4Material* fOesophagus;
G4Material* fMisc;
G4Material* fUterus_prostate;
G4Material* fLymph;
G4Material* fBreast_glandular;
G4Material* fBreast_adipose;
G4Material* fGastro_content;
G4Material* fUrine;
};
#endif
@@ -0,0 +1,53 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Authors: M. Large, S. Guatelli - University of Wollongong, Australia
//
#ifndef ICRP110PhantomMessenger_h
#define ICRP110PhantomMessenger_h 1
#include "G4UImessenger.hh"
#include "globals.hh"
class ICRP110PhantomConstruction;
class G4UIcommand;
class G4UIdirectory;
class G4UIcmdWithAString;
class ICRP110PhantomMessenger: public G4UImessenger
{
public:
ICRP110PhantomMessenger(ICRP110PhantomConstruction* myUsrPhtm);
~ICRP110PhantomMessenger();
void SetNewValue(G4UIcommand* command, G4String newValue);
private:
ICRP110PhantomConstruction* fUserPhantom;
G4UIdirectory* fPhantomDir;
G4UIcmdWithAString* fSexCmd;
G4UIcmdWithAString* fSectionCmd;
};
#endif
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
// Code based on the extended example DICOM
//
#ifndef ICRP110PhantomNestedParameterisation_HH
#define ICRP110PhantomNestedParameterisation_HH
#include <vector>
#include <map>
#include "G4Types.hh"
#include "G4ThreeVector.hh"
#include "G4VNestedParameterisation.hh"
class G4VPhysicalVolume;
class G4VTouchable;
class G4VSolid;
class G4Material;
class G4VisAttributes;
// CSG Entities which may be parameterised/replicated
class G4Box;
class G4Tubs;
class G4Trd;
class G4Trap;
class G4Cons;
class G4Sphere;
class G4Ellipsoid;
class G4Orb;
class G4Torus;
class G4Para;
class G4Polycone;
class G4Polyhedra;
class G4Hype;
/// Implements a G4VNestedParameterisation
class ICRP110PhantomNestedParameterisation : public G4VNestedParameterisation
{
public:
ICRP110PhantomNestedParameterisation(const G4ThreeVector& voxelSize,
std::vector<G4Material*>& mat,
G4int fnX_ = 0, G4int fnY_ = 0, G4int fnZ_ = 0);
// the total number of voxels along X, Y and Z
// are initialised to zero
~ICRP110PhantomNestedParameterisation();
virtual G4Material* ComputeMaterial(G4VPhysicalVolume *currentVol,
const G4int repNo,
const G4VTouchable *parentTouch );
G4int GetNumberOfMaterials() const;
G4Material* GetMaterial(G4int idx) const;
G4int GetMaterialIndex( G4int copyNo) const;
void SetMaterialIndices( size_t* matInd ){ fMaterialIndices = matInd;}
// This method passes the information of the matID associated to each voxel
// from the DetectorConstruction to the NestedParameterisation class
void SetNoVoxel( G4int nx, G4int ny, G4int nz );
// This method passes the total number of voxels along X, Y and Z from
// the DetectorConstruction to the NestedParameterisation class
void ComputeTransformation(const G4int no,
G4VPhysicalVolume *currentPV) const;
// Additional standard Parameterisation methods,
// which can be optionally defined, in case solid is used.
void ComputeDimensions(G4Box &, const G4int,
const G4VPhysicalVolume *) const;
private: // Dummy declarations to get rid of warnings ...
void ComputeDimensions (G4Trd&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Trap&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Cons&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Sphere&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Ellipsoid&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Orb&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Torus&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Para&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Hype&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Tubs&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Polycone&, const G4int,
const G4VPhysicalVolume*) const {}
void ComputeDimensions (G4Polyhedra&, const G4int,
const G4VPhysicalVolume*) const {}
void ReadColourData();
using G4VNestedParameterisation::ComputeMaterial;
private:
G4double fdX,fdY,fdZ; // Half of the voxels along X, Y and Z
G4int fnX,fnY,fnZ; // Number of voxels along X, Y and Z
std::vector<G4Material*> fMaterials; // Vector with materials
size_t* fMaterialIndices; // Index of the material associated to each voxel
std::map<G4String,G4VisAttributes*> fColours;
};
#endif
@@ -0,0 +1,52 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#ifndef ICRP110PhantomPrimaryGeneratorAction_h
#define ICRP110PhantomPrimaryGeneratorAction_h 1
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4GeneralParticleSource;
class G4Event;
class ICRP110PhantomPrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
ICRP110PhantomPrimaryGeneratorAction();
~ICRP110PhantomPrimaryGeneratorAction();
public:
void GeneratePrimaries(G4Event* anEvent);
private:
G4GeneralParticleSource* fParticleGun;
};
#endif
@@ -0,0 +1,57 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Authors: S.Guatelli, Matthew Large and A. Malaroda, University of Wollongong
//
//
#ifndef ICRP110ScoreWriterMessenger_h
#define ICRP110ScoreWriterMessenger_h 1
#include "G4UImessenger.hh"
#include "globals.hh"
class ICRP110UserScoreWriter;
class G4UIcommand;
class G4UIdirectory;
class G4UIcmdWithAString;
class G4UIcmdWithoutParameter;
class ICRP110ScoreWriterMessenger: public G4UImessenger
{
public:
ICRP110ScoreWriterMessenger(ICRP110UserScoreWriter* myUsrScWriter);
~ICRP110ScoreWriterMessenger();
void SetNewValue(G4UIcommand* command, G4String newValue);
private:
ICRP110UserScoreWriter* fUserScoreWriter;
G4UIdirectory* fPhantomDir;
G4UIcmdWithAString* fSexCmd;
G4UIcmdWithAString* fSectionCmd;
};
#endif
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
// Original code from geant4/examples/extended/runAndEvent/RE03
//
#ifndef ICRP110UserScoreWriter_h
#define ICRP110UserScoreWriter_h 1
#include "ICRP110ScoreWriterMessenger.hh"
#include "globals.hh"
#include "G4VScoreWriter.hh"
class ICRP110UserScoreWriter:public G4VScoreWriter
{
public:
ICRP110UserScoreWriter();
virtual ~ICRP110UserScoreWriter();
// store a quantity into a file
void DumpQuantityToFile(const G4String & psName,
const G4String & fileName,
const G4String & option);
void SetPhantomSex(G4String);
void SetPhantomSection(G4String);
private:
ICRP110ScoreWriterMessenger* fMessenger;
G4String fSex;
G4String fSection;
};
#endif
@@ -0,0 +1,88 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex male
/phantom/setScoreWriterSex male
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection full
/phantom/setScoreWriterSection full
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (2.137, 2.137, 8)mm #
# and there are 254 voxels along x, 127 along y and 222 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths #
# #
# If the user is not building all 222 z-slices of the phantom, they #
# must change the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for #
# the full male phantom with 222 single slices in z. #
# #
#################################################################################
/score/mesh/boxSize 271.399 135.6995 888. mm
/score/mesh/nBin 254 127 222
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
#/score/quantity/energyDeposit energyDeposit
/score/quantity/doseDeposit doseDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 1000
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
#/score/dumpQuantityToFile PhantomMesh energyDeposit PhantomMesh_Edep.txt
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,88 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex male
/phantom/setScoreWriterSex male
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection head
/phantom/setScoreWriterSection head
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (2.137, 2.137, 8)mm #
# and there are 254 voxels along x, 127 along y and 222 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths #
# #
# If the user is not building all 222 z-slices of the phantom, they #
# must change the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for a #
# male partial head phantom with 30 slices in z. #
# #
#################################################################################
/score/mesh/boxSize 271.399 135.6995 120. mm
/score/mesh/nBin 254 127 30
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
#/score/quantity/energyDeposit energyDeposit
/score/quantity/doseDeposit doseDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 100
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
#/score/dumpQuantityToFile PhantomMesh energyDeposit PhantomMesh_Edep.txt
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,88 @@
#---------------------------------------#
#-------------Select Phantom------------#
#---------------------------------------#
# Choose phantom sex (male or female)
/phantom/setPhantomSex male
/phantom/setScoreWriterSex male
# Choose phantom section (head, trunk or full)
/phantom/setPhantomSection trunk
/phantom/setScoreWriterSection trunk
#---------------------------------------#
#------------Initialization-------------#
#---------------------------------------#
/run/initialize
/control/verbose 1
/tracking/verbose 0
/run/verbose 0
/event/verbose 0
#---------------------------------------#
#-------------Visualisation-------------#
#---------------------------------------#
# Visualize Phantom with OPENGL
# /control/execute openGLVis.mac
#
#---------------------------------------#
#---------Radiation Environment---------#
#---------------------------------------#
# Call upon definition of primary beam
/control/execute primary.mac
#
#---------------------------------------#
#------Create Phantom Scoring Mesh------#
#---------------------------------------#
/score/create/boxMesh PhantomMesh
#################################################################################
# #
# The phantom voxels have dimensions (x,y,z) = (2.137, 2.137, 8)mm #
# and there are 254 voxels along x, 127 along y and 222 along z in #
# the full phantom. Mesh dimensions, however, are to be specified as #
# half-lengths #
# #
# If the user is not building all 222 z-slices of the phantom, they #
# must change the boxSize in z and the nBins in z to match the geometry of #
# the phantom in which they have simulated. Below, the mesh is defined for a #
# male partial trunk phantom with 50 slices in z. #
# #
#################################################################################
/score/mesh/boxSize 271.399 135.6995 200. mm
/score/mesh/nBin 254 127 50
/score/mesh/translate/xyz 0. 0. 0. mm
# Choose the quantity to score via mesh
#/score/quantity/energyDeposit energyDeposit
/score/quantity/doseDeposit doseDeposit
# Close Scorer
/score/close
/score/list
#
#---------------------------------------#
#----------Run Beam-On Command----------#
#---------------------------------------#
# Chooose number of events
/run/beamOn 100
#
#---------------------------------------#
#-------Visualising Scoring Mesh--------#
#---------------------------------------#
# You can also enter the below commands in the GUI
# when running the simulation in interactive mode
#
#/score/drawProjection PhantomMesh energyDeposit
#/score/drawProjection PhantomMesh doseDeposit
#---------------------------------------#
#----Dump Scoring Mesh Data to File-----#
#---------------------------------------#
#/score/dumpQuantityToFile PhantomMesh energyDeposit PhantomMesh_Edep.txt
/score/dumpQuantityToFile PhantomMesh doseDeposit PhantomMesh_Dose.txt
@@ -0,0 +1,77 @@
# Use this open statement to create an OpenGL view:
/run/initialize
#/vis/open OGLSX
/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
#
# Define background colour (comment out for black as default)
#/vis/viewer/set/background white
#
# Draw geometry:
/vis/drawVolume worlds
#
# Specify view angle:
/vis/viewer/set/viewpointThetaPhi 85 -75 deg
#/vis/viewer/set/lightsMove with-camera
#
# Set Voxels number to be visualised
/vis/ogl/set/displayListLimit 4000000
# 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
@@ -0,0 +1,14 @@
#
### Radiation field defined
### by means of GPS
/gps/verbose 0
### Generates Pencil beam of 200MeV protons by default
### Proton pencil beam is incident on far left side of the phantom
### (x = -27 cm)and centered in y and z
/gps/particle proton
/gps/energy 250 MeV
/gps/pos/centre -27. 0. 0. cm
/gps/direction 1 0 0
@@ -0,0 +1,45 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#include "ICRP110PhantomActionInitialization.hh"
#include "ICRP110PhantomPrimaryGeneratorAction.hh"
ICRP110PhantomActionInitialization::ICRP110PhantomActionInitialization():
G4VUserActionInitialization()
{}
ICRP110PhantomActionInitialization::~ICRP110PhantomActionInitialization()
{}
void ICRP110PhantomActionInitialization::BuildForMaster() const
{}
void ICRP110PhantomActionInitialization::Build() const
{
SetUserAction(new ICRP110PhantomPrimaryGeneratorAction);
}
@@ -0,0 +1,809 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#include <map>
#include <cstdlib>
#include "globals.hh"
#include "ICRP110PhantomConstruction.hh"
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
#include "ICRP110PhantomMaterial_Female.hh"
#include "ICRP110PhantomMaterial_Male.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVParameterised.hh"
#include "ICRP110PhantomNestedParameterisation.hh"
ICRP110PhantomConstruction::ICRP110PhantomConstruction():
fNVoxelX(0), fNVoxelY(0), fNVoxelZ(0),
fVoxelHalfDimX(0), fVoxelHalfDimY(0), fVoxelHalfDimZ(0),
fMinX(0),fMaxX(0), fMinY(0), fMaxY(0),
fMinZ(0), fMaxZ(0), fNoFiles(0), fNVoxels(0),
fMateIDs(0)
{
fMessenger = new ICRP110PhantomMessenger(this);
// the messenger allows to set the sex of the phantom
// interactively
fMaterial_Female = new ICRP110PhantomMaterial_Female();
fMaterial_Male = new ICRP110PhantomMaterial_Male();
fSex = "female"; // Female phantom is the default option
fSection = "head"; // Head partial phantom is the default option
}
ICRP110PhantomConstruction::~ICRP110PhantomConstruction()
{
delete fMaterial_Female;
delete fMaterial_Male;
delete fMessenger;
}
G4VPhysicalVolume* ICRP110PhantomConstruction::Construct()
{
// Define Material Air
G4double A; // atomic mass
G4double Z; // atomic number
G4double d; // density
A = 14.01*g/mole;
G4Element* elN = new G4Element("Nitrogen","N",Z = 7.,A);
A = 16.00*g/mole;
G4Element* elO = new G4Element("Oxygen","O",Z = 8.,A);
d = 0.001 *g/cm3;
G4Material* matAir = new G4Material("Air",d,2);
matAir -> AddElement(elN,0.8);
matAir -> AddElement(elO,0.2);
std::vector<G4Material*> pMaterials;
if(fSex == "female"){
fMaterial_Female -> DefineMaterials();
//----- Store materials in a vector
pMaterials.push_back(matAir);
pMaterials.push_back(fMaterial_Female -> GetMaterial("teeth"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("bone"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("humeri_upper"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("humeri_lower"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("arm_lower"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("hand"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("clavicle"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("cranium"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("femora_upper"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("femora_lower"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("leg_lower"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("foot"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("mandible"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("pelvis"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("ribs"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("scapulae"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("spine_cervical"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("spine_thoratic"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("spine_lumbar"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("sacrum"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("sternum"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("hf_upper"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("hf_lower"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("med_lowerarm"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("med_lowerleg"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("cartilage"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("skin"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("blood"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("muscle"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("liver"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("pancreas"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("brain"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("heart"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("eye"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("kidney"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("stomach"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("intestine_sml"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("intestine_lrg"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("spleen"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("thyroid"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("bladder"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("ovaries_testes"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("adrenals"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("oesophagus"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("misc"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("uterus_prostate"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("lymph"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("breast_glandular"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("breast_adipose"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("lung"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("gastro_content"));
pMaterials.push_back(fMaterial_Female -> GetMaterial("urine"));
}
else if (fSex == "male"){
// MATT do the same here
fMaterial_Male -> DefineMaterials();
//----- Store materials in a vector
pMaterials.push_back(matAir);
pMaterials.push_back(fMaterial_Male -> GetMaterial("teeth"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("bone"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("humeri_upper"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("humeri_lower"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("arm_lower"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("hand"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("clavicle"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("cranium"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("femora_upper"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("femora_lower"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("leg_lower"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("foot"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("mandible"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("pelvis"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("ribs"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("scapulae"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("spine_cervical"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("spine_thoratic"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("spine_lumbar"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("sacrum"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("sternum"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("hf_upper"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("hf_lower"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("med_lowerarm"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("med_lowerleg"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("cartilage"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("skin"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("blood"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("muscle"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("liver"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("pancreas"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("brain"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("heart"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("eye"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("kidney"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("stomach"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("intestine_sml"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("intestine_lrg"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("spleen"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("thyroid"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("bladder"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("ovaries_testes"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("adrenals"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("oesophagus"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("misc"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("uterus_prostate"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("lymph"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("breast_glandular"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("breast_adipose"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("lung"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("gastro_content"));
pMaterials.push_back(fMaterial_Male -> GetMaterial("urine"));
}
// World Volume
G4double worldSize = 2.*m ;
G4Box* world = new G4Box("world", worldSize, worldSize, worldSize);
G4LogicalVolume* logicWorld = new G4LogicalVolume(world,
matAir,
"logicalWorld", 0, 0,0);
G4VPhysicalVolume* motherVolume = new G4PVPlacement(0,G4ThreeVector(),
"physicalWorld",
logicWorld,
0,
false,
0);
logicWorld -> SetVisAttributes(G4VisAttributes::GetInvisible());
G4cout << "World has been built" << G4endl;
G4cout << "Phantom Sex: " << fSex << G4endl;
G4cout << "Phantom Section: " << fSection << G4endl;
ReadPhantomData(fSex, fSection);
G4cout << "Number of X,Y,Z voxels = " << fNVoxelX << ", " << fNVoxelY << ", " << fNVoxelZ << G4endl;
//----- Define the volume that contains all the voxels
G4Box* fContainer_solid = new G4Box("phantomContainer",fNVoxelX*fVoxelHalfDimX*mm,
fNVoxelY*fVoxelHalfDimY*mm,
fNVoxelZ*fVoxelHalfDimZ*mm);
G4LogicalVolume* fContainer_logic = new G4LogicalVolume( fContainer_solid,
matAir,
"phantomContainer",
0, 0, 0 );
fMaxX = fNVoxelX*fVoxelHalfDimX*mm; // Max X along X axis of the voxelised geometry
fMaxY = fNVoxelY*fVoxelHalfDimY*mm; // Max Y
fMaxZ = fNVoxelZ*fVoxelHalfDimZ*mm; // Max Z
fMinX = -fNVoxelX*fVoxelHalfDimX*mm;// Min X
fMinY = -fNVoxelY*fVoxelHalfDimY*mm;// Min Y
fMinZ = -fNVoxelZ*fVoxelHalfDimZ*mm;// Min Z
G4ThreeVector posCentreVoxels((fMinX+fMaxX)/2.,(fMinY+fMaxY)/2.,(fMinZ+fMaxZ)/2.);
G4cout << " placing voxel container volume at " << posCentreVoxels << G4endl;
new G4PVPlacement(0, // rotation
posCentreVoxels,
fContainer_logic, // The logic volume
"phantomContainer", // Name
logicWorld, // Mother
false, // No op. bool.
1); // Copy number
fContainer_logic -> SetVisAttributes(new G4VisAttributes(G4Colour(1.,0.,0.,0.)));
// Define the voxelised phantom here
// Replication of air Phantom Volume.
//--- Slice the phantom along Y axis
G4String yRepName("RepY");
G4VSolid* solYRep = new G4Box(yRepName,fNVoxelX*fVoxelHalfDimX,
fVoxelHalfDimY, fNVoxelZ*fVoxelHalfDimZ);
G4LogicalVolume* logYRep = new G4LogicalVolume(solYRep,matAir,yRepName);
new G4PVReplica(yRepName,logYRep,fContainer_logic,kYAxis, fNVoxelY,fVoxelHalfDimY*2.);
logYRep -> SetVisAttributes(new G4VisAttributes(G4VisAttributes::GetInvisible()));
//--- Slice the phantom along X axis
G4String xRepName("RepX");
G4VSolid* solXRep = new G4Box(xRepName,fVoxelHalfDimX,fVoxelHalfDimY,
fNVoxelZ*fVoxelHalfDimZ);
G4LogicalVolume* logXRep = new G4LogicalVolume(solXRep,matAir,xRepName);
new G4PVReplica(xRepName,logXRep,logYRep,kXAxis,fNVoxelX,fVoxelHalfDimX*2.);
logXRep -> SetVisAttributes(new G4VisAttributes(G4VisAttributes::GetInvisible()));
//----- Voxel solid and logical volumes
//--- Slice along Z axis
G4VSolid* solidVoxel = new G4Box("phantom",fVoxelHalfDimX, fVoxelHalfDimY,fVoxelHalfDimZ);
G4LogicalVolume* logicVoxel = new G4LogicalVolume(solidVoxel,matAir,"phantom");
logicVoxel -> SetVisAttributes(new G4VisAttributes(G4VisAttributes::GetInvisible()));
// Parameterisation to define the material of each voxel
G4ThreeVector halfVoxelSize(fVoxelHalfDimX,fVoxelHalfDimY,fVoxelHalfDimZ);
ICRP110PhantomNestedParameterisation* param = new ICRP110PhantomNestedParameterisation(halfVoxelSize, pMaterials);
new G4PVParameterised("phantom", // their name
logicVoxel, // their logical volume
logXRep, // Mother logical volume
kZAxis, // Are placed along this axis
fNVoxelZ, // Number of cells
param); // Parameterisation
param -> SetMaterialIndices(fMateIDs); // fMateIDs is the vector with Material ID associated to each voxel, from ASCII input data files.
param -> SetNoVoxel(fNVoxelX,fNVoxelY,fNVoxelZ);
return motherVolume;
}
void ICRP110PhantomConstruction::ReadPhantomData(const G4String& sex, const G4String& section)
{
// This method reads the information of ICRPdata/FemaleData.dat or
// ICRPdata/MaleData.data depending on the sex of the chosen phantom
fSex = sex;
fSection = section;
G4String dataFile;
if (fSex == "female")
{
if (fSection == "head")
{
dataFile = "ICRPdata/FemaleHead.dat";
}
else if (fSection == "trunk")
{
dataFile = "ICRPdata/FemaleTrunk.dat";
}
else if (fSection == "full")
{
dataFile = "ICRPdata/FemaleData.dat";
}
}
if (fSex == "male")
{
if (fSection == "head")
{
dataFile = "ICRPdata/MaleHead.dat";
}
else if (fSection == "trunk")
{
dataFile = "ICRPdata/MaleTrunk.dat";
}
else if (fSection == "full")
{
dataFile = "ICRPdata/MaleData.dat";
}
}
G4cout << "Data file " << dataFile << " is read by Detector Construction." << G4endl;
// The data.dat file in directory/build/ICRPdata/ contains the information
// to build the phantoms. For more details look in the README file.
//input file named finDF which consists of dataFile as a string object
std::ifstream finDF(dataFile.c_str());
G4String fname;
if(finDF.good() != 1 ) //check that the file is good and working
{
G4String descript = "Problem reading data file: "+dataFile;
G4Exception(" HumanPhantomConstruction::ReadPhantomData"," ",
FatalException,descript);
}
finDF >> fNoFiles;
G4cout << "Number of files = " << fNoFiles << G4endl;
finDF >> fNVoxelX; //Inputs number of X-Voxels
finDF >> fNVoxelY; //Y-Voxels
fNVoxelZ = fNoFiles; //Z-Voxels (equal to number of slice files built/read)
finDF >> fVoxelHalfDimX;
finDF >> fVoxelHalfDimY;
finDF >> fVoxelHalfDimZ;
G4cout << "Number of X,Y,Z voxels = " << fNVoxelX << ", " << fNVoxelY << ", " << fNVoxelZ <<G4endl;
fNVoxels = fNVoxelX*fNVoxelY*fNVoxelZ;
G4cout << "Total Number of Voxels = " << fNVoxels << G4endl;
G4int nMaterials;
finDF >> nMaterials;
G4String mateName;
G4int nmate;
//-----Read materials and associate with material ID number------//
for( G4int ii = 0; ii < nMaterials; ii++ ){
finDF >> nmate;
finDF >> mateName;
// This allows to skip empty spaces and tabs in the string
if( mateName[0] == '"' && mateName[mateName.length()-1] == '"' )
{
mateName = mateName.substr(1,mateName.length()-2);
}
// To uncomment for eventual debugging
/* G4cout << "GmReadPhantomG4Geometry::ReadPhantomData reading nmate "
<< ii << " = " << nmate
<< " mate " << mateName << G4endl;*/
if( ii != nmate ) {
G4Exception("GmReadPhantomG4Geometry::ReadPhantomData",
"Wrong argument",
FatalErrorInArgument,
"Material number should be in increasing order:wrong material number");
}
}
fMateIDs = new size_t[fNVoxels]; //Array with Material ID for each voxel
G4cout << "ICRP110PhantomConstruction::ReadPhantomDataFile is openining the following phantom files: " << G4endl;
for(G4int i = 0; i < fNoFiles; i++ )
{
finDF >> fname;
ReadPhantomDataFile(fSex, fname, i);
}
finDF.close();
}
//----------------Opens phantom ASCII slice files to construct the phantom from-----------------//
void ICRP110PhantomConstruction::ReadPhantomDataFile(const G4String& sex, const G4String& fileName, G4int numberFile)
{
G4cout << fileName << G4endl;
fSex = sex;
G4String slice;
if (fSex == "female")
{
slice = "ICRPdata/ICRP110_g4dat/AF/"+fileName;
}
if (fSex == "male")
{
slice = "ICRPdata/ICRP110_g4dat/AM/"+fileName;
}
std::ifstream fin(slice.c_str(), std::ios_base::in);
if( !fin.is_open() ) {
G4Exception("HumanPhantomConstruction::ReadPhantomDataFile",
"",
FatalErrorInArgument,
G4String("File not found " + fileName ).c_str());
}
for( G4int iy = 0; iy < fNVoxelY; iy++ ) {
for( G4int ix = 0; ix < fNVoxelX; ix++ ) {
if (ix == 0 && iy == 0)
{
G4int dudX,dudY,dudZ;
fin >> dudX >> dudY >> dudZ ;
// Dummy method to skip the first three lines of the files
// which are not used here
}
else{
G4int nnew = ix + (iy)*fNVoxelX + numberFile*fNVoxelX*fNVoxelY;
G4int OrgID;
fin >> OrgID;
G4int mateID_out;
// The code below associates organ ID numbers (called here mateID) from ASCII slice
// files with material ID numbers (called here mateID_out) as defined in ICRP110PhantomMaterials
// Material and Organ IDs are associated as stated in AM_organs.dat and FM_organs.dat depending on
// the sex of the phantom (male and female, respctively)
if (OrgID==128)
{
mateID_out=1;
}
else if (OrgID==13 || OrgID==16 || OrgID==19 || OrgID==22 || OrgID==24 || OrgID==26 || OrgID==28 || OrgID==31 || OrgID==34 || OrgID==37 || OrgID==39 || OrgID==41 || OrgID==43 || OrgID==45 || OrgID==47 || OrgID==49 || OrgID==51 || OrgID==53 || OrgID==55)
{
mateID_out=2;
}
else if (OrgID==14)
{
mateID_out=3;
}
else if (OrgID==17)
{
mateID_out=4;
}
else if (OrgID==20)
{
mateID_out=5;
}
else if (OrgID==23)
{
mateID_out=6;
}
else if (OrgID==25)
{
mateID_out=7;
}
else if (OrgID==27)
{
mateID_out=8;
}
else if (OrgID==29)
{
mateID_out=9;
}
else if (OrgID==32)
{
mateID_out=10;
}
else if (OrgID==35)
{
mateID_out=11;
}
else if (OrgID==38)
{
mateID_out=12;
}
else if (OrgID==40)
{
mateID_out=13;
}
else if (OrgID==42)
{
mateID_out=14;
}
else if (OrgID==44)
{
mateID_out=15;
}
else if (OrgID==46)
{
mateID_out=16;
}
else if (OrgID==48)
{
mateID_out=17;
}
else if (OrgID==50)
{
mateID_out=18;
}
else if (OrgID==52)
{
mateID_out=19;
}
else if (OrgID==54)
{
mateID_out=20;
}
else if (OrgID==56)
{
mateID_out=21;
}
else if (OrgID==15 || OrgID==30)
{
mateID_out=22;
}
else if (OrgID==18 || OrgID==33)
{
mateID_out=23;
}
else if (OrgID==21)
{
mateID_out=24;
}
else if (OrgID==36)
{
mateID_out=25;
}
else if (OrgID==57 || OrgID==58 || OrgID==59 || OrgID==60)
{
mateID_out=26;
}
else if (OrgID==122 || OrgID==123 || OrgID==124 || OrgID==125 || OrgID==141 )
{
mateID_out=27;
}
else if (OrgID==9 || OrgID==10 || OrgID==11 || OrgID==12 || OrgID==88 || OrgID==96 || OrgID==98)
{
mateID_out=28;
}
else if (OrgID==5 || OrgID==6 || OrgID==106 || OrgID==107 || OrgID==108 || OrgID==109 || OrgID==133)
{
mateID_out=29;
}
else if (OrgID==95)
{
mateID_out=30;
}
else if (OrgID==113)
{
mateID_out=31;
}
else if (OrgID==61)
{
mateID_out=32;
}
else if (OrgID==87)
{
mateID_out=33;
}
else if (OrgID==66 || OrgID==67 || OrgID==68 || OrgID==69)
{
mateID_out=34;
}
else if (OrgID==89 || OrgID==90 || OrgID==91 || OrgID==92 || OrgID==93 || OrgID==94)
{
mateID_out=35;
}
else if (OrgID==72)
{
mateID_out=36;
}
else if (OrgID==74)
{
mateID_out=37;
}
else if (OrgID==76 || OrgID==78 || OrgID==80 || OrgID==82 || OrgID==84 || OrgID==86)
{
mateID_out=38;
}
else if (OrgID==127)
{
mateID_out=39;
}
else if (OrgID==132)
{
mateID_out=40;
}
else if (OrgID==137)
{
mateID_out=41;
}
else if (OrgID==111 || OrgID==112 || OrgID==129 || OrgID==130)
{
mateID_out=42;
}
else if (OrgID==1 || OrgID==2)
{
mateID_out=43;
}
else if (OrgID==110)
{
mateID_out=44;
}
else if (OrgID==3 || OrgID==4 || OrgID==7 || OrgID==8 || OrgID==70 || OrgID==71 || OrgID==114 || OrgID==120 || OrgID==121 || OrgID==126 || OrgID==131 || OrgID==134 || OrgID==135 || OrgID == 136)
{
mateID_out=45;
}
else if (OrgID==115 || OrgID==139)
{
mateID_out=46;
}
else if (OrgID==100 || OrgID==101 || OrgID==102 || OrgID==103 || OrgID==104 || OrgID==105)
{
mateID_out=47;
}
else if (OrgID==63 || OrgID==65)
{
mateID_out=48;
}
else if (OrgID==62 || OrgID==64 || OrgID==116 || OrgID==117 || OrgID==118 || OrgID==119)
{
mateID_out=49;
}
else if (OrgID==97 || OrgID==99)
{
mateID_out=50;
}
else if (OrgID==73 || OrgID==75 || OrgID==77 || OrgID==79 || OrgID==81 || OrgID==83 || OrgID==85)
{
mateID_out=51;
}
else if (OrgID==138)
{
mateID_out=52;
}
else if (OrgID==0 || OrgID==140)
{
mateID_out=0;
}
else
{
mateID_out=OrgID;
}
G4int nMaterials = 53;
if( mateID_out < 0 || mateID_out >= nMaterials ) {
G4Exception("GmReadPhantomG4Geometry::ReadPhantomData",
"Wrong index in phantom file",
FatalException,
G4String("It should be between 0 and "
+ G4UIcommand::ConvertToString(nMaterials-1)
+ ", while it is "
+ G4UIcommand::ConvertToString(OrgID)).c_str());
//-------------Store Material IDs and position/reference number within phantom in vector---------------//
}
fMateIDs[nnew] = mateID_out;
}
}
}
}
//-----------Define phantom sex (male or female) to be constructed-------------//
void ICRP110PhantomConstruction::SetPhantomSex(G4String newSex)
{
fSex = newSex;
if (fSex == "male")
{
G4cout << ">> Male Phantom will be built." << G4endl;
}
if (fSex == "female")
{
G4cout << ">> Female Phantom will be built." << G4endl;
}
if ((fSex != "female") && (fSex != "male"))
G4cout << fSex << " is not defined!" << G4endl;
}
//-----------Define phantom section to be constructed-------------//
void ICRP110PhantomConstruction::SetPhantomSection(G4String newSection)
{
fSection = newSection;
if (fSection == "head")
{
G4cout << ">> Partial Head Phantom will be built." << G4endl;
}
if (fSection == "trunk")
{
G4cout << ">> Partial Trunk Phantom will be built." << G4endl;
}
if (fSection == "full")
{
G4cout << ">> Full/Custom Phantom will be built." << G4endl;
}
if ((fSection != "head") && (fSection != "trunk") && (fSection != "full"))
G4cout << fSection << " is not defined!" << G4endl;
}
@@ -0,0 +1,799 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//
#include "ICRP110PhantomMaterial_Female.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4MaterialPropertyVector.hh"
#include "G4MaterialTable.hh"
#include "Randomize.hh"
#include "G4RunManager.hh"
#include "G4Element.hh"
#include "G4ElementTable.hh"
ICRP110PhantomMaterial_Female::ICRP110PhantomMaterial_Female():
fLung(nullptr), fTeeth(nullptr), fBone(nullptr), fHumeri_upper(nullptr), fHumeri_lower(nullptr),
fArm_lower(nullptr), fHand(nullptr), fClavicle(nullptr), fCranium(nullptr), fFemora_upper(nullptr),
fFemora_lower(nullptr), fLeg_lower(nullptr), fFoot(nullptr), fMandible(nullptr),
fPelvis(nullptr), fRibs(nullptr), fScapulae(nullptr), fSpine_cervical(nullptr),
fSpine_lumbar(nullptr), fSpine_thoratic(nullptr), fSacrum(nullptr),
fSternum(nullptr), fHf_upper(nullptr), fHf_lower(nullptr), fMed_lowerleg(nullptr),
fMed_lowerarm(nullptr), fCartilage(nullptr), fSkin(nullptr), fBlood(nullptr),
fMuscle(nullptr), fLiver(nullptr), fPancreas(nullptr), fBrain(nullptr), fHeart(nullptr), fEye(nullptr),
fKidney(nullptr), fStomach(nullptr), fIntestine_sml(nullptr), fIntestine_lrg(nullptr),
fSpleen(nullptr), fThyroid(nullptr), fBladder(nullptr), fOvaries_testes(nullptr), fAdrenals(nullptr),
fOesophagus(nullptr), fMisc(nullptr), fUterus_prostate(nullptr), fLymph(nullptr),
fBreast_glandular(nullptr), fBreast_adipose(nullptr), fGastro_content(nullptr),
fUrine(nullptr)
{;}
ICRP110PhantomMaterial_Female::~ICRP110PhantomMaterial_Female()
{;}
void ICRP110PhantomMaterial_Female::DefineMaterials()
{
// Define required materials
G4double A; // atomic mass
G4double Z; // atomic number
G4double d; // density
// General elements
A = 1.01*g/mole;
G4Element* elH = new G4Element ("Hydrogen","H",Z = 1.,A);
A = 12.011*g/mole;
G4Element* elC = new G4Element("Carbon","C",Z = 6.,A);
A = 14.01*g/mole;
G4Element* elN = new G4Element("Nitrogen","N",Z = 7.,A);
A = 16.00*g/mole;
G4Element* elO = new G4Element("Oxygen","O",Z = 8.,A);
A = 22.99*g/mole;
G4Element* elNa = new G4Element("Sodium","Na",Z = 11.,A);
A = 24.305*g/mole;
G4Element* elMg = new G4Element("Magnesium","Mg",Z = 12.,A);
A = 30.974*g/mole;
G4Element* elP = new G4Element("Phosphorus","P",Z = 15.,A);
A = 32.064*g/mole;
G4Element* elS = new G4Element("Sulfur","S",Z = 16.,A);
A = 35.453*g/mole;
G4Element* elCl = new G4Element("Chlorine","Cl",Z = 17.,A);
A = 39.098*g/mole;
G4Element* elK = new G4Element("Potassium","K",Z = 19.,A);
A = 40.08*g/mole;
G4Element* elCa = new G4Element("Calcium","Ca",Z = 20.,A);
A = 55.85*g/mole;
G4Element* elFe = new G4Element("Iron","Fe",Z = 26.,A);
A = 126.90447 *g/mole;
G4Element*elI = new G4Element("Iodine","I", Z = 53.,A);
//Added tissues for phantom including their tissue ID
//Teeth -> Tissue ID 1
d = 2.750 *g/cm3;
fTeeth = new G4Material("teeth",d,7);
fTeeth -> AddElement(elH,0.022);
fTeeth -> AddElement(elC,0.095);
fTeeth -> AddElement(elN,0.029);
fTeeth -> AddElement(elO,0.421);
fTeeth -> AddElement(elMg,0.007);
fTeeth -> AddElement(elP,0.137);
fTeeth -> AddElement(elCa,0.289);
//Mineral Bone -> Tissue ID 2
d = 1.920 *g/cm3;
fBone = new G4Material("bone",d,9);
fBone -> AddElement(elH,0.036);
fBone -> AddElement(elC,0.159);
fBone -> AddElement(elN,0.042);
fBone -> AddElement(elO,0.448);
fBone -> AddElement(elNa,0.003);
fBone -> AddElement(elMg,0.002);
fBone -> AddElement(elP,0.094);
fBone -> AddElement(elS,0.003);
fBone -> AddElement(elH,0.213);
//Humeri, upper half, spongiosa -> ID 3
d = 1.185 *g/cm3;
fHumeri_upper = new G4Material("humeri_upper",d,11);
fHumeri_upper -> AddElement(elH,0.087) ;
fHumeri_upper -> AddElement(elC,0.366);
fHumeri_upper -> AddElement(elN,0.025);
fHumeri_upper -> AddElement(elO,0.422);
fHumeri_upper -> AddElement(elNa,0.002);
fHumeri_upper -> AddElement(elMg,0.001);
fHumeri_upper -> AddElement(elP,0.030);
fHumeri_upper -> AddElement(elS,0.003);
fHumeri_upper -> AddElement(elCl,0.001);
fHumeri_upper -> AddElement(elK, 0.001);
fHumeri_upper -> AddElement(elCa,0.062);
//Humeri, lower half, spongiosa -> ID 4
d = 1.117 *g/cm3;
fHumeri_lower = new G4Material("humeri_lower",d,9);
fHumeri_lower -> AddElement(elH,0.096);
fHumeri_lower -> AddElement(elC,0.473);
fHumeri_lower -> AddElement(elN,0.017);
fHumeri_lower -> AddElement(elO,0.341);
fHumeri_lower -> AddElement(elNa,0.002);
fHumeri_lower -> AddElement(elP,0.022);
fHumeri_lower -> AddElement(elS,0.002);
fHumeri_lower -> AddElement(elCl,0.001);
fHumeri_lower -> AddElement(elCa,0.046);
//Lower arm bones, spongiosa -> ID 5
d = 1.117 *g/cm3;
fArm_lower = new G4Material("arm_lower",d,9);
fArm_lower -> AddElement(elH,0.096);
fArm_lower -> AddElement(elC,0.473);
fArm_lower -> AddElement(elN,0.017);
fArm_lower -> AddElement(elO,0.341);
fArm_lower -> AddElement(elNa,0.002);
fArm_lower -> AddElement(elP,0.022);
fArm_lower -> AddElement(elS,0.002);
fArm_lower -> AddElement(elCl,0.001);
fArm_lower -> AddElement(elCa,0.046);
//Hand Bones, Spongiosa ->ID 6
d = 1.117 *g/cm3;
fHand = new G4Material("hand",d,9);
fHand -> AddElement(elH,0.096);
fHand -> AddElement(elC,0.473);
fHand -> AddElement(elN,0.017);
fHand -> AddElement(elO,0.341);
fHand -> AddElement(elNa,0.002);
fHand -> AddElement(elP,0.022);
fHand -> AddElement(elS,0.002);
fHand -> AddElement(elCl,0.001);
fHand -> AddElement(elCa,0.046);
//Clavicles, spongiosa -> ID 7
d = 1.191 *g/cm3;
fClavicle = new G4Material("clavicle",d,11);
fClavicle -> AddElement(elH,0.087);
fClavicle -> AddElement(elC,0.361);
fClavicle -> AddElement(elN,0.025);
fClavicle -> AddElement(elO,0.424);
fClavicle -> AddElement(elNa,0.002);
fClavicle -> AddElement(elMg,0.001);
fClavicle -> AddElement(elP,0.031);
fClavicle -> AddElement(elS,0.003);
fClavicle -> AddElement(elCl,0.001);
fClavicle -> AddElement(elK,0.001);
fClavicle -> AddElement(elCa,0.064);
// Cranium, spongiosa -> ID 8
d = 1.245 *g/cm3;
fCranium = new G4Material("cranium",d,11);
fCranium -> AddElement(elH,0.081);
fCranium -> AddElement(elC,0.317);
fCranium -> AddElement(elN,0.028);
fCranium -> AddElement(elO,0.451);
fCranium -> AddElement(elNa,0.002);
fCranium -> AddElement(elMg, 0.001);
fCranium -> AddElement(elP,0.037);
fCranium -> AddElement(elS,0.003);
fCranium -> AddElement(elCl,0.001);
fCranium -> AddElement(elK,0.001);
fCranium -> AddElement(elCa,0.078);
//Femora, upper half, spongiosa -> ID 9
d = 1.046 *g/cm3;
fFemora_upper = new G4Material("femora_upper",d,10);
fFemora_upper -> AddElement(elH,0.104);
fFemora_upper -> AddElement(elC,0.496);
fFemora_upper -> AddElement(elN,0.018);
fFemora_upper -> AddElement(elO,0.349);
fFemora_upper -> AddElement(elNa,0.001);
fFemora_upper -> AddElement(elP,0.009);
fFemora_upper -> AddElement(elS,0.002);
fFemora_upper -> AddElement(elCl,0.001);
fFemora_upper -> AddElement(elK,0.001);
fFemora_upper -> AddElement(elCa,0.019);
//Femora, lower half, spongiosa -> ID 10
d = 1.117 *g/cm3;
fFemora_lower = new G4Material("femora_lower",d,9);
fFemora_lower -> AddElement(elH,0.096);
fFemora_lower -> AddElement(elC,0.473);
fFemora_lower -> AddElement(elN,0.017);
fFemora_lower -> AddElement(elO,0.341);
fFemora_lower -> AddElement(elNa,0.002);
fFemora_lower -> AddElement(elP,0.022);
fFemora_lower -> AddElement(elS,0.002);
fFemora_lower -> AddElement(elCl,0.001);
fFemora_lower -> AddElement(elCa,0.046);
//Lower leg bones, spongiosa -> ID 11
d = 1.117 *g/cm3;
fLeg_lower = new G4Material("leg_lower",d,9);
fLeg_lower -> AddElement(elH,0.096);
fLeg_lower -> AddElement(elC,0.473);
fLeg_lower -> AddElement(elN,0.017);
fLeg_lower -> AddElement(elO,0.341);
fLeg_lower -> AddElement(elNa,0.002);
fLeg_lower -> AddElement(elP,0.022);
fLeg_lower -> AddElement(elS,0.002);
fLeg_lower -> AddElement(elCl,0.001);
fLeg_lower -> AddElement(elCa,0.046);
//Foot bones, spongiosa ->ID 12
d = 1.117 *g/cm3;
fFoot = new G4Material("foot",d,9);
fFoot -> AddElement(elH,0.096);
fFoot -> AddElement(elC,0.473);
fFoot -> AddElement(elN,0.017);
fFoot -> AddElement(elO,0.341);
fFoot -> AddElement(elNa,0.002);
fFoot -> AddElement(elP,0.022);
fFoot -> AddElement(elS,0.002);
fFoot -> AddElement(elCl,0.001);
fFoot -> AddElement(elCa,0.046);
//Mandible, spongiosa -> ID 13
d = 1.189 *g/cm3;
fMandible = new G4Material("mandible",d,11);
fMandible -> AddElement(elH,0.087);
fMandible -> AddElement(elC,0.357);
fMandible -> AddElement(elN,0.026);
fMandible -> AddElement(elO,0.429);
fMandible -> AddElement(elNa,0.002);
fMandible -> AddElement(elMg,0.001);
fMandible -> AddElement(elP,0.030);
fMandible -> AddElement(elS,0.003);
fMandible -> AddElement(elCl,0.001);
fMandible -> AddElement(elK,0.001);
fMandible -> AddElement(elCa,0.063);
//Pelvis, Spongiosa -> ID 14
d = 1.109 *g/cm3;
fPelvis = new G4Material("pelvis",d,10);
fPelvis -> AddElement(elH,0.096);
fPelvis -> AddElement(elC,0.406);
fPelvis -> AddElement(elN,0.025);
fPelvis -> AddElement(elO,0.412);
fPelvis -> AddElement(elNa,0.001);
fPelvis -> AddElement(elP,0.018);
fPelvis -> AddElement(elS,0.002);
fPelvis -> AddElement(elCl,0.001);
fPelvis -> AddElement(elK,0.001);
fPelvis -> AddElement(elCa,0.038);
//Ribs, spongiosa -> ID 15
d = 1.092 *g/cm3;
fRibs = new G4Material("ribs",d,11);
fRibs -> AddElement(elH,0.097);
fRibs -> AddElement(elC,0.381);
fRibs -> AddElement(elN,0.028);
fRibs -> AddElement(elO,0.445);
fRibs -> AddElement(elNa,0.001);
fRibs -> AddElement(elP,0.014);
fRibs -> AddElement(elS,0.002);
fRibs -> AddElement(elCl,0.002);
fRibs -> AddElement(elK,0.001);
fRibs -> AddElement(elCa,0.028);
fRibs -> AddElement(elFe,0.001);
//Scapulae, spongiosa -> ID 16
d = 1.128 *g/cm3;
fScapulae = new G4Material("scapulae",d,10);
fScapulae -> AddElement(elH,0.094);
fScapulae -> AddElement(elC,0.406);
fScapulae -> AddElement(elN,0.024);
fScapulae -> AddElement(elO,0.404);
fScapulae -> AddElement(elNa,0.001);
fScapulae -> AddElement(elP,0.022);
fScapulae -> AddElement(elS,0.002);
fScapulae -> AddElement(elCl,0.001);
fScapulae -> AddElement(elK,0.001);
fScapulae -> AddElement(elCa,0.045);
//Cervical Spine, spongiosa -> ID 17
d = 1.135 *g/cm3;
fSpine_cervical = new G4Material("spine_cervical",d,10);
fSpine_cervical -> AddElement(elH,0.092);
fSpine_cervical -> AddElement(elC,0.351);
fSpine_cervical -> AddElement(elN,0.029);
fSpine_cervical -> AddElement(elO,0.458);
fSpine_cervical -> AddElement(elNa,0.001);
fSpine_cervical -> AddElement(elP,0.021);
fSpine_cervical -> AddElement(elS,0.002);
fSpine_cervical -> AddElement(elCl,0.002);
fSpine_cervical -> AddElement(elK,0.002);
fSpine_cervical -> AddElement(elCa,0.043);
//Thoratic Spine, spongiosa -> ID 18
d = 1.084 *g/cm3;
fSpine_thoratic = new G4Material("spine_thoratic",d,11);
fSpine_thoratic -> AddElement(elH,0.098);
fSpine_thoratic -> AddElement(elC,0.386);
fSpine_thoratic -> AddElement(elN,0.028);
fSpine_thoratic -> AddElement(elO,0.442);
fSpine_thoratic -> AddElement(elNa,0.001);
fSpine_thoratic -> AddElement(elP,0.013);
fSpine_thoratic -> AddElement(elS,0.002);
fSpine_thoratic -> AddElement(elCl,0.002);
fSpine_thoratic -> AddElement(elK,0.001);
fSpine_thoratic -> AddElement(elCa,0.026);
fSpine_thoratic -> AddElement(elFe,0.001);
//Lumbar Spine, spongiosa -> ID 19
d = 1.171 *g/cm3;
fSpine_lumbar = new G4Material("spine_lumbar",d,11);
fSpine_lumbar -> AddElement(elH,0.088);
fSpine_lumbar -> AddElement(elC,0.329);
fSpine_lumbar -> AddElement(elN,0.030);
fSpine_lumbar -> AddElement(elO,0.466);
fSpine_lumbar -> AddElement(elNa,0.001);
fSpine_lumbar -> AddElement(elMg,0.001);
fSpine_lumbar -> AddElement(elP,0.026);
fSpine_lumbar -> AddElement(elS,0.003);
fSpine_lumbar -> AddElement(elCl,0.001);
fSpine_lumbar -> AddElement(elK,0.001);
fSpine_lumbar -> AddElement(elCa,0.054);
//Sacrum, spongiosa -> ID 20
d = 1.052 *g/cm3;
fSacrum = new G4Material("sacrum",d,11);
fSacrum -> AddElement(elH,0.102);
fSacrum -> AddElement(elC,0.410);
fSacrum -> AddElement(elN,0.027);
fSacrum -> AddElement(elO,0.433);
fSacrum -> AddElement(elNa,0.001);
fSacrum -> AddElement(elP,0.007);
fSacrum -> AddElement(elS,0.002);
fSacrum -> AddElement(elCl,0.002);
fSacrum -> AddElement(elK,0.001);
fSacrum -> AddElement(elCa,0.014);
fSacrum -> AddElement(elFe,0.001);
//Sternum, spongiosa -> ID 21
d = 1.076 *g/cm3;
fSternum = new G4Material("sternum",d,11);
fSternum -> AddElement(elH,0.099);
fSternum -> AddElement(elC,0.392);
fSternum -> AddElement(elN,0.028);
fSternum -> AddElement(elO,0.439);
fSternum -> AddElement(elNa,0.001);
fSternum -> AddElement(elP,0.012);
fSternum -> AddElement(elS,0.002);
fSternum -> AddElement(elCl,0.002);
fSternum -> AddElement(elK,0.001);
fSternum -> AddElement(elCa,0.023);
fSternum -> AddElement(elFe,0.001);
//Humeri and femora, upper halves, medullary cavity -> ID 22
d = 0.980 *g/cm3;
fHf_upper = new G4Material("hf_upper",d,7);
fHf_upper -> AddElement(elH,0.115);
fHf_upper -> AddElement(elC,0.637);
fHf_upper -> AddElement(elN,0.007);
fHf_upper -> AddElement(elO,0.238);
fHf_upper -> AddElement(elNa,0.001);
fHf_upper -> AddElement(elS,0.001);
fHf_upper -> AddElement(elCl,0.001);
//Humeri and femora, lower halves, medullary cavity -> ID 23
d = 0.980 *g/cm3;
fHf_lower = new G4Material("hf_lower",d,7);
fHf_lower -> AddElement(elH,0.115);
fHf_lower -> AddElement(elC,0.637);
fHf_lower -> AddElement(elN,0.007);
fHf_lower -> AddElement(elO,0.238);
fHf_lower -> AddElement(elNa,0.001);
fHf_lower -> AddElement(elS,0.001);
fHf_lower -> AddElement(elCl,0.001);
//Lower arm bones, medullary cavity -> ID 24
d = 0.980 *g/cm3;
fMed_lowerarm = new G4Material("med_lowerarm",d,7);
fMed_lowerarm -> AddElement(elH,0.115);
fMed_lowerarm -> AddElement(elC,0.637);
fMed_lowerarm -> AddElement(elN,0.007);
fMed_lowerarm -> AddElement(elO,0.238);
fMed_lowerarm -> AddElement(elNa,0.001);
fMed_lowerarm -> AddElement(elS,0.001);
fMed_lowerarm -> AddElement(elCl,0.001);
//Lower leg bones, medullary cavity -> ID 25
d = 0.980 *g/cm3;
fMed_lowerleg = new G4Material("med_lowerleg",d,7);
fMed_lowerleg -> AddElement(elH,0.115);
fMed_lowerleg -> AddElement(elC,0.637);
fMed_lowerleg -> AddElement(elN,0.007);
fMed_lowerleg -> AddElement(elO,0.238);
fMed_lowerleg -> AddElement(elNa,0.001);
fMed_lowerleg -> AddElement(elS,0.001);
fMed_lowerleg -> AddElement(elCl,0.001);
//Cartilage -> ID 26
d = 1.100 *g/cm3;
fCartilage = new G4Material("cartilage",d,8);
fCartilage -> AddElement(elH,0.096);
fCartilage -> AddElement(elC,0.099);
fCartilage -> AddElement(elN,0.022);
fCartilage -> AddElement(elO,0.744);
fCartilage -> AddElement(elNa,0.005);
fCartilage -> AddElement(elP,0.022);
fCartilage -> AddElement(elS,0.009);
fCartilage -> AddElement(elCl,0.003);
//Skin -> Id 27
d = 1.090 *g/cm3;
fSkin = new G4Material("skin",d,9);
fSkin -> AddElement(elH,0.100);
fSkin -> AddElement(elC,0.199);
fSkin -> AddElement(elN,0.042);
fSkin -> AddElement(elO,0.650);
fSkin -> AddElement(elNa,0.002);
fSkin -> AddElement(elP,0.001);
fSkin -> AddElement(elS,0.002);
fSkin -> AddElement(elCl,0.003);
fSkin -> AddElement(elK,0.001);
//Blood -> ID 28
d = 1.060 *g/cm3;
fBlood = new G4Material("blood",d,10);
fBlood -> AddElement(elH,0.102);
fBlood -> AddElement(elC,0.110);
fBlood -> AddElement(elN,0.033);
fBlood -> AddElement(elO,0.745);
fBlood -> AddElement(elNa,0.001);
fBlood -> AddElement(elP,0.001);
fBlood -> AddElement(elS,0.002);
fBlood -> AddElement(elCl,0.003);
fBlood -> AddElement(elK,0.002);
fBlood -> AddElement(elFe,0.001);
//Muscular Tissue -> ID 29
d = 1.050 *g/cm3;
fMuscle = new G4Material("muscle",d,9);
fMuscle -> AddElement(elH,0.102);
fMuscle -> AddElement(elC,0.142);
fMuscle -> AddElement(elN,0.034);
fMuscle -> AddElement(elO,0.711);
fMuscle -> AddElement(elNa,0.001);
fMuscle -> AddElement(elP,0.002);
fMuscle -> AddElement(elS,0.003);
fMuscle -> AddElement(elCl,0.001);
fMuscle -> AddElement(elK,0.004);
//Liver -> ID 30
d = 1.050 *g/cm3;
fLiver = new G4Material("liver",d,9);
fLiver -> AddElement(elH,0.102);
fLiver -> AddElement(elC,0.131);
fLiver -> AddElement(elN,0.031);
fLiver -> AddElement(elO,0.724);
fLiver -> AddElement(elNa,0.002);
fLiver -> AddElement(elP,0.002);
fLiver -> AddElement(elS,0.003);
fLiver -> AddElement(elCl,0.002);
fLiver -> AddElement(elK,0.003);
//Pancreas ->ID 31
d = 1.050 *g/cm3;
fPancreas = new G4Material("pancreas",d,9);
fPancreas -> AddElement(elH,0.105);
fPancreas -> AddElement(elC,0.157);
fPancreas -> AddElement(elN,0.024);
fPancreas -> AddElement(elO,0.705);
fPancreas -> AddElement(elNa,0.002);
fPancreas -> AddElement(elP,0.002);
fPancreas -> AddElement(elS,0.001);
fPancreas -> AddElement(elCl,0.002);
fPancreas -> AddElement(elK,0.002);
//Brain -> ID 32
d = 1.050 *g/cm3;
fBrain = new G4Material("brain",d,9);
fBrain -> AddElement(elH,0.107);
fBrain -> AddElement(elC,0.144);
fBrain -> AddElement(elN,0.022);
fBrain -> AddElement(elO,0.713);
fBrain -> AddElement(elNa,0.002);
fBrain -> AddElement(elP,0.004);
fBrain -> AddElement(elS,0.002);
fBrain -> AddElement(elCl,0.003);
fBrain -> AddElement(elK,0.003);
//Heart -> ID 33
d = 1.050 *g/cm3;
fHeart = new G4Material("heart",d,9);
fHeart -> AddElement(elH,0.104);
fHeart -> AddElement(elC,0.138);
fHeart -> AddElement(elN,0.029);
fHeart -> AddElement(elO,0.719);
fHeart -> AddElement(elNa,0.001);
fHeart -> AddElement(elP,0.002);
fHeart -> AddElement(elS,0.002);
fHeart -> AddElement(elCl,0.002);
fHeart -> AddElement(elK,0.003);
//Eye ->ID 34
d = 1.050 *g/cm3;
fEye = new G4Material("eye",d,8);
fEye -> AddElement(elH,0.097);
fEye -> AddElement(elC,0.183);
fEye -> AddElement(elN,0.054);
fEye -> AddElement(elO,0.660);
fEye -> AddElement(elCa,0.001);
fEye -> AddElement(elP,0.001);
fEye -> AddElement(elS,0.003);
fEye -> AddElement(elCl,0.001);
//Kidneys -> ID 35
d = 1.050 *g/cm3;
fKidney = new G4Material("kidney",d,10);
fKidney -> AddElement(elH,0.103);
fKidney -> AddElement(elC,0.125);
fKidney -> AddElement(elN,0.031);
fKidney -> AddElement(elO,0.730);
fKidney -> AddElement(elNa,0.002);
fKidney -> AddElement(elP,0.002);
fKidney -> AddElement(elS,0.002);
fKidney -> AddElement(elCl,0.002);
fKidney -> AddElement(elK,0.002);
fKidney -> AddElement(elCa,0.001);
//Stomach ->ID 36
d = 1.040 *g/cm3;
fStomach = new G4Material("stomach",d,9);
fStomach -> AddElement(elH,0.105);
fStomach -> AddElement(elC,0.114);
fStomach -> AddElement(elN,0.025);
fStomach -> AddElement(elO,0.750);
fStomach -> AddElement(elNa,0.001);
fStomach -> AddElement(elP,0.001);
fStomach -> AddElement(elS,0.001);
fStomach -> AddElement(elCl,0.002);
fStomach -> AddElement(elK,0.001);
//Small intestine ->ID 37
d = 1.040 *g/cm3;
fIntestine_sml = new G4Material("intestine_sml",d,9);
fIntestine_sml -> AddElement(elH,0.105);
fIntestine_sml -> AddElement(elC,0.114);
fIntestine_sml -> AddElement(elN,0.025);
fIntestine_sml -> AddElement(elO,0.750);
fIntestine_sml -> AddElement(elNa,0.001);
fIntestine_sml -> AddElement(elP,0.001);
fIntestine_sml -> AddElement(elS,0.001);
fIntestine_sml -> AddElement(elCl,0.002);
fIntestine_sml -> AddElement(elK,0.001);
//Large intestine ->ID 38
d = 1.040 *g/cm3;
fIntestine_lrg = new G4Material("intestine_lrg",d,9);
fIntestine_lrg -> AddElement(elH,0.105);
fIntestine_lrg -> AddElement(elC,0.114);
fIntestine_lrg -> AddElement(elN,0.025);
fIntestine_lrg -> AddElement(elO,0.750);
fIntestine_lrg -> AddElement(elNa,0.001);
fIntestine_lrg -> AddElement(elP,0.001);
fIntestine_lrg -> AddElement(elS,0.001);
fIntestine_lrg -> AddElement(elCl,0.002);
fIntestine_lrg -> AddElement(elK,0.001);
//Spleen -> ID 39
d = 1.040 *g/cm3;
fSpleen = new G4Material("spleen",d,9);
fSpleen -> AddElement(elH,0.103);
fSpleen -> AddElement(elC,0.112);
fSpleen -> AddElement(elN,0.032);
fSpleen -> AddElement(elO,0.743);
fSpleen -> AddElement(elNa,0.001);
fSpleen -> AddElement(elP,0.002);
fSpleen -> AddElement(elS,0.002);
fSpleen -> AddElement(elCl,0.002);
fSpleen -> AddElement(elK,0.003);
//Thyroid -> ID 40
d = 1.040 *g/cm3;
fThyroid = new G4Material("thyroid",d,10);
fThyroid -> AddElement(elH,0.104);
fThyroid -> AddElement(elC,0.118);
fThyroid -> AddElement(elN,0.025);
fThyroid -> AddElement(elO,0.745);
fThyroid -> AddElement(elNa,0.002);
fThyroid -> AddElement(elP,0.001);
fThyroid -> AddElement(elS,0.001);
fThyroid -> AddElement(elCl,0.002);
fThyroid -> AddElement(elK,0.001);
fThyroid -> AddElement(elI,0.001);
//Urinary Bladder -> ID 41
d = 1.040 *g/cm3;
fBladder = new G4Material("bladder",d,9);
fBladder -> AddElement(elH,0.105);
fBladder -> AddElement(elC,0.096);
fBladder -> AddElement(elN,0.026);
fBladder -> AddElement(elO,0.761);
fBladder -> AddElement(elNa,0.002);
fBladder -> AddElement(elP,0.002);
fBladder -> AddElement(elS,0.002);
fBladder -> AddElement(elCl,0.003);
fBladder -> AddElement(elK,0.003);
// Ovaries (Defined as ovaries_testes to be called upon by ColourMap.dat
//for visualisation purposes) -> ID 42
d = 1.040 *g/cm3;
fOvaries_testes = new G4Material("ovaries_testes",d,9);
fOvaries_testes -> AddElement(elH,0.105);
fOvaries_testes -> AddElement(elC,0.094);
fOvaries_testes -> AddElement(elN,0.025);
fOvaries_testes -> AddElement(elO,0.766);
fOvaries_testes -> AddElement(elNa,0.002);
fOvaries_testes -> AddElement(elP,0.002);
fOvaries_testes -> AddElement(elS,0.002);
fOvaries_testes -> AddElement(elCl,0.002);
fOvaries_testes -> AddElement(elK,0.002);
//Adrenals -> ID 43
d = 1.030 *g/cm3;
fAdrenals = new G4Material("adrenals",d,9);
fAdrenals -> AddElement(elH,0.104);
fAdrenals -> AddElement(elC,0.228);
fAdrenals -> AddElement(elN,0.028);
fAdrenals -> AddElement(elO,0.630);
fAdrenals -> AddElement(elNa,0.001);
fAdrenals -> AddElement(elP,0.002);
fAdrenals -> AddElement(elS,0.003);
fAdrenals -> AddElement(elCl,0.002);
fAdrenals -> AddElement(elK,0.002);
//Oesophagus -> ID 44
d = 1.030 *g/cm3;
fOesophagus = new G4Material("oesophagus",d,9);
fOesophagus -> AddElement(elH,0.104);
fOesophagus -> AddElement(elC,0.222);
fOesophagus -> AddElement(elN,0.028);
fOesophagus -> AddElement(elO,0.636);
fOesophagus -> AddElement(elNa,0.001);
fOesophagus -> AddElement(elP,0.002);
fOesophagus -> AddElement(elS,0.003);
fOesophagus -> AddElement(elCl,0.002);
fOesophagus -> AddElement(elK,0.002);
//Miscillaneous (Gallbladder, Trachea, Thymus, Tonsils, Ureters, ...) -> ID 45
d = 1.030 *g/cm3;
fMisc = new G4Material("misc",d,9);
fMisc -> AddElement(elH,0.105);
fMisc -> AddElement(elC,0.235);
fMisc -> AddElement(elN,0.028);
fMisc -> AddElement(elO,0.622);
fMisc -> AddElement(elNa,0.001);
fMisc -> AddElement(elP,0.002);
fMisc -> AddElement(elS,0.003);
fMisc -> AddElement(elCl,0.002);
fMisc -> AddElement(elK,0.002);
//Uterus (Defined as fUterus_prostate to be called upon by ColourMap.dat
// for visualisation purposes) -> ID 46
d = 1.030 *g/cm3;
fUterus_prostate = new G4Material("uterus_prostate",d,9);
fUterus_prostate -> AddElement(elH,0.105);
fUterus_prostate -> AddElement(elC,0.286);
fUterus_prostate -> AddElement(elN,0.025);
fUterus_prostate -> AddElement(elO,0.576);
fUterus_prostate -> AddElement(elNa,0.001);
fUterus_prostate -> AddElement(elP,0.002);
fUterus_prostate -> AddElement(elS,0.002);
fUterus_prostate -> AddElement(elCl,0.001);
fUterus_prostate -> AddElement(elK,0.002);
//Lymph -> ID 47
d = 1.030 *g/cm3;
fLymph = new G4Material("lymph",d,7);
fLymph -> AddElement(elH,0.108);
fLymph -> AddElement(elC,0.042);
fLymph -> AddElement(elN,0.011);
fLymph -> AddElement(elO,0.831);
fLymph -> AddElement(elNa,0.003);
fLymph -> AddElement(elS,0.001);
fLymph -> AddElement(elCl,0.004);
//Breast (Mammary Gland)-> ID 48
d = 1.020 *g/cm3;
fBreast_glandular = new G4Material("breast_glandular",d,4);
fBreast_glandular -> AddElement(elH,0.114);
fBreast_glandular -> AddElement(elC,0.461);
fBreast_glandular -> AddElement(elN,0.005);
fBreast_glandular -> AddElement(elO,0.420);
//Adipose tissue (breast) -> ID 49
d = 0.950 *g/cm3;
fBreast_adipose = new G4Material("breast_adipose",d,7);
fBreast_adipose -> AddElement(elH,0.114);
fBreast_adipose -> AddElement(elC,0.589);
fBreast_adipose -> AddElement(elN,0.007);
fBreast_adipose -> AddElement(elO,0.287);
fBreast_adipose -> AddElement(elNa,0.001);
fBreast_adipose -> AddElement(elS,0.001);
fBreast_adipose -> AddElement(elCl,0.001);
//Lung Tissue (Compressed Lung) -> ID 50
d = 0.385 *g/cm3;
fLung = new G4Material("lung",d,9);
fLung -> AddElement(elH,0.103);
fLung -> AddElement(elC,0.107);
fLung -> AddElement(elN,0.032);
fLung -> AddElement(elO,0.746);
fLung -> AddElement(elNa,0.002);
fLung -> AddElement(elP,0.002);
fLung -> AddElement(elS,0.003);
fLung -> AddElement(elCl,0.003);
fLung -> AddElement(elK,0.002);
//Contents of gastro-intestinal tract -> ID 51
d = 1.040 *g/cm3;
fGastro_content = new G4Material("gastro_content",d,10);
fGastro_content -> AddElement(elH,0.100);
fGastro_content -> AddElement(elC,0.222);
fGastro_content -> AddElement(elN,0.022);
fGastro_content -> AddElement(elO,0.644);
fGastro_content -> AddElement(elNa,0.001);
fGastro_content -> AddElement(elP,0.002);
fGastro_content -> AddElement(elS,0.003);
fGastro_content -> AddElement(elCl,0.001);
fGastro_content -> AddElement(elK,0.004);
fGastro_content -> AddElement(elCa,0.001);
//Urine -> ID 52
d = 1.040 *g/cm3;
fUrine = new G4Material("urine",d,7);
fUrine -> AddElement(elH,0.107);
fUrine -> AddElement(elC,0.003);
fUrine -> AddElement(elN,0.010);
fUrine -> AddElement(elO,0.873);
fUrine -> AddElement(elNa,0.004);
fUrine -> AddElement(elP,0.001);
fUrine -> AddElement(elK,0.002);
}
G4Material* ICRP110PhantomMaterial_Female::GetMaterial(G4String material)
{
// Returns a material
G4Material* pttoMaterial = G4Material::GetMaterial(material);
if (!pttoMaterial) G4cout << "WARNING: material '" << material << "' is not defined!" << G4endl;
return pttoMaterial;
}
@@ -0,0 +1,796 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#include "ICRP110PhantomMaterial_Male.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4MaterialPropertyVector.hh"
#include "G4MaterialTable.hh"
#include "Randomize.hh"
#include "G4RunManager.hh"
#include "G4Element.hh"
#include "G4ElementTable.hh"
ICRP110PhantomMaterial_Male::ICRP110PhantomMaterial_Male():
fLung(nullptr), fTeeth(nullptr), fBone(nullptr), fHumeri_upper(nullptr), fHumeri_lower(nullptr),
fArm_lower(nullptr), fHand(nullptr), fClavicle(nullptr), fCranium(nullptr), fFemora_upper(nullptr),
fFemora_lower(nullptr), fLeg_lower(nullptr), fFoot(nullptr), fMandible(nullptr),
fPelvis(nullptr), fRibs(nullptr), fScapulae(nullptr), fSpine_cervical(nullptr),
fSpine_lumbar(nullptr), fSpine_thoratic(nullptr), fSacrum(nullptr),
fSternum(nullptr), fHf_upper(nullptr), fHf_lower(nullptr), fMed_lowerleg(nullptr),
fMed_lowerarm(nullptr), fCartilage(nullptr), fSkin(nullptr), fBlood(nullptr),
fMuscle(nullptr), fLiver(nullptr), fPancreas(nullptr), fBrain(nullptr), fHeart(nullptr), fEye(nullptr),
fKidney(nullptr), fStomach(nullptr), fIntestine_sml(nullptr), fIntestine_lrg(nullptr),
fSpleen(nullptr), fThyroid(nullptr), fBladder(nullptr), fOvaries_testes(nullptr), fAdrenals(nullptr),
fOesophagus(nullptr), fMisc(nullptr), fUterus_prostate(nullptr), fLymph(nullptr),
fBreast_glandular(nullptr), fBreast_adipose(nullptr), fGastro_content(nullptr),
fUrine(nullptr)
{;}
ICRP110PhantomMaterial_Male::~ICRP110PhantomMaterial_Male()
{;}
void ICRP110PhantomMaterial_Male::DefineMaterials()
{
// Define required materials
G4double A; // atomic mass
G4double Z; // atomic number
G4double d; // density
// General elements
A = 1.01*g/mole;
G4Element* elH = new G4Element ("Hydrogen","H",Z = 1.,A);
A = 12.011*g/mole;
G4Element* elC = new G4Element("Carbon","C",Z = 6.,A);
A = 14.01*g/mole;
G4Element* elN = new G4Element("Nitrogen","N",Z = 7.,A);
A = 16.00*g/mole;
G4Element* elO = new G4Element("Oxygen","O",Z = 8.,A);
A = 22.99*g/mole;
G4Element* elNa = new G4Element("Sodium","Na",Z = 11.,A);
A = 24.305*g/mole;
G4Element* elMg = new G4Element("Magnesium","Mg",Z = 12.,A);
A = 30.974*g/mole;
G4Element* elP = new G4Element("Phosphorus","P",Z = 15.,A);
A = 32.064*g/mole;
G4Element* elS = new G4Element("Sulfur","S",Z = 16.,A);
A = 35.453*g/mole;
G4Element* elCl = new G4Element("Chlorine","Cl",Z = 17.,A);
A = 39.098*g/mole;
G4Element* elK = new G4Element("Potassium","K",Z = 19.,A);
A = 40.08*g/mole;
G4Element* elCa = new G4Element("Calcium","Ca",Z = 20.,A);
A = 55.85*g/mole;
G4Element* elFe = new G4Element("Iron","Fe",Z = 26.,A);
A = 126.90447 *g/mole;
G4Element*elI = new G4Element("Iodine","I", Z = 53.,A);
//Added tissues for phantom including their tissue ID
//Teeth -> Tissue ID 1
d = 2.750 *g/cm3;
fTeeth = new G4Material("teeth",d,7);
fTeeth -> AddElement(elH,0.022);
fTeeth -> AddElement(elC,0.095);
fTeeth -> AddElement(elN,0.029);
fTeeth -> AddElement(elO,0.421);
fTeeth -> AddElement(elMg,0.007);
fTeeth -> AddElement(elP,0.137);
fTeeth -> AddElement(elCa,0.289);
//Mineral Bone -> Tissue ID 2
d = 1.920 *g/cm3;
fBone = new G4Material("bone",d,9);
fBone -> AddElement(elH,0.036);
fBone -> AddElement(elC,0.159);
fBone -> AddElement(elN,0.042);
fBone -> AddElement(elO,0.448);
fBone -> AddElement(elNa,0.003);
fBone -> AddElement(elMg,0.002);
fBone -> AddElement(elP,0.094);
fBone -> AddElement(elS,0.003);
fBone -> AddElement(elH,0.213);
//Humeri, upper half, spongiosa -> ID 3
d = 1.205 *g/cm3;
fHumeri_upper = new G4Material("humeri_upper",d,10);
fHumeri_upper -> AddElement(elH,0.085) ;
fHumeri_upper -> AddElement(elC,0.288);
fHumeri_upper -> AddElement(elN,0.026);
fHumeri_upper -> AddElement(elO,0.498);
fHumeri_upper -> AddElement(elNa,0.002);
fHumeri_upper -> AddElement(elMg,0.001);
fHumeri_upper -> AddElement(elP,0.033);
fHumeri_upper -> AddElement(elS,0.004);
fHumeri_upper -> AddElement(elCl,0.002);
fHumeri_upper -> AddElement(elCa,0.061);
//Humeri, lower half, spongiosa -> ID 4
d = 1.108 *g/cm3;
fHumeri_lower = new G4Material("humeri_lower",d,9);
fHumeri_lower -> AddElement(elH,0.097);
fHumeri_lower -> AddElement(elC,0.439);
fHumeri_lower -> AddElement(elN,0.017);
fHumeri_lower -> AddElement(elO,0.381);
fHumeri_lower -> AddElement(elNa,0.002);
fHumeri_lower -> AddElement(elP,0.021);
fHumeri_lower -> AddElement(elS,0.003);
fHumeri_lower -> AddElement(elCl,0.001);
fHumeri_lower -> AddElement(elCa,0.039);
//Lower arm bones, spongiosa -> ID 5
d = 1.108 *g/cm3;
fArm_lower = new G4Material("arm_lower",d,9);
fArm_lower -> AddElement(elH,0.097);
fArm_lower -> AddElement(elC,0.439);
fArm_lower -> AddElement(elN,0.017);
fArm_lower -> AddElement(elO,0.381);
fArm_lower -> AddElement(elNa,0.002);
fArm_lower -> AddElement(elP,0.021);
fArm_lower -> AddElement(elS,0.003);
fArm_lower -> AddElement(elCl,0.001);
fArm_lower -> AddElement(elCa,0.039);
//Hand Bones, Spongiosa ->ID 6
d = 1.108 *g/cm3;
fHand = new G4Material("hand",d,9);
fHand -> AddElement(elH,0.097);
fHand -> AddElement(elC,0.439);
fHand -> AddElement(elN,0.017);
fHand -> AddElement(elO,0.381);
fHand -> AddElement(elNa,0.002);
fHand -> AddElement(elP,0.021);
fHand -> AddElement(elS,0.003);
fHand -> AddElement(elCl,0.001);
fHand -> AddElement(elCa,0.039);
//Clavicles, spongiosa -> ID 7
d = 1.151 *g/cm3;
fClavicle = new G4Material("clavicle",d,9);
fClavicle -> AddElement(elH,0.091);
fClavicle -> AddElement(elC,0.348);
fClavicle -> AddElement(elN,0.024);
fClavicle -> AddElement(elO,0.457);
fClavicle -> AddElement(elNa,0.002);
fClavicle -> AddElement(elP,0.026);
fClavicle -> AddElement(elS,0.003);
fClavicle -> AddElement(elCl,0.001);
fClavicle -> AddElement(elCa,0.048);
//cranium, spongiosa -> ID 8
d = 1.157 *g/cm3;
fCranium = new G4Material("cranium",d,10);
fCranium -> AddElement(elH,0.090);
fCranium -> AddElement(elC,0.335);
fCranium -> AddElement(elN,0.025);
fCranium -> AddElement(elO,0.467);
fCranium -> AddElement(elNa,0.002);
fCranium -> AddElement(elP,0.026);
fCranium -> AddElement(elS,0.003);
fCranium -> AddElement(elCl,0.002);
fCranium -> AddElement(elK,0.001);
fCranium -> AddElement(elCa,0.049);
//femora, upper half, spongiosa -> ID 9
d = 1.124 *g/cm3;
fFemora_upper = new G4Material("femora_upper",d,9);
fFemora_upper->AddElement(elH,0.094);
fFemora_upper->AddElement(elC,0.385);
fFemora_upper->AddElement(elN,0.022);
fFemora_upper->AddElement(elO,0.430);
fFemora_upper->AddElement(elNa,0.002);
fFemora_upper->AddElement(elP,0.022);
fFemora_upper->AddElement(elS,0.003);
fFemora_upper->AddElement(elCl,0.001);
fFemora_upper->AddElement(elCa,0.041);
//femora, lower half, spongiosa -> ID 10
d = 1.108 *g/cm3;
fFemora_lower = new G4Material("femora_lower",d,9);
fFemora_lower->AddElement(elH,0.097);
fFemora_lower->AddElement(elC,0.439);
fFemora_lower->AddElement(elN,0.017);
fFemora_lower->AddElement(elO,0.381);
fFemora_lower->AddElement(elNa,0.002);
fFemora_lower->AddElement(elP,0.021);
fFemora_lower->AddElement(elS,0.003);
fFemora_lower->AddElement(elCl,0.001);
fFemora_lower->AddElement(elCa,0.039);
//Lower leg bones, spongiosa -> ID 11
d = 1.108 *g/cm3;
fLeg_lower = new G4Material("leg_lower",d,9);
fLeg_lower -> AddElement(elH,0.097);
fLeg_lower -> AddElement(elC,0.439);
fLeg_lower -> AddElement(elN,0.017);
fLeg_lower -> AddElement(elO,0.381);
fLeg_lower -> AddElement(elNa,0.002);
fLeg_lower -> AddElement(elP,0.021);
fLeg_lower -> AddElement(elS,0.003);
fLeg_lower -> AddElement(elCl,0.001);
fLeg_lower -> AddElement(elCa,0.039);
//Foot bones, spongiosa ->ID 12
d = 1.108 *g/cm3;
fFoot = new G4Material("foot",d,9);
fFoot -> AddElement(elH,0.097);
fFoot -> AddElement(elC,0.439);
fFoot -> AddElement(elN,0.017);
fFoot -> AddElement(elO,0.381);
fFoot -> AddElement(elNa,0.002);
fFoot -> AddElement(elP,0.021);
fFoot -> AddElement(elS,0.003);
fFoot -> AddElement(elCl,0.001);
fFoot -> AddElement(elCa,0.039);
//Mandible, spongiosa -> ID 13
d = 1.228 *g/cm3;
fMandible = new G4Material("mandible",d,10);
fMandible -> AddElement(elH,0.083);
fMandible -> AddElement(elC,0.266);
fMandible -> AddElement(elN,0.027);
fMandible -> AddElement(elO,0.511);
fMandible -> AddElement(elNa,0.003);
fMandible -> AddElement(elMg,0.001);
fMandible -> AddElement(elP,0.036);
fMandible -> AddElement(elS,0.004);
fMandible -> AddElement(elCl,0.002);
fMandible -> AddElement(elCa,0.067);
//Pelvis, Spongiosa -> ID 14
d = 1.123 *g/cm3;
fPelvis = new G4Material("pelvis",d,10);
fPelvis -> AddElement(elH,0.094);
fPelvis -> AddElement(elC,0.360);
fPelvis -> AddElement(elN,0.025);
fPelvis -> AddElement(elO,0.454);
fPelvis -> AddElement(elNa,0.002);
fPelvis -> AddElement(elP,0.021);
fPelvis -> AddElement(elS,0.003);
fPelvis -> AddElement(elCl,0.002);
fPelvis -> AddElement(elK,0.001);
fPelvis -> AddElement(elCa,0.038);
//Ribs, spongiosa -> ID 15
d = 1.165 *g/cm3;
fRibs = new G4Material("ribs",d,10);
fRibs -> AddElement(elH,0.089);
fRibs -> AddElement(elC,0.292);
fRibs -> AddElement(elN,0.029);
fRibs -> AddElement(elO,0.507);
fRibs -> AddElement(elNa,0.002);
fRibs -> AddElement(elP,0.026);
fRibs -> AddElement(elS,0.004);
fRibs -> AddElement(elCl,0.002);
fRibs -> AddElement(elK,0.001);
fRibs -> AddElement(elCa,0.048);
//scapulae, spongiosa -> ID 16
d = 1.183 *g/cm3;
fScapulae = new G4Material("scapulae",d,10);
fScapulae -> AddElement(elH,0.087);
fScapulae -> AddElement(elC,0.309);
fScapulae -> AddElement(elN,0.026);
fScapulae -> AddElement(elO,0.483);
fScapulae -> AddElement(elNa,0.002);
fScapulae -> AddElement(elMg,0.001);
fScapulae -> AddElement(elP,0.030);
fScapulae -> AddElement(elS,0.004);
fScapulae -> AddElement(elCl,0.002);
fScapulae -> AddElement(elCa,0.056);
//Cervical fSpine, spongiosa -> ID 17
d = 1.050 *g/cm3;
fSpine_cervical = new G4Material("spine_cervical",d,11);
fSpine_cervical -> AddElement(elH,0.103);
fSpine_cervical -> AddElement(elC,0.400);
fSpine_cervical -> AddElement(elN,0.027);
fSpine_cervical -> AddElement(elO,0.444);
fSpine_cervical -> AddElement(elNa,0.001);
fSpine_cervical -> AddElement(elP,0.007);
fSpine_cervical -> AddElement(elS,0.002);
fSpine_cervical -> AddElement(elCl,0.002);
fSpine_cervical -> AddElement(elK,0.001);
fSpine_cervical -> AddElement(elCa,0.012);
fSpine_cervical -> AddElement(elFe,0.001);
//Thoratic spine, spongiosa -> ID 18
d = 1.074 *g/cm3;
fSpine_thoratic = new G4Material("spine_thoratic",d,11);
fSpine_thoratic -> AddElement(elH,0.099);
fSpine_thoratic -> AddElement(elC,0.376);
fSpine_thoratic -> AddElement(elN,0.027);
fSpine_thoratic -> AddElement(elO,0.459);
fSpine_thoratic -> AddElement(elNa,0.001);
fSpine_thoratic -> AddElement(elP,0.012);
fSpine_thoratic -> AddElement(elS,0.002);
fSpine_thoratic -> AddElement(elCl,0.002);
fSpine_thoratic -> AddElement(elK,0.001);
fSpine_thoratic -> AddElement(elCa,0.020);
fSpine_thoratic -> AddElement(elFe,0.001);
//Lumbar spine, spongiosa -> ID 19
d = 1.112 *g/cm3;
fSpine_lumbar = new G4Material("spine_lumbar",d,10);
fSpine_lumbar -> AddElement(elH,0.095);
fSpine_lumbar -> AddElement(elC,0.340);
fSpine_lumbar -> AddElement(elN,0.028);
fSpine_lumbar -> AddElement(elO,0.480);
fSpine_lumbar -> AddElement(elNa,0.001);
fSpine_lumbar -> AddElement(elP,0.018);
fSpine_lumbar -> AddElement(elS,0.003);
fSpine_lumbar -> AddElement(elCl,0.002);
fSpine_lumbar -> AddElement(elK,0.001);
fSpine_lumbar -> AddElement(elCa,0.032);
//sacrum, spongiosa -> ID 20
d = 1.031 *g/cm3;
fSacrum = new G4Material("sacrum",d,11);
fSacrum -> AddElement(elH,0.105);
fSacrum -> AddElement(elC,0.419);
fSacrum -> AddElement(elN,0.027);
fSacrum -> AddElement(elO,0.432);
fSacrum -> AddElement(elNa,0.001);
fSacrum -> AddElement(elP,0.004);
fSacrum -> AddElement(elS,0.002);
fSacrum -> AddElement(elCl,0.002);
fSacrum -> AddElement(elK,0.001);
fSacrum -> AddElement(elCa,0.006);
fSacrum -> AddElement(elFe,0.001);
//sternum, spongiosa -> ID 21
d = 1.041 *g/cm3;
fSternum = new G4Material("sternum",d,11);
fSternum->AddElement(elH,0.104);
fSternum->AddElement(elC,0.409);
fSternum->AddElement(elN,0.027);
fSternum->AddElement(elO,0.438);
fSternum->AddElement(elNa,0.001);
fSternum->AddElement(elP,0.006);
fSternum->AddElement(elS,0.002);
fSternum->AddElement(elCl,0.002);
fSternum->AddElement(elK,0.001);
fSternum->AddElement(elCa,0.009);
fSternum->AddElement(elFe,0.001);
//Humeri and femora, upper halves, medullary cavity -> ID 22
d = 0.980 *g/cm3;
fHf_upper = new G4Material("hf_upper",d,7);
fHf_upper -> AddElement(elH,0.115);
fHf_upper -> AddElement(elC,0.636);
fHf_upper -> AddElement(elN,0.007);
fHf_upper -> AddElement(elO,0.239);
fHf_upper -> AddElement(elNa,0.001);
fHf_upper -> AddElement(elS,0.001);
fHf_upper -> AddElement(elCl,0.001);
//Humeri and femora, lower halves, medullary cavity -> ID 23
d = 0.980 *g/cm3;
fHf_lower = new G4Material("hf_lower",d,7);
fHf_lower -> AddElement(elH,0.115);
fHf_lower -> AddElement(elC,0.636);
fHf_lower -> AddElement(elN,0.007);
fHf_lower -> AddElement(elO,0.239);
fHf_lower -> AddElement(elNa,0.001);
fHf_lower -> AddElement(elS,0.001);
fHf_lower -> AddElement(elCl,0.001);
//Lower arm bones, medullary cavity -> ID 24
d = 0.980 *g/cm3;
fMed_lowerarm = new G4Material("med_lowerarm",d,7);
fMed_lowerarm -> AddElement(elH,0.115);
fMed_lowerarm -> AddElement(elC,0.636);
fMed_lowerarm -> AddElement(elN,0.007);
fMed_lowerarm -> AddElement(elO,0.239);
fMed_lowerarm -> AddElement(elNa,0.001);
fMed_lowerarm -> AddElement(elS,0.001);
fMed_lowerarm -> AddElement(elCl,0.001);
//Lower leg bones, medullary cavity -> ID 25
d = 0.980 *g/cm3;
fMed_lowerleg = new G4Material("med_lowerleg",d,7);
fMed_lowerleg -> AddElement(elH,0.115);
fMed_lowerleg -> AddElement(elC,0.636);
fMed_lowerleg -> AddElement(elN,0.007);
fMed_lowerleg -> AddElement(elO,0.239);
fMed_lowerleg -> AddElement(elNa,0.001);
fMed_lowerleg -> AddElement(elS,0.001);
fMed_lowerleg -> AddElement(elCl,0.001);
//Cartilage -> ID 26
d = 1.100 *g/cm3;
fCartilage = new G4Material("cartilage",d,8);
fCartilage -> AddElement(elH,0.096);
fCartilage -> AddElement(elC,0.099);
fCartilage -> AddElement(elN,0.022);
fCartilage -> AddElement(elO,0.744);
fCartilage -> AddElement(elNa,0.005);
fCartilage -> AddElement(elP,0.022);
fCartilage -> AddElement(elS,0.009);
fCartilage -> AddElement(elCl,0.003);
//Skin -> Id 27
d = 1.090 *g/cm3;
fSkin = new G4Material("skin",d,9);
fSkin -> AddElement(elH,0.100);
fSkin -> AddElement(elC,0.199);
fSkin -> AddElement(elN,0.042);
fSkin -> AddElement(elO,0.650);
fSkin -> AddElement(elNa,0.002);
fSkin -> AddElement(elP,0.001);
fSkin -> AddElement(elS,0.002);
fSkin -> AddElement(elCl,0.003);
fSkin -> AddElement(elK,0.001);
//Blood -> ID 28
d = 1.060 *g/cm3;
fBlood = new G4Material("blood",d,10);
fBlood -> AddElement(elH,0.102);
fBlood -> AddElement(elC,0.110);
fBlood -> AddElement(elN,0.033);
fBlood -> AddElement(elO,0.745);
fBlood -> AddElement(elNa,0.001);
fBlood -> AddElement(elP,0.001);
fBlood -> AddElement(elS,0.002);
fBlood -> AddElement(elCl,0.003);
fBlood -> AddElement(elK,0.002);
fBlood -> AddElement(elFe,0.001);
//Muscular Tissue -> ID 29
d = 1.050 *g/cm3;
fMuscle = new G4Material("muscle",d,9);
fMuscle -> AddElement(elH,0.102);
fMuscle -> AddElement(elC,0.142);
fMuscle -> AddElement(elN,0.034);
fMuscle -> AddElement(elO,0.711);
fMuscle -> AddElement(elNa,0.001);
fMuscle -> AddElement(elP,0.002);
fMuscle -> AddElement(elS,0.003);
fMuscle -> AddElement(elCl,0.001);
fMuscle -> AddElement(elK,0.004);
//Liver -> ID 30
d = 1.050 *g/cm3;
fLiver = new G4Material("liver",d,9);
fLiver -> AddElement(elH,0.102);
fLiver -> AddElement(elC,0.130);
fLiver -> AddElement(elN,0.031);
fLiver -> AddElement(elO,0.725);
fLiver -> AddElement(elNa,0.002);
fLiver -> AddElement(elP,0.002);
fLiver -> AddElement(elS,0.003);
fLiver -> AddElement(elCl,0.002);
fLiver -> AddElement(elK,0.003);
//Pancreas ->ID 31
d = 1.050 *g/cm3;
fPancreas = new G4Material("pancreas",d,9);
fPancreas -> AddElement(elH,0.105);
fPancreas -> AddElement(elC,0.155);
fPancreas -> AddElement(elN,0.025);
fPancreas -> AddElement(elO,0.706);
fPancreas -> AddElement(elNa,0.002);
fPancreas -> AddElement(elP,0.002);
fPancreas -> AddElement(elS,0.001);
fPancreas -> AddElement(elCl,0.002);
fPancreas -> AddElement(elK,0.002);
//Brain -> ID 32
d = 1.050 *g/cm3;
fBrain = new G4Material("brain",d,9);
fBrain -> AddElement(elH,0.107);
fBrain -> AddElement(elC,0.143);
fBrain -> AddElement(elN,0.023);
fBrain -> AddElement(elO,0.713);
fBrain -> AddElement(elNa,0.002);
fBrain -> AddElement(elP,0.004);
fBrain -> AddElement(elS,0.002);
fBrain -> AddElement(elCl,0.003);
fBrain -> AddElement(elK,0.003);
//Heart -> ID 33
d = 1.050 *g/cm3;
fHeart = new G4Material("heart",d,9);
fHeart -> AddElement(elH,0.104);
fHeart -> AddElement(elC,0.138);
fHeart -> AddElement(elN,0.029);
fHeart -> AddElement(elO,0.719);
fHeart -> AddElement(elNa,0.001);
fHeart -> AddElement(elP,0.002);
fHeart -> AddElement(elS,0.002);
fHeart -> AddElement(elCl,0.002);
fHeart -> AddElement(elK,0.003);
//Eye ->ID 34
d = 1.050 *g/cm3;
fEye = new G4Material("eye",d,8);
fEye -> AddElement(elH,0.097);
fEye -> AddElement(elC,0.181);
fEye -> AddElement(elN,0.053);
fEye -> AddElement(elO,0.663);
fEye -> AddElement(elCa,0.001);
fEye -> AddElement(elP,0.001);
fEye -> AddElement(elS,0.003);
fEye -> AddElement(elCl,0.001);
//Kidneys -> ID 35
d = 1.050 *g/cm3;
fKidney = new G4Material("kidney",d,10);
fKidney -> AddElement(elH,0.103);
fKidney -> AddElement(elC,0.124);
fKidney -> AddElement(elN,0.031);
fKidney -> AddElement(elO,0.731);
fKidney -> AddElement(elNa,0.002);
fKidney -> AddElement(elP,0.002);
fKidney -> AddElement(elS,0.002);
fKidney -> AddElement(elCl,0.002);
fKidney -> AddElement(elK,0.002);
fKidney -> AddElement(elCa,0.001);
//Stomach ->ID 36
d = 1.040 *g/cm3;
fStomach = new G4Material("stomach",d,9);
fStomach -> AddElement(elH,0.105);
fStomach -> AddElement(elC,0.114);
fStomach -> AddElement(elN,0.025);
fStomach -> AddElement(elO,0.750);
fStomach -> AddElement(elNa,0.001);
fStomach -> AddElement(elP,0.001);
fStomach -> AddElement(elS,0.001);
fStomach -> AddElement(elCl,0.002);
fStomach -> AddElement(elK,0.001);
//Small intestine ->ID 37
d = 1.040 *g/cm3;
fIntestine_sml = new G4Material("intestine_sml",d,9);
fIntestine_sml -> AddElement(elH,0.105);
fIntestine_sml -> AddElement(elC,0.113);
fIntestine_sml -> AddElement(elN,0.026);
fIntestine_sml -> AddElement(elO,0.750);
fIntestine_sml -> AddElement(elNa,0.001);
fIntestine_sml -> AddElement(elP,0.001);
fIntestine_sml -> AddElement(elS,0.001);
fIntestine_sml -> AddElement(elCl,0.002);
fIntestine_sml -> AddElement(elK,0.001);
//Large intestine ->ID 38
d = 1.040 *g/cm3;
fIntestine_lrg = new G4Material("intestine_lrg",d,9);
fIntestine_lrg -> AddElement(elH,0.105);
fIntestine_lrg -> AddElement(elC,0.113);
fIntestine_lrg -> AddElement(elN,0.026);
fIntestine_lrg -> AddElement(elO,0.750);
fIntestine_lrg -> AddElement(elNa,0.001);
fIntestine_lrg -> AddElement(elP,0.001);
fIntestine_lrg -> AddElement(elS,0.001);
fIntestine_lrg -> AddElement(elCl,0.002);
fIntestine_lrg -> AddElement(elK,0.001);
//Spleen -> ID 39
d = 1.040 *g/cm3;
fSpleen = new G4Material("spleen",d,10);
fSpleen -> AddElement(elH,0.102);
fSpleen -> AddElement(elC,0.111);
fSpleen -> AddElement(elN,0.033);
fSpleen -> AddElement(elO,0.743);
fSpleen -> AddElement(elNa,0.001);
fSpleen -> AddElement(elP,0.002);
fSpleen -> AddElement(elS,0.002);
fSpleen -> AddElement(elCl,0.003);
fSpleen -> AddElement(elK,0.002);
fSpleen -> AddElement(elFe,0.001);
//Thyroid -> ID 40
d = 1.040 *g/cm3;
fThyroid = new G4Material("thyroid",d,10);
fThyroid -> AddElement(elH,0.104);
fThyroid -> AddElement(elC,0.117);
fThyroid -> AddElement(elN,0.026);
fThyroid -> AddElement(elO,0.745);
fThyroid -> AddElement(elNa,0.002);
fThyroid -> AddElement(elP,0.001);
fThyroid -> AddElement(elS,0.001);
fThyroid -> AddElement(elCl,0.002);
fThyroid -> AddElement(elK,0.001);
fThyroid -> AddElement(elI,0.001);
//Urinary Bladder -> ID 41
d = 1.040 *g/cm3;
fBladder = new G4Material("bladder",d,9);
fBladder -> AddElement(elH,0.105);
fBladder -> AddElement(elC,0.096);
fBladder -> AddElement(elN,0.026);
fBladder -> AddElement(elO,0.761);
fBladder -> AddElement(elNa,0.002);
fBladder -> AddElement(elP,0.002);
fBladder -> AddElement(elS,0.002);
fBladder -> AddElement(elCl,0.003);
fBladder -> AddElement(elK,0.003);
// Testes (Defined as ovaries_testes for visualisation purposes) -> ID 42
d = 1.040 *g/cm3;
fOvaries_testes = new G4Material("ovaries_testes",d,9);
fOvaries_testes -> AddElement(elH,0.106);
fOvaries_testes -> AddElement(elC,0.100);
fOvaries_testes -> AddElement(elN,0.021);
fOvaries_testes -> AddElement(elO,0.764);
fOvaries_testes -> AddElement(elNa,0.002);
fOvaries_testes -> AddElement(elP,0.001);
fOvaries_testes -> AddElement(elS,0.002);
fOvaries_testes -> AddElement(elCl,0.002);
fOvaries_testes -> AddElement(elK,0.002);
//Adrenals -> ID 43
d = 1.030 *g/cm3;
fAdrenals = new G4Material("adrenals",d,9);
fAdrenals -> AddElement(elH,0.104);
fAdrenals -> AddElement(elC,0.221);
fAdrenals -> AddElement(elN,0.028);
fAdrenals -> AddElement(elO,0.637);
fAdrenals -> AddElement(elNa,0.001);
fAdrenals -> AddElement(elP,0.002);
fAdrenals -> AddElement(elS,0.003);
fAdrenals -> AddElement(elCl,0.002);
fAdrenals -> AddElement(elK,0.002);
//Oesophagus -> ID 44
d = 1.030 *g/cm3;
fOesophagus = new G4Material("oesophagus",d,9);
fOesophagus -> AddElement(elH,0.104);
fOesophagus -> AddElement(elC,0.213);
fOesophagus -> AddElement(elN,0.029);
fOesophagus -> AddElement(elO,0.644);
fOesophagus -> AddElement(elNa,0.001);
fOesophagus -> AddElement(elP,0.002);
fOesophagus -> AddElement(elS,0.003);
fOesophagus -> AddElement(elCl,0.002);
fOesophagus -> AddElement(elK,0.002);
//Miscillaneous (Gallbladder, Trachea, Thymus, Tonsils, Ureters, ...) -> ID 45
d = 1.030 *g/cm3;
fMisc = new G4Material("misc",d,9);
fMisc -> AddElement(elH,0.104);
fMisc -> AddElement(elC,0.231);
fMisc -> AddElement(elN,0.028);
fMisc -> AddElement(elO,0.627);
fMisc -> AddElement(elNa,0.001);
fMisc -> AddElement(elP,0.002);
fMisc -> AddElement(elS,0.003);
fMisc -> AddElement(elCl,0.002);
fMisc -> AddElement(elK,0.002);
//Prostate (Defined as Uterus_Prostate for visualisation purposes) -> ID 46
d = 1.030 *g/cm3;
fUterus_prostate = new G4Material("uterus_prostate",d,9);
fUterus_prostate -> AddElement(elH,0.104);
fUterus_prostate -> AddElement(elC,0.231);
fUterus_prostate -> AddElement(elN,0.028);
fUterus_prostate -> AddElement(elO,0.627);
fUterus_prostate -> AddElement(elNa,0.001);
fUterus_prostate -> AddElement(elP,0.002);
fUterus_prostate -> AddElement(elS,0.003);
fUterus_prostate -> AddElement(elCl,0.002);
fUterus_prostate -> AddElement(elK,0.002);
//Lymph -> ID 47
d = 1.030 *g/cm3;
fLymph = new G4Material("lymph",d,7);
fLymph -> AddElement(elH,0.108);
fLymph -> AddElement(elC,0.042);
fLymph -> AddElement(elN,0.011);
fLymph -> AddElement(elO,0.831);
fLymph -> AddElement(elNa,0.003);
fLymph -> AddElement(elS,0.001);
fLymph -> AddElement(elCl,0.004);
//Breast (Mammary Gland)-> ID 48
d = 1.020 *g/cm3;
fBreast_glandular = new G4Material("breast_glandular",d,7);
fBreast_glandular -> AddElement(elH,0.112);
fBreast_glandular -> AddElement(elC,0.516);
fBreast_glandular -> AddElement(elN,0.011);
fBreast_glandular -> AddElement(elO,0.358);
fBreast_glandular -> AddElement(elNa,0.001);
fBreast_glandular -> AddElement(elS,0.001);
fBreast_glandular -> AddElement(elCl,0.001);
//Adipose tissue (fBreast) -> ID 49
d = 0.950 *g/cm3;
fBreast_adipose = new G4Material("breast_adipose",d,7);
fBreast_adipose -> AddElement(elH,0.114);
fBreast_adipose -> AddElement(elC,0.588);
fBreast_adipose -> AddElement(elN,0.008);
fBreast_adipose -> AddElement(elO,0.287);
fBreast_adipose -> AddElement(elNa,0.001);
fBreast_adipose -> AddElement(elS,0.001);
fBreast_adipose -> AddElement(elCl,0.001);
//Lung Tissue (Compressed Lung) -> ID 50
d = 0.382 *g/cm3;
fLung = new G4Material("lung",d,9);
fLung -> AddElement(elH,0.103);
fLung -> AddElement(elC,0.107);
fLung -> AddElement(elN,0.032);
fLung -> AddElement(elO,0.746);
fLung -> AddElement(elNa,0.002);
fLung -> AddElement(elP,0.002);
fLung -> AddElement(elS,0.003);
fLung -> AddElement(elCl,0.003);
fLung -> AddElement(elK,0.002);
//Contents of Gastro-intestinal tract -> ID 51
d = 1.040 *g/cm3;
fGastro_content = new G4Material("gastro_content",d,10);
fGastro_content -> AddElement(elH,0.100);
fGastro_content -> AddElement(elC,0.222);
fGastro_content -> AddElement(elN,0.022);
fGastro_content -> AddElement(elO,0.644);
fGastro_content -> AddElement(elNa,0.001);
fGastro_content -> AddElement(elP,0.002);
fGastro_content -> AddElement(elS,0.003);
fGastro_content -> AddElement(elCl,0.001);
fGastro_content -> AddElement(elK,0.004);
fGastro_content -> AddElement(elCa,0.001);
//Urine -> ID 52
d = 1.040 *g/cm3;
fUrine = new G4Material("urine",d,7);
fUrine -> AddElement(elH,0.107);
fUrine -> AddElement(elC,0.003);
fUrine -> AddElement(elN,0.010);
fUrine -> AddElement(elO,0.873);
fUrine -> AddElement(elNa,0.004);
fUrine -> AddElement(elP,0.001);
fUrine -> AddElement(elK,0.002);
}
G4Material* ICRP110PhantomMaterial_Male::GetMaterial(G4String material)
{
// Returns a material
G4Material* pttoMaterial = G4Material::GetMaterial(material);
if (!pttoMaterial) G4cout << "WARNING: material '" << material << "' is not defined!" << G4endl;
return pttoMaterial;
}
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
#include "ICRP110PhantomMessenger.hh"
#include "ICRP110PhantomConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
ICRP110PhantomMessenger::ICRP110PhantomMessenger(ICRP110PhantomConstruction* myUsrPhtm)
:fUserPhantom(myUsrPhtm)
{
fPhantomDir = new G4UIdirectory("/phantom/");
fPhantomDir -> SetGuidance("Set Your Phantom.");
fSexCmd = new G4UIcmdWithAString("/phantom/setPhantomSex",this);
fSexCmd -> SetGuidance("Set sex of Phantom: Male or Female.");
fSexCmd -> SetParameterName("phantomSex",true);
fSexCmd -> SetDefaultValue("female");
fSexCmd -> SetCandidates("male female");
fSexCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
fSectionCmd = new G4UIcmdWithAString("/phantom/setPhantomSection",this);
fSectionCmd -> SetGuidance("Set section of Phantom: head, trunk or full");
fSectionCmd -> SetParameterName("phantomSection",true);
fSectionCmd -> SetDefaultValue("head");
fSectionCmd -> SetCandidates("head trunk full");
fSectionCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
}
ICRP110PhantomMessenger::~ICRP110PhantomMessenger()
{
delete fSexCmd;
delete fSectionCmd;
delete fPhantomDir;
}
void ICRP110PhantomMessenger::SetNewValue(G4UIcommand* command,G4String newValue){
if( command == fSexCmd )
{
fUserPhantom -> SetPhantomSex(newValue);
//G4cout << "Phantom Messenger calls upon SetPhantomSex in Detector Construction. " << G4endl;
}
if( command == fSectionCmd )
{
fUserPhantom -> SetPhantomSection(newValue);
//G4cout << "Phantom Messenger calls upon SetPhantomSection in Detector Construction. " << G4endl;
}
}
@@ -0,0 +1,174 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
// Code based on the Geant4 extended example DICOM
//
//
#include "ICRP110PhantomNestedParameterisation.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "G4ThreeVector.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VisAttributes.hh"
#include "G4VVisManager.hh"
ICRP110PhantomNestedParameterisation::
ICRP110PhantomNestedParameterisation(const G4ThreeVector& halfVoxelSize,
std::vector<G4Material*>& mat,
G4int fnX_, G4int fnY_, G4int fnZ_)
:
fdX(halfVoxelSize.x()), fdY(halfVoxelSize.y()), fdZ(halfVoxelSize.z()),
fnX(fnX_), fnY(fnY_), fnZ(fnZ_), // number of voxels along X, Y and Z
fMaterials(mat), // vector of defined materials
fMaterialIndices(0) // vector which associates MaterialID to voxels
{
ReadColourData();//Define the color of each material
// from ColourMap.dat
}
ICRP110PhantomNestedParameterisation::~ICRP110PhantomNestedParameterisation()
{}
void ICRP110PhantomNestedParameterisation::ReadColourData()
{
// By default the tissues are not visible. Then
// the visualisation attributes are defined based on
// ColourMap.dat
G4VisAttributes* blankAtt = new G4VisAttributes;
blankAtt->SetVisibility( FALSE );
fColours["Default"] = blankAtt;
G4String colourFile = "ColourMap.dat";
G4cout << "Phantom Material Colours set via ColourMap.dat data file " << G4endl;
std::ifstream fin(colourFile.c_str());
G4int nMate;
G4String mateName;
G4double cred, cgreen, cblue, copacity;
fin >> nMate;
for( G4int ii = 0; ii < nMate; ii++ ){
fin >> mateName >> cred >> cgreen >> cblue >> copacity;
G4Colour colour( cred, cgreen, cblue, copacity );
G4VisAttributes* visAtt = new G4VisAttributes( colour );
visAtt->SetForceSolid(true);
fColours[mateName] = visAtt;
// G4cout << mateName << " colour set : " << colour << G4endl;
}
}
void ICRP110PhantomNestedParameterisation::
SetNoVoxel( G4int nx, G4int ny, G4int nz )
{
fnX = nx;
fnY = ny;
fnZ = nz;
}
G4Material* ICRP110PhantomNestedParameterisation::
ComputeMaterial(G4VPhysicalVolume* physVol, const G4int iz,
const G4VTouchable* parentTouch)
{
// protection for initialization and vis at idle state
//
if(parentTouch == nullptr)
return fMaterials[0];
// Copy number of voxels.
// Copy number of X and Y are obtained from replication number.
// Copy number of Z is the copy number of current voxel.
G4int ix = parentTouch -> GetReplicaNumber(0);
G4int iy = parentTouch -> GetReplicaNumber(1);
G4int copyID = ix + fnX*iy + fnX*fnY*iz;
//G4cout << "ix: "<< ix << ", iy: " << iy << ", iz:" << iz<< G4endl;
//G4cout << "copyID from the Nested Param: "<< copyID << G4endl;
//The copyID identifies the voxel
std::size_t matIndex = GetMaterialIndex(copyID);
static G4Material* mate = nullptr;
mate = fMaterials[matIndex];
if(true && physVol && G4VVisManager::GetConcreteInstance()) {
G4String mateName = fMaterials.at(matIndex)->GetName();
std::string::size_type iuu = mateName.find("__");
if( iuu != std::string::npos ) {
mateName = mateName.substr( 0, iuu ); // Associate material
}
if(0 < fColours.count(mateName)) {
physVol -> GetLogicalVolume() ->
SetVisAttributes(fColours.find(mateName)->second);
}
else {
physVol->GetLogicalVolume() ->
SetVisAttributes(fColours.begin() ->second); // Associate color
}
}
physVol -> GetLogicalVolume()->SetMaterial(mate);
return mate;
}
G4int ICRP110PhantomNestedParameterisation::GetMaterialIndex( G4int copyNo ) const
{
return fMaterialIndices[copyNo];
}
G4int ICRP110PhantomNestedParameterisation::GetNumberOfMaterials() const
{
return fMaterials.size();
}
G4Material* ICRP110PhantomNestedParameterisation::GetMaterial(G4int i) const
{
return fMaterials[i];
}
void ICRP110PhantomNestedParameterisation::
ComputeTransformation(const G4int copyNo, G4VPhysicalVolume* physVol) const
{
// Position of voxels.
// x and y positions are already defined in DetectorConstruction by using
// replicated volume. Hre we define the position along the z axis of voxels.
physVol -> SetTranslation(G4ThreeVector(0.,0.,(2.*static_cast<double>(copyNo)
+1.)*fdZ - fdZ*fnZ));
}
void ICRP110PhantomNestedParameterisation::
ComputeDimensions( G4Box& box, const G4int, const G4VPhysicalVolume* ) const
{
box.SetXHalfLength(fdX);
box.SetYHalfLength(fdY);
box.SetZHalfLength(fdZ);
}
@@ -0,0 +1,49 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//
//
#include "ICRP110PhantomPrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4GeneralParticleSource.hh"
ICRP110PhantomPrimaryGeneratorAction::ICRP110PhantomPrimaryGeneratorAction()
{
fParticleGun = new G4GeneralParticleSource();
}
ICRP110PhantomPrimaryGeneratorAction::~ICRP110PhantomPrimaryGeneratorAction()
{
delete fParticleGun;
}
void ICRP110PhantomPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
fParticleGun -> GeneratePrimaryVertex(anEvent);
}
@@ -0,0 +1,79 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//
#include "ICRP110ScoreWriterMessenger.hh"
#include "ICRP110UserScoreWriter.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "globals.hh"
#include "G4RunManager.hh"
ICRP110ScoreWriterMessenger::ICRP110ScoreWriterMessenger(ICRP110UserScoreWriter* myUsrScWriter)
:fUserScoreWriter(myUsrScWriter)
{
fPhantomDir = new G4UIdirectory("/phantom/");
fPhantomDir -> SetGuidance("Set Your Phantom.");
fSexCmd = new G4UIcmdWithAString("/phantom/setScoreWriterSex",this);
fSexCmd -> SetGuidance("Set sex of Phantom: Male or Female.");
fSexCmd -> SetParameterName("ScoreWriterSex",true);
fSexCmd -> SetDefaultValue("female");
fSexCmd -> SetCandidates("male female");
fSexCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
fSectionCmd = new G4UIcmdWithAString("/phantom/setScoreWriterSection",this);
fSectionCmd -> SetGuidance("Set section of Phantom: Head, Trunk or Full.");
fSectionCmd -> SetParameterName("ScoreWriterSection",true);
fSectionCmd -> SetDefaultValue("head");
fSectionCmd -> SetCandidates("head trunk full");
fSectionCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
}
ICRP110ScoreWriterMessenger::~ICRP110ScoreWriterMessenger()
{
delete fSexCmd;
delete fSectionCmd;
delete fPhantomDir;
}
void ICRP110ScoreWriterMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == fSexCmd )
{
fUserScoreWriter -> SetPhantomSex(newValue);
}
if( command == fSectionCmd )
{
fUserScoreWriter -> SetPhantomSection(newValue);
}
}
@@ -0,0 +1,565 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Code developed by:
// S.Guatelli, M. Large and A. Malaroda, University of Wollongong
//
//Original code from geant4/examples/extended/runAndEvent/RE03
//
#include <vector>
#include <map>
#include "ICRP110UserScoreWriter.hh"
#include "ICRP110ScoreWriterMessenger.hh"
#include "G4SystemOfUnits.hh"
#include "G4SDParticleFilter.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4VScoringMesh.hh"
ICRP110UserScoreWriter::ICRP110UserScoreWriter():
G4VScoreWriter()
{
fMessenger = new ICRP110ScoreWriterMessenger(this);
fSex = "female"; //Default phantom sex is female
fSection = "head"; // Default phantom section is head
}
ICRP110UserScoreWriter::~ICRP110UserScoreWriter()
{
delete fMessenger;
}
void ICRP110UserScoreWriter::DumpQuantityToFile(const G4String & psName, const G4String & fileName, const G4String & option)
{
using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
if(verboseLevel > 0)
{
G4cout << "ICRP110UserScorer-defined DumpQuantityToFile() method is invoked." << G4endl;
}
// change the option string into lowercase to the case-insensitive.
G4String opt = option;
std::transform(opt.begin(), opt.end(), opt.begin(), (int (*)(int))(tolower));
// confirm the option
if(opt.size() == 0) opt = "csv";
//--------------------------------------------------------------------//
//----------------Create Scoring Mesh Output Text File----------------//
//--------------------------------------------------------------------//
// First we create use the scoring mesh to create a default output text
// file containing 4 columns: voxel number along x, y, z, and dose deposited
// in that voxel (in Gy). This file is to be called "PhantomDose_Mesh.txt".
std::ofstream ofile(fileName);
if(!ofile)
{
G4cerr << "ERROR : DumpToFile : File open error -> " << fileName << G4endl;
return;
}
ofile << "# mesh name: " << fScoringMesh -> GetWorldName() << G4endl;
// retrieve the map
MeshScoreMap fSMap = fScoringMesh -> GetScoreMap();
MeshScoreMap::const_iterator msMapItr = fSMap.find(psName);
if(msMapItr == fSMap.end())
{
G4cerr << "ERROR : DumpToFile : Unknown quantity, \""<< psName
<< "\"." << G4endl;
return;
}
std::map<G4int, G4StatDouble*> * score = msMapItr -> second-> GetMap();
ofile << "# primitive scorer name: " << msMapItr -> first << G4endl;
// declare dose array and initialize to zero.
std::vector<double> ScoringMeshDose;
for(G4int y = 0; y < fNMeshSegments[0]*fNMeshSegments[1]*fNMeshSegments[2]; y++) ScoringMeshDose.push_back(0.);
ofile << std::setprecision(16); // for double value with 8 bytes
for(G4int x = 0; x < fNMeshSegments[0]; x++) {
for(G4int y = 0; y < fNMeshSegments[1]; y++) {
for(G4int z = 0; z < fNMeshSegments[2]; z++){
// Retrieve dose in each scoring mesh bin/voxel
G4int idx = GetIndex(x, y, z);
std::map<G4int, G4StatDouble*>::iterator value = score -> find(idx);
if (value != score -> end()) ScoringMeshDose[idx] += (value->second->sum_wx())/gray;
}
}
}
ofile << std::setprecision(6);
ofile << std::setprecision(16); // for double value with 8 bytes
for(G4int x = 0; x < fNMeshSegments[0]; x++) {
for(G4int y = 0; y < fNMeshSegments[1]; y++) {
for(G4int z = 0; z < fNMeshSegments[2]; z++){
G4int idx = GetIndex(x, y, z);
ofile << x << "\t" << y << "\t" << z << "\t" << ScoringMeshDose[idx] << G4endl;
//Store x,y,z and dose for each voxel in output text file.
}
}
}
// Close the output ASCII file
ofile.close();
//----------------------------------------------------------------------------------------//
//-----Read Data.dat File to determine the name and number of slice files to open---------//
//----------------------------------------------------------------------------------------//
// Using the macro commands from the .in files, the UserScoreWriter identifies which
// phantom sex and section has been constructed. We then store the names of the individual z-slices
// which have been called upon in the detector construction when creating the phantom.
G4int NSlices = 0;
G4int NXVoxels = 0;
G4int NYVoxels = 0;
std::ifstream DataFile;
G4cout << "Phantom Sex: " << fSex << G4endl;
G4cout << "Phantom Section: " << fSection << G4endl;
G4String male = "male";
G4String female = "female";
//G4String
//Determine Phantom Sex and Section which was Simulated
if (fSex == "male")
{
if (fSection == "head")
{
DataFile.open("ICRPdata/MaleHead.dat");
G4cout << "Selecting data file ICRPdata/MaleHead.dat..." << G4endl;
}
if (fSection == "trunk")
{
DataFile.open("ICRPdata/MaleTrunk.dat");
G4cout << "Selecting data file ICRPdata/MaleTrunk.dat..." << G4endl;
}
if (fSection == "full")
{
DataFile.open("ICRPdata/MaleData.dat");
G4cout << "Selecting data file ICRPdata/MaleData.dat..." << G4endl;
}
}
else if(fSex == "female")
{
if (fSection == "head")
{
DataFile.open("ICRPdata/FemaleHead.dat");
G4cout << "Selecting data file ICRPdata/FemaleHead.dat..." << G4endl;
}
if (fSection == "trunk")
{
DataFile.open("ICRPdata/FemaleTrunk.dat");
G4cout << "Selecting data file ICRPdata/FemaleTrunk.dat..." << G4endl;
}
if (fSection == "full")
{
DataFile.open("ICRPdata/FemaleData.dat");
G4cout << "Selecting data file ICRPdata/FemaleData.dat..." << G4endl;
}
}
else
{
G4cout << "Phantom Sex or section not correctly specified to ICRP110UserScoreWriter" << G4endl;
}
//Check if file opens
if(DataFile.good() != 1 )
{
G4cout << "Problem Reading Data File" << G4endl;
}
else
{
G4cout << "Opening Data.dat File..." << G4endl;
}
DataFile >> NSlices;
G4cout << "Number of Phantom Slices Simulated = " << NSlices << G4endl;
DataFile >> NXVoxels >> NYVoxels;
G4cout << "Number of X Voxels per slice = " << NXVoxels << G4endl;
G4cout << "Number of Y Voxels per slice = " << NYVoxels << G4endl;
G4int VoxelsPerSlice = 0;
VoxelsPerSlice = NXVoxels * NYVoxels;
//Skip lines 4-60 of Data.dat as they hold no useful information for this code
for (G4int i = 0; i < 58; i++){
DataFile.ignore(256, '\n');
}
// Read file names to open from Data.dat (i.e. those that were used in simulation)
std::vector<G4String> SliceName; //char SliceName[NSlices][20]; //Stores name and number of phantom slices used in simulation
for(G4int i = 0; i < NSlices; i++){
SliceName.push_back("empty");
}
for (G4int i = 0; i < NSlices; i++){
DataFile >> SliceName[i];
}
//--------------------------------------------------------------------//
//----------------------Read Phantom Slice Files----------------------//
//--------------------------------------------------------------------//
// Reads each of the phantom z-slice files identified by the above code
// and stores the organIDs within each voxel sequentially.
// Later, we will compare the dose in each voxel to the organ ID of each
// voxel to calculate total dose in each organ.
G4int ARRAY_SIZE = VoxelsPerSlice * NSlices;
std::vector<G4int> OrganIDs;
std::ifstream PhantomFile;
for (G4int ii = 0; ii < NSlices; ii++){
G4String sliceVar = SliceName[ii];
G4String slice;
if (fSex == "male")
{
slice = "ICRPdata/ICRP110_g4dat/AM/"+sliceVar;
}
else if(fSex == "female")
{
slice = "ICRPdata/ICRP110_g4dat/AF/"+sliceVar;
}
PhantomFile.open(slice.c_str());
//Check if file opens
if(PhantomFile.good() != 1 )
{
G4cout << "Problem Reading Phantom Slice File:" << SliceName[ii] << G4endl;
}
else
{
G4cout << "Opening Phantom Slice File: " << SliceName[ii] << G4endl;
}
G4int FNVoxelX;
G4int FNVoxelY;
G4int FNVoxelZ;
//Input first 3 numbers of file - They are not organ IDs
PhantomFile >> FNVoxelX >> FNVoxelY >> FNVoxelZ;
G4int aa = 0;
for (G4int i = 0; i < VoxelsPerSlice; i++)
{
PhantomFile >> aa;
OrganIDs.push_back(aa);
}
PhantomFile.close();
}
//---------------------------------------------------------------//
//--------------Read Data from Scoring Mesh Text File------------//
//---------------------------------------------------------------//
// Opens and reads initial/default scoring mesh output file which
// was created at the beginning of the code. We now store the dose in each
// voxel to cross reference against the organ ID of each voxel for
// calculations of total dose in each organ.
std::ifstream DoseFile(fileName);
//Check if file opens
if(DoseFile.good() != 1 )
{
G4cout << "Problem Reading Data File PhantomMesh_Dose.txt" << G4endl;
}
else {
G4cout << "Opening File PhantomMesh_Dose.txt" << G4endl;
}
//-----Reads Phantom Mesh Text File and Stores Data in 6 different Vectors-------//
G4int col = 4;
G4int lines = VoxelsPerSlice*NSlices;
//Ignore first 2 lines of PhantomMesh.txt as they are text headers
DoseFile.ignore(256, '\n');
DoseFile.ignore(256, '\n');
std::vector<G4int> X_MeshID; //Stores X-position of all scoring mesh voxels
std::vector<G4int> Y_MeshID; //Stores Y-position
std::vector<G4int> Z_MeshID; //Stores Z-position
std::vector<G4double> Dose; //Stores Dose in all voxels
G4int nX = 0; //Number along X of scoring mesh voxel
G4int nY = 0; //Number along Y
G4int nZ = 0; //Number along Z
G4double DoseDep = 0.0; //Dose deposited in individual voxels
for (G4int i=0; i< lines; i++){
for (G4int j=0; j < col;){
DoseFile >> nX; //Reads number along X of current scoring mesh voxel
X_MeshID.push_back(nX); //Stores it sequentially in vector X_MeshID
j++;
DoseFile >> nY; // Reads number along Y
Y_MeshID.push_back(nY); // Stores in vector
j++;
DoseFile >> nZ; // Reads number along Z
Z_MeshID.push_back(nZ); // Stores in vector
j++;
DoseFile >> DoseDep; // Reads dose in each voxel
Dose.push_back(DoseDep); // Stores in vector
j++;
}
}
DoseFile.close();
//--------------------------------------------------------------------//
//---------Reads AF_organs.dat file and stores info about-------------//
//------------------------the phantom organs--------------------------//
//--------------------------------------------------------------------//
std::ifstream PhantomOrganNames;
if (strcmp(fSex.c_str(), male.c_str()) == 0)
{
PhantomOrganNames.open ("ICRPdata/ICRP110_g4dat/P110_data_V1.2/AM/AM_organs.dat");
//Check if file opens
if(PhantomOrganNames.good() != 1 )
{
G4cout << "Problem reading AM_organs.dat" << G4endl;
}
else
{
G4cout << "Reading AM_organs.dat" << G4endl;
}
}
else if(strcmp(fSex.c_str(), female.c_str()) == 0)
{
PhantomOrganNames.open ("ICRPdata/ICRP110_g4dat/P110_data_V1.2/AF/AF_organs.dat");
//Check if file opens
if(PhantomOrganNames.good() != 1 )
{
G4cout << "Problem reading AF_organs.dat" << G4endl;
}
else
{
G4cout << "Reading AF_organs.dat" << G4endl;
}
}
PhantomOrganNames.ignore(256, '\n');
PhantomOrganNames.ignore(256, '\n');
PhantomOrganNames.ignore(256, '\n');
PhantomOrganNames.ignore(256, '\n');
G4String str;
std::vector<G4String> OrganNames;
OrganNames.push_back("0 Air"); // Register air surrounding phantom
//Fill with organ IDs of the phantom from ICRP data files (located in /ICRPdata/ICRP110_g4dat/P110_data_V1.2/)
while(getline(PhantomOrganNames, str))
{
OrganNames.push_back(str);
}
OrganNames.push_back("141 Phantom Top/Bottom Skin Layer"); //Registers top and bottom slices of phantom made entirely of
// skin. The skin in these layers has organ ID 141 to differentiate it from other skin, and is given its
// own organ ID so that the user can choose whether to include it or not.
//---------------------------------------------------------------------------//
//----------------------Writes Outputs of code to File-----------------------//
//-------------------------------OrganDoses.dat------------------------------//
//---------------------------------------------------------------------------//
// As the final step, we compare the dose in each voxel with the voxels organID
// and sum the dose in voxels with identical organIDs to obtain total doses in
// each organ. All this information is then output to the file "OrganDoses.out".
std::ofstream OutputFile2;
G4int VoxelNumber = 0;
G4int OrganIndex = 0;
G4int NOrganIDs = OrganNames.size();
G4cout << "NOrganIDs: " << NOrganIDs << G4endl;
std::vector <G4double> OrganDose;
G4double a = 0.0;
for (G4int i = 0; i < NOrganIDs; i++)
{
OrganDose.push_back(a);
}
for (G4int i = 0; i < ARRAY_SIZE; i++){
VoxelNumber = X_MeshID[i] + NXVoxels * Y_MeshID[i] + VoxelsPerSlice * Z_MeshID[i];
OrganIndex = OrganIDs[VoxelNumber];
OrganDose[OrganIndex] += Dose[i];
// G4cout << "Organ index: " << OrganIndex << G4endl;
}
/*
for (G4int i = 0; i< NOrganIDs; i++)
{
G4cout << "OrganDose for OrganID " << i << " gives: " << OrganDose[i] << G4endl;
}
*/
OutputFile2.open ("OrganDoses.out");
//Check if file opens
if(OutputFile2.good() != 1 )
{
G4cout << "Problem writing output to OrganDoses.out" << G4endl;
}
else {
G4cout << "Writing output to OrganDoses.out" << G4endl;
}
G4double TotalDose = 0.0;
OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
OutputFile2 << "-------------------------------ORGAN INFO-----------------------------------" << G4endl;
OutputFile2 << "-------------------(of organs where dose was scored)------------------------" << G4endl;
OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
OutputFile2 << "ID" << '\t' << '\t' << "Organ Name" << '\t' << " " << '\t' << " " << '\t' << " " << '\t' << "Material ID" << '\t' << '\t' << "Density (g/cm^3) " << G4endl;
for(G4int i = 1; i < NOrganIDs; i++)
{
if (OrganDose[i] != 0)
{
if (i != 140) //Skip dose deposited in air inside body
{
OutputFile2 << OrganNames[i] << G4endl;
}
}
}
OutputFile2 << G4endl;
OutputFile2 << '\t' << "-------------- " << G4endl;
OutputFile2 << '\t' << "ABSORBED DOSES " << G4endl;
OutputFile2 << '\t' << "-------------- " << G4endl;
OutputFile2 << '\t' << "OrganID" << '\t' << "Dose(Gy)" << G4endl;
for (G4int i = 1; i < NOrganIDs; i++)
{
if (OrganDose[i] != 0)
{
if (i != 140) //Skip dose deposited in air inside body
{
OutputFile2 << '\t' << i << '\t' << '\t' << OrganDose[i] << G4endl;
}
}
}
//Sum total dose over all organs
for (G4int i = 1; i < NOrganIDs; i++)
{
if (i != 140) //Skip dose deposited in air inside body
{
TotalDose += OrganDose[i];
}
}
OutputFile2 << G4endl;
OutputFile2 << "Total Dose over all organs = " << TotalDose << " Gy" << G4endl;
OutputFile2 << G4endl;
OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
OutputFile2 << "-------------------------------ORGAN DOSES----------------------------------" << G4endl;
OutputFile2 << "-----------(for all organs [includes air - OrganIDs = 0, 140])--------------" << G4endl;
OutputFile2 << "--------------([and top/bottom skin layer - OrganIDs = 141])----------------" << G4endl;
OutputFile2 << "OrganID" << '\t' << "Dose(Gy)" << G4endl;
OutputFile2 << "-------------------------------" << G4endl;
for (G4int i = 0; i < NOrganIDs; i++)
{
OutputFile2 << i << '\t' << OrganDose[i] << G4endl;
}
OutputFile2 << "Total Dose over all organs = " << TotalDose << " Gy" << G4endl;
G4cout << "Total Dose over all Organs within the Phantom is " << TotalDose << " Gy" << G4endl;
OutputFile2.close();
}
// Sets the sex of the phantom as defined through the messenger class
void ICRP110UserScoreWriter::SetPhantomSex(G4String newSex)
{
fSex = newSex;
if (fSex == "male")
{
G4cout << ">> Male Phantom identified by UserScoreWriter." << G4endl;
}
if (fSex == "female")
{
G4cout << ">> Female Phantom identified by UserScoreWriter." << G4endl;
}
if ((fSex != "female") && (fSex != "male"))
G4cout << fSex << " can not be defined!" << G4endl;
}
// Sets the section of the phantom as defined through the messenger class
void ICRP110UserScoreWriter::SetPhantomSection(G4String newSection)
{
fSection = newSection;
if (fSection == "head")
{
G4cout << ">> Partial Head Phantom identified by UserScoreWriter." << G4endl;
}
if (fSection == "trunk")
{
G4cout << ">> Partial Trunk Phantom identified by UserScoreWriter." << G4endl;
}
if (fSection == "full")
{
G4cout << ">> Custom/Full Phantom identified by UserScoreWriter." << G4endl;
}
if ((fSection != "head") && (fSection != "trunk") && (fSection != "full"))
G4cout << fSection << " can not be defined!" << G4endl;
}
@@ -0,0 +1,81 @@
# Use this open statement to create an OpenGL view:
/run/initialize
#/vis/open OGLSX
/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
#
# Define background colour (comment out for black as default)
#/vis/viewer/set/background white
#
# Draw geometry:
/vis/drawVolume worlds
#
# Specify view angle:
/vis/viewer/set/viewpointThetaPhi 85 -75 deg
#/vis/viewer/set/lightsMove with-camera
#
# Set Voxels number to be visualised
/vis/ogl/set/displayListLimit 4000000
# 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
#Define the primary particles
/control/execute primary.mac
+6 -3
View File
@@ -1,6 +1,9 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
cmake_minimum_required(VERSION 3.8...3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(STCyclotron)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
@@ -24,8 +27,8 @@ include_directories(${PROJECT_SOURCE_DIR}/include)
include(${Geant4_USE_FILE})
#---------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
#
include_directories(${PROJECT_SOURCE_DIR}/include
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
View File
+13 -5
View File
@@ -1,18 +1,26 @@
-------------------------------------------------------------------
-------------------------------------------------------------------
=========================================================
Geant4 - radiprotection example
=========================================================
==============================================================
Geant4 - Solid-target cyclotron example
==============================================================
Category History file
---------------------
12.11.2020 - S. Guatelli STCyclotron-V10-06-02
- Migration to G4RunFactory
05.11.2020 - Gunter Folger STCyclotron-V10-06-01
- Update READme to recommended env variable G4PARTCILEHPDATA
02.11.2020 - B.Morgan tag STCyclotron-V10-06-00
- Support same CMake version range as core Geant4
19.11.2019 - G. Cosmo tag STCyclotron-V10-05-01
- Fixed compilation warnings for cases of implicit type conversions.
08.11.2019 - S. Guatelli tag STCyclotron-V10-05-00
new example modelling a solid target of the cyclotron to study to
new example modelling a solid target of the cyclotron to study to
production of the radioisotope of interest for proton irradiation.
View File
View File
View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File
View File
View File
View File
View File
View File
View File
+11 -2
View File
@@ -46,11 +46,20 @@ Beforehand, you first need to make sure that the database used for inelastic col
particles is set up correctly. You can download formated data of the TENDL and ENDF-VII0 database
at the following links:
http://geant4.web.cern.ch/geant4/support/download.shtml (TENDL1.3)
TENDL data:
- CMake can download and install this dataset, add
-DGEANT4_INSTALL_DATASETS_TENDL=ON
to your CMake options.
- or, download via download page searching for TENDL download
https://cern.ch/geant4/support/download
- or direct download:
https://cern.ch/geant4-data/datasets/G4TENDL.1.4.tar.gz
ENDF-VII0:
ftp://gdo-nuclear.ucllnl.org/pub/G4LEND/ (G4 Low Energy Nuclear Data)
In your bashrc file, add the following:
export G4PROTONHPDATA=/PATH_TO_TENDL____OR____ENDF_DATABASE/Proton
export G4PARTICLEHPDATA=/PATH_TO_TENDL____OR____ENDF_DATABASE
export G4NEUTRONHPDATA=/PATHTO_GEANT4_INSTALLATION_FOLDER/share/Geant4-vXX.XX/data/G4NDL4.5
export G4PHP_DO_NOT_ADJUST_FINAL_STATE=1
export G4PHP_MULTIPLICITY_METHOD=Poisson
+7 -10
View File
@@ -34,13 +34,11 @@
//
// file STCyclotron.cc
//
#include "G4MTRunManager.hh"
#include "G4RunManager.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "STCyclotronAnalysis.hh"
#include "STCyclotronActionInitialization.hh"
#include "STCyclotronDetectorConstruction.hh"
#include "STCyclotronPhysicsList.hh"
@@ -49,13 +47,12 @@
int main(int argc, char** argv)
{
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager;
runManager->SetNumberOfThreads(4); // Is equal to 2 by default
#else
G4RunManager* runManager = new G4RunManager;
#endif
// Construct the default run manager
//
auto* runManager = G4RunManagerFactory::CreateRunManager();
G4int nThreads = 4;
runManager -> SetNumberOfThreads(nThreads);
//Set mandatory initialization classes
STCyclotronDetectorConstruction* det = new STCyclotronDetectorConstruction();
runManager->SetUserInitialization(det);
View File
View File

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