Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
-6
View File
@@ -20,10 +20,4 @@ different techniques for achieving event parallelism with Geant4.
library (TBB), and organise MT event-level parallelism as TBB tasks.
<br><br>
- TopC examples are Geant4 examples adapted to be run together with
the TOP-C communication layer application on either a cluster of systems
or multi-processor machines. They are based on N02 and N04 examples,
originally provided in novice examples (see more in \ref README_novice)
<br><br>
*/
+3
View File
@@ -5,6 +5,9 @@ which **must** added in reverse chronological order (newest at the top). It must
be used as a substitute for writing good git commit messages!
## 2024-05-30 Ben Morgan (exparallel-V11-02-00)
- Remove obsolete and untested TopC example
## 2023-11-15 I. Hrivnacova (exparallel-V11-01-00)
- Updated vis.mac macros:
- Changed "/vis/open XYZ [600x600-0+0]" to "/vis/open" to allow run-time choices
+3
View File
@@ -4,6 +4,9 @@ See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
## 2023-03-11 Ben Morgan (MPI-V11-02-00)
- Move CTests definitions to tests/ctests_examples
## 2023-11-09 I. Hrivnacova (MPI-V11-01-03)
- Coding guidelines - document examples macros in README files
- Renamed v.mac in vis.mac
@@ -1,134 +0,0 @@
#Workaround: rely on executables build by cmake since it does not compile
#correctly because FindG4mpi.cmake is not found
find_package(MPI QUIET)
if(NOT MPI_CXX_FOUND)
message(STATUS "G4 Examples: MPI not found --> mpi based tests disabled")
return()
endif()
message(STATUS "G4 Examples: mpi examples will use mpi launcher: " ${MPIEXEC})
# Base output dir for MPI examples:
set(G4MPI_CTESTS_BASE_OUTPUT_DIR "${PROJECT_BINARY_DIR}/examples/extended/parallel/MPI")
# Set G4mpi_DIR fo later pass-down to examples
set(G4mpi_DIR "${G4MPI_CTESTS_BASE_OUTPUT_DIR}/G4mpi")
# - Build/Test G4mpi
geant4_add_test(mpi-libg4mpi
COMMAND ${CMAKE_COMMAND} -E echo "G4mpi build complete"
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/source
BINARY_DIR ${G4mpi_DIR}
PROJECT libG4mpi
BUILD G4mpi
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
LABELS MPI
)
# - Build/Test exMPI01
# variable to simplify paths
set(G4MPI_EX01_BINDIR ${G4MPI_CTESTS_BASE_OUTPUT_DIR}/exMPI01)
geant4_add_test(mpi-ex01-sequential
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/examples/exMPI01
BINARY_DIR ${G4MPI_EX01_BINDIR}
PROJECT exMPI01
BUILD exMPI01
COMMAND ${G4MPI_EX01_BINDIR}/exMPI01 run.mac
WORKING_DIRECTORY ${G4MPI_EX01_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-libg4mpi
LABELS MPI
)
# Needs G4mpi
set_property(TEST mpi-ex01-sequential APPEND PROPERTY ENVIRONMENT G4mpi_DIR=${G4mpi_DIR})
geant4_add_test(mpi-ex01
COMMAND ${MPIEXEC} -n 2 ${G4MPI_EX01_BINDIR}/exMPI01 run.mac
WORKING_DIRECTORY ${G4MPI_EX01_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-ex01-sequential
LABELS MPI
)
# - Build/Test exMPI02
# Needs ROOT
find_package(ROOT QUIET)
if(ROOT_FOUND)
set(G4MPI_EX02_BINDIR ${G4MPI_CTESTS_BASE_OUTPUT_DIR}/exMPI02)
geant4_add_test(mpi-ex02-sequential
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/examples/exMPI02
BINARY_DIR ${G4MPI_EX02_BINDIR}
PROJECT exMPI02
BUILD exMPI02
COMMAND ${G4MPI_EX02_BINDIR}/exMPI02 run.mac
WORKING_DIRECTORY ${G4MPI_EX02_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-libg4mpi
LABELS MPI
)
# Needs G4mpi
set_property(TEST mpi-ex02-sequential APPEND PROPERTY ENVIRONMENT G4mpi_DIR=${G4mpi_DIR})
geant4_add_test(mpi-ex02
COMMAND ${MPIEXEC} -n 2 ${G4MPI_EX02_BINDIR}/exMPI02 run.mac
WORKING_DIRECTORY ${G4MPI_EX02_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-ex02-sequential
LABELS MPI
)
else()
message(STATUS "G4 Examples: MPI example exMPI02 disabled: ROOT not found")
endif()
# - Build/Test exMPI03
# variable to simplify paths
set(G4MPI_EX03_BINDIR ${G4MPI_CTESTS_BASE_OUTPUT_DIR}/exMPI03)
geant4_add_test(mpi-ex03-sequential
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/examples/exMPI03
BINARY_DIR ${G4MPI_EX03_BINDIR}
PROJECT exMPI03
BUILD exMPI03
COMMAND ${G4MPI_EX03_BINDIR}/exMPI03 run.mac
WORKING_DIRECTORY ${G4MPI_EX03_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-libg4mpi
LABELS MPI
)
# Needs G4mpi
set_property(TEST mpi-ex03-sequential APPEND PROPERTY ENVIRONMENT G4mpi_DIR=${G4mpi_DIR})
geant4_add_test(mpi-ex03
COMMAND ${MPIEXEC} -n 2 ${G4MPI_EX03_BINDIR}/exMPI03 run.mac
WORKING_DIRECTORY ${G4MPI_EX03_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-ex03-sequential
LABELS MPI
)
# - Build/Test exMPI04
# variable to simplify paths
set(G4MPI_EX04_BINDIR ${G4MPI_CTESTS_BASE_OUTPUT_DIR}/exMPI04)
geant4_add_test(mpi-ex04-sequential
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/examples/exMPI04
BINARY_DIR ${G4MPI_EX04_BINDIR}
PROJECT exMPI04
BUILD exMPI04
COMMAND ${G4MPI_EX04_BINDIR}/exMPI04 run.mac
WORKING_DIRECTORY ${G4MPI_EX04_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-libg4mpi
LABELS MPI
)
# Needs G4mpi
set_property(TEST mpi-ex04-sequential APPEND PROPERTY ENVIRONMENT G4mpi_DIR=${G4mpi_DIR})
geant4_add_test(mpi-ex04
COMMAND ${MPIEXEC} -n 3 ${G4MPI_EX04_BINDIR}/exMPI04 run.mac
WORKING_DIRECTORY ${G4MPI_EX04_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-ex04-sequential
LABELS MPI
)
@@ -30,19 +30,18 @@
#include "G4MPIsession.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
# include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
# include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "FTFP_BERT.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc, char** argv)
@@ -59,33 +58,33 @@ int main(int argc, char** argv)
// MPI session (G4MPIsession) instead of G4UIterminal
// Terminal availability depends on your MPI implementation.
G4MPIsession* session = g4MPI-> GetMPIsession();
G4MPIsession* session = g4MPI->GetMPIsession();
// LAM/MPI users can use G4tcsh.
G4String prompt = "";
prompt += "G4MPI";
prompt += "(%s)[%/]:";
session-> SetPrompt(prompt);
session->SetPrompt(prompt);
// --------------------------------------------------------------------
// user application setting
// --------------------------------------------------------------------
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager();
runManager-> SetNumberOfThreads(4);
runManager->SetNumberOfThreads(4);
#else
G4RunManager* runManager = new G4RunManager();
#endif
// setup your application
runManager-> SetUserInitialization(new DetectorConstruction);
runManager-> SetUserInitialization(new FTFP_BERT);
runManager-> SetUserInitialization(new ActionInitialization);
runManager->SetUserInitialization(new DetectorConstruction);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization);
runManager-> Initialize();
runManager->Initialize();
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
visManager->Initialize();
G4cout << G4endl;
// --------------------------------------------------------------------
@@ -93,7 +92,7 @@ int main(int argc, char** argv)
// MPIsession treats both interactive and batch modes.
// Just start your session as below.
// --------------------------------------------------------------------
session-> SessionStart();
session->SessionStart();
// --------------------------------------------------------------------
// termination
@@ -32,13 +32,13 @@
#include "G4VUserActionInitialization.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
~ActionInitialization();
virtual void Build() const;
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
~ActionInitialization();
virtual void Build() const;
};
#endif
@@ -32,13 +32,14 @@
#include "G4VUserDetectorConstruction.hh"
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
~DetectorConstruction();
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
};
#endif
@@ -32,12 +32,13 @@
#include "globals.hh"
class Materials {
public:
Materials();
~Materials();
class Materials
{
public:
Materials();
~Materials();
void Construct();
void Construct();
};
#endif
@@ -34,15 +34,16 @@
class G4ParticleGun;
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
public:
PrimaryGeneratorAction();
~PrimaryGeneratorAction();
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction();
~PrimaryGeneratorAction();
virtual void GeneratePrimaries(G4Event* anEvent);
virtual void GeneratePrimaries(G4Event* anEvent);
private:
G4ParticleGun* fparticleGun;
private:
G4ParticleGun* fparticleGun;
};
#endif
@@ -28,18 +28,14 @@
/// @brief Define action initialization
#include "ActionInitialization.hh"
#include "PrimaryGeneratorAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization()
: G4VUserActionInitialization()
{
}
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
}
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const
@@ -27,6 +27,10 @@
/// @file DetectorConstruction.cc
/// @brief Define geometry
#include "DetectorConstruction.hh"
#include "Materials.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
@@ -34,94 +38,83 @@
#include "G4SystemOfUnits.hh"
#include "G4Tubs.hh"
#include "G4VisAttributes.hh"
#include "DetectorConstruction.hh"
#include "Materials.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
{
}
DetectorConstruction::DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
}
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
{
// material definition
Materials* materialConstruction = new Materials;
materialConstruction-> Construct();
materialConstruction->Construct();
G4Material* mate;
G4VisAttributes* va;
// world volume
const G4double DXYZ_AREA = 32.*cm;
G4Box* areaSolid = new G4Box("AREA", DXYZ_AREA/2., DXYZ_AREA/2.,
DXYZ_AREA/2.);
const G4double DXYZ_AREA = 32. * cm;
G4Box* areaSolid = new G4Box("AREA", DXYZ_AREA / 2., DXYZ_AREA / 2., DXYZ_AREA / 2.);
G4Material* vacuum = G4Material::GetMaterial("Vacuum");
G4LogicalVolume* areaLV = new G4LogicalVolume(areaSolid, vacuum, "AREA_LV");
G4PVPlacement* area = new G4PVPlacement(0, G4ThreeVector(), "AREA_PV",
areaLV, 0, false, 0);
G4PVPlacement* area = new G4PVPlacement(0, G4ThreeVector(), "AREA_PV", areaLV, 0, false, 0);
// vis. attributes
va = new G4VisAttributes(G4Color(1.,1.,1.));
va-> SetVisibility(false);
areaLV-> SetVisAttributes(va);
va = new G4VisAttributes(G4Color(1., 1., 1.));
va->SetVisibility(false);
areaLV->SetVisAttributes(va);
// detectors
// voxel
const G4double dvoxel = 10.*mm;
const G4double dl = 10.*cm;
const G4double dvoxel = 10. * mm;
const G4double dl = 10. * cm;
G4Box* svoxel = new G4Box("voxel", dvoxel, dl, dvoxel);
mate = G4Material::GetMaterial("Vacuum");
G4LogicalVolume* lvoxel = new G4LogicalVolume(svoxel, mate, "voxel");
va = new G4VisAttributes(G4Color(0.,0.8,0.8));
va-> SetVisibility(false);
lvoxel-> SetVisAttributes(va);
va = new G4VisAttributes(G4Color(0., 0.8, 0.8));
va->SetVisibility(false);
lvoxel->SetVisAttributes(va);
G4int ix, iz;
G4int index = 0;
for ( iz = 0; iz < 5; iz++ ) {
for ( ix = -7; ix <= 7; ix++ ) {
G4double x0 = (2.*ix) * cm;
G4double z0 = (-13.+2.*iz) * cm;
new G4PVPlacement(0, G4ThreeVector(x0, 0., z0),
lvoxel, "voxel", areaLV, false, index);
for (iz = 0; iz < 5; iz++) {
for (ix = -7; ix <= 7; ix++) {
G4double x0 = (2. * ix) * cm;
G4double z0 = (-13. + 2. * iz) * cm;
new G4PVPlacement(0, G4ThreeVector(x0, 0., z0), lvoxel, "voxel", areaLV, false, index);
index++;
}
}
// tube
G4Tubs* stube = new G4Tubs("tube", 0.*mm, 19./2.*mm, dl, 0., 360.*deg);
G4Tubs* stube = new G4Tubs("tube", 0. * mm, 19. / 2. * mm, dl, 0., 360. * deg);
mate = G4Material::GetMaterial("Al");
G4LogicalVolume* ltube = new G4LogicalVolume(stube, mate, "tube");
va = new G4VisAttributes(G4Color(0.,0.8,0.8));
ltube-> SetVisAttributes(va);
va = new G4VisAttributes(G4Color(0., 0.8, 0.8));
ltube->SetVisAttributes(va);
G4RotationMatrix* rmtube = new G4RotationMatrix;
rmtube-> rotateX(-90.*deg);
new G4PVPlacement(rmtube, G4ThreeVector(),
ltube, "tube", lvoxel, false, 0);
rmtube->rotateX(-90. * deg);
new G4PVPlacement(rmtube, G4ThreeVector(), ltube, "tube", lvoxel, false, 0);
// cal
const G4double dxycal = 25.*mm;
const G4double dzcal = 3.*cm;
const G4double dxycal = 25. * mm;
const G4double dzcal = 3. * cm;
G4Box* scal = new G4Box("cal", dxycal, dxycal, dzcal);
mate = G4Material::GetMaterial("CsI");
G4LogicalVolume* lcal = new G4LogicalVolume(scal, mate, "cal");
va = new G4VisAttributes(G4Color(0.5,0.5,0.));
lcal-> SetVisAttributes(va);
va = new G4VisAttributes(G4Color(0.5, 0.5, 0.));
lcal->SetVisAttributes(va);
index = 0;
for ( ix = -2; ix <= 2; ix++ ) {
G4double x0 = (5.*ix)*cm;
new G4PVPlacement(0, G4ThreeVector(x0, 0., 2.*cm),
lcal, "cal", areaLV, false, index);
for (ix = -2; ix <= 2; ix++) {
G4double x0 = (5. * ix) * cm;
new G4PVPlacement(0, G4ThreeVector(x0, 0., 2. * cm), lcal, "cal", areaLV, false, index);
index++;
}
@@ -129,6 +122,4 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField()
{
}
void DetectorConstruction::ConstructSDandField() {}
@@ -27,20 +27,17 @@
/// @file Materials.cc
/// @brief Define materials
#include "Materials.hh"
#include "G4Material.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Materials.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Materials::Materials()
{
}
Materials::Materials() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Materials::~Materials()
{
}
Materials::~Materials() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Materials::Construct()
@@ -50,15 +47,15 @@ void Materials::Construct()
// ------------------------------------------------------------------------
// Elements
// ------------------------------------------------------------------------
G4Element* elH = new G4Element("Hydrogen","H", Z=1., A=1.00794*g/mole);
G4Element* elC = new G4Element("Carbon", "C", Z=6., A= 12.011 *g/mole);
G4Element* elN = new G4Element("Nitrogen","N", Z=7., A= 14.00674*g/mole);
G4Element* elO = new G4Element("Oxygen", "O", Z=8., A= 15.9994*g/mole);
G4Element* elNa = new G4Element("Sodium", "Na", Z=11., A= 22.989768*g/mole);
G4Element* elSi = new G4Element("Silicon", "Si", Z=14., A= 28.0855*g/mole);
G4Element* elAr = new G4Element("Argon", "Ar", Z=18., A= 39.948*g/mole);
G4Element* elI = new G4Element("Iodine", "I", Z=53., A= 126.90447*g/mole);
G4Element* elCs = new G4Element("Cesium", "Cs", Z=55., A= 132.90543*g/mole);
G4Element* elH = new G4Element("Hydrogen", "H", Z = 1., A = 1.00794 * g / mole);
G4Element* elC = new G4Element("Carbon", "C", Z = 6., A = 12.011 * g / mole);
G4Element* elN = new G4Element("Nitrogen", "N", Z = 7., A = 14.00674 * g / mole);
G4Element* elO = new G4Element("Oxygen", "O", Z = 8., A = 15.9994 * g / mole);
G4Element* elNa = new G4Element("Sodium", "Na", Z = 11., A = 22.989768 * g / mole);
G4Element* elSi = new G4Element("Silicon", "Si", Z = 14., A = 28.0855 * g / mole);
G4Element* elAr = new G4Element("Argon", "Ar", Z = 18., A = 39.948 * g / mole);
G4Element* elI = new G4Element("Iodine", "I", Z = 53., A = 126.90447 * g / mole);
G4Element* elCs = new G4Element("Cesium", "Cs", Z = 55., A = 132.90543 * g / mole);
// ------------------------------------------------------------------------
// Materials
@@ -67,85 +64,80 @@ void Materials::Construct()
G4int natoms, nel;
// temperature of experimental hall is controlled at 20 degree.
const G4double expTemp = STP_Temperature+20.*kelvin;
const G4double expTemp = STP_Temperature + 20. * kelvin;
// vacuum
density = universe_mean_density;
G4Material* Vacuum = new G4Material("Vacuum", density, nel=2);
Vacuum-> AddElement(elN, .7);
Vacuum-> AddElement(elO, .3);
G4Material* Vacuum = new G4Material("Vacuum", density, nel = 2);
Vacuum->AddElement(elN, .7);
Vacuum->AddElement(elO, .3);
// air
density = 1.2929e-03 *g/cm3; // at 20 degree
G4Material* Air = new G4Material("Air", density, nel=3,
kStateGas, expTemp);
G4double ttt = 75.47+23.20+1.28;
Air-> AddElement(elN, massfraction= 75.47/ttt);
Air-> AddElement(elO, massfraction= 23.20/ttt);
Air-> AddElement(elAr, massfraction= 1.28/ttt);
density = 1.2929e-03 * g / cm3; // at 20 degree
G4Material* Air = new G4Material("Air", density, nel = 3, kStateGas, expTemp);
G4double ttt = 75.47 + 23.20 + 1.28;
Air->AddElement(elN, massfraction = 75.47 / ttt);
Air->AddElement(elO, massfraction = 23.20 / ttt);
Air->AddElement(elAr, massfraction = 1.28 / ttt);
// Ar gas
A = 39.948 *g/mole;
const G4double denAr = 1.782e-03 *g/cm3 * STP_Temperature/expTemp;
G4Material* Ar= new G4Material("ArgonGas", Z=18., A, denAr,
kStateGas, expTemp);
A = 39.948 * g / mole;
const G4double denAr = 1.782e-03 * g / cm3 * STP_Temperature / expTemp;
G4Material* Ar = new G4Material("ArgonGas", Z = 18., A, denAr, kStateGas, expTemp);
// ethane (C2H6)
const G4double denEthane = 1.356e-3 *g/cm3 * STP_Temperature/expTemp;
G4Material* Ethane= new G4Material("Ethane", denEthane, nel=2,
kStateGas, expTemp);
Ethane-> AddElement(elC, natoms=2);
Ethane-> AddElement(elH, natoms=6);
const G4double denEthane = 1.356e-3 * g / cm3 * STP_Temperature / expTemp;
G4Material* Ethane = new G4Material("Ethane", denEthane, nel = 2, kStateGas, expTemp);
Ethane->AddElement(elC, natoms = 2);
Ethane->AddElement(elH, natoms = 6);
// Ar(50%) + ethane(50%) mixture
density = (denAr+denEthane)/2.;
G4Material* ArEthane = new G4Material("ArEthane", density, nel=2,
kStateGas, expTemp);
ArEthane-> AddMaterial(Ar, massfraction= denAr/density/2.);
ArEthane-> AddMaterial(Ethane, massfraction= denEthane/density/2.);
density = (denAr + denEthane) / 2.;
G4Material* ArEthane = new G4Material("ArEthane", density, nel = 2, kStateGas, expTemp);
ArEthane->AddMaterial(Ar, massfraction = denAr / density / 2.);
ArEthane->AddMaterial(Ethane, massfraction = denEthane / density / 2.);
// silicon
A = 28.0855 *g/mole;
density = 2.33 *g/cm3;
new G4Material("SiliconWafer", Z=14., A, density);
A = 28.0855 * g / mole;
density = 2.33 * g / cm3;
new G4Material("SiliconWafer", Z = 14., A, density);
// alminium
A = 26.98 *g/mole;
density = 2.70 *g/cm3;
new G4Material("Al", Z=13., A, density);
A = 26.98 * g / mole;
density = 2.70 * g / cm3;
new G4Material("Al", Z = 13., A, density);
// iron
A = 55.847 *g/mole;
density = 7.87 *g/cm3;
new G4Material("Iron", Z=26., A, density);
A = 55.847 * g / mole;
density = 7.87 * g / cm3;
new G4Material("Iron", Z = 26., A, density);
// lead
A = 207.2 *g/mole;
density = 11.35 *g/cm3;
new G4Material("Lead", Z=82., A, density);
A = 207.2 * g / mole;
density = 11.35 * g / cm3;
new G4Material("Lead", Z = 82., A, density);
// scintillator (Polystyene(C6H5CH=CH2))
density = 1.032 *g/cm3;
G4Material* Scinti = new G4Material("Scinti", density, nel=2);
Scinti-> AddElement(elC, natoms=8);
Scinti-> AddElement(elH, natoms=8);
density = 1.032 * g / cm3;
G4Material* Scinti = new G4Material("Scinti", density, nel = 2);
Scinti->AddElement(elC, natoms = 8);
Scinti->AddElement(elH, natoms = 8);
// quartz (SiO2, crystalline)
density = 2.64 *g/cm3;
G4Material* Quartz = new G4Material("Quartz", density, nel= 2);
Quartz-> AddElement(elSi, natoms=1);
Quartz-> AddElement(elO, natoms=2);
density = 2.64 * g / cm3;
G4Material* Quartz = new G4Material("Quartz", density, nel = 2);
Quartz->AddElement(elSi, natoms = 1);
Quartz->AddElement(elO, natoms = 2);
// NaI crystal
density = 3.67 *g/cm3;
G4Material* NaI = new G4Material("NaI", density, nel= 2);
NaI-> AddElement(elNa, natoms=1);
NaI-> AddElement(elI, natoms=1);
density = 3.67 * g / cm3;
G4Material* NaI = new G4Material("NaI", density, nel = 2);
NaI->AddElement(elNa, natoms = 1);
NaI->AddElement(elI, natoms = 1);
// CsI crystal
density = 4.51 *g/cm3;
G4Material* CsI = new G4Material("CsI", density, nel= 2);
CsI-> AddElement(elCs, natoms=1);
CsI-> AddElement(elI, natoms=1);
density = 4.51 * g / cm3;
G4Material* CsI = new G4Material("CsI", density, nel = 2);
CsI->AddElement(elCs, natoms = 1);
CsI->AddElement(elI, natoms = 1);
}
@@ -27,11 +27,12 @@
/// @file PrimaryGeneratorAction.cc
/// @brief Define primary generator action
#include "PrimaryGeneratorAction.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4SystemOfUnits.hh"
#include "PrimaryGeneratorAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction()
@@ -39,12 +40,12 @@ PrimaryGeneratorAction::PrimaryGeneratorAction()
fparticleGun = new G4ParticleGun;
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4ParticleDefinition* particle = particleTable-> FindParticle("e-");
G4ParticleDefinition* particle = particleTable->FindParticle("e-");
fparticleGun-> SetParticleDefinition(particle);
fparticleGun-> SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.));
fparticleGun->SetParticlePosition(G4ThreeVector(0.,0.,-14.9*cm));
fparticleGun-> SetParticleEnergy(200.*MeV);
fparticleGun->SetParticleDefinition(particle);
fparticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
fparticleGun->SetParticlePosition(G4ThreeVector(0., 0., -14.9 * cm));
fparticleGun->SetParticleEnergy(200. * MeV);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -56,5 +57,5 @@ PrimaryGeneratorAction::~PrimaryGeneratorAction()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
fparticleGun-> GeneratePrimaryVertex(anEvent);
fparticleGun->GeneratePrimaryVertex(anEvent);
}
@@ -30,19 +30,18 @@
#include "G4MPIsession.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
# include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
# include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "FTFP_BERT.hh"
#include "G4ScoringManager.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
int main(int argc, char** argv)
{
// --------------------------------------------------------------------
@@ -53,33 +52,33 @@ int main(int argc, char** argv)
// MPI session (G4MPIsession) instead of G4UIterminal
// Terminal availability depends on your MPI implementation.
G4MPIsession* session = g4MPI-> GetMPIsession();
G4MPIsession* session = g4MPI->GetMPIsession();
// LAM/MPI users can use G4tcsh.
G4String prompt = "";
prompt += "G4MPI";
prompt += "(%s)[%/]:";
session-> SetPrompt(prompt);
session->SetPrompt(prompt);
// --------------------------------------------------------------------
// user application setting
// --------------------------------------------------------------------
#ifdef G4MULTITHREADED_DISABLE //ROOT ISSUES WITH MT, SEE exMPI03 FOR A MT
#ifdef G4MULTITHREADED_DISABLE // ROOT ISSUES WITH MT, SEE exMPI03 FOR A MT
G4MTRunManager* runManager = new G4MTRunManager();
runManager-> SetNumberOfThreads(4);
runManager->SetNumberOfThreads(4);
#else
G4RunManager* runManager = new G4RunManager();
#endif
// setup your application
runManager-> SetUserInitialization(new DetectorConstruction);
runManager-> SetUserInitialization(new FTFP_BERT);
runManager-> SetUserInitialization(new ActionInitialization);
runManager->SetUserInitialization(new DetectorConstruction);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization);
runManager-> Initialize();
runManager->Initialize();
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
visManager->Initialize();
G4cout << G4endl;
// --------------------------------------------------------------------
@@ -87,7 +86,7 @@ int main(int argc, char** argv)
// MPIsession treats both interactive and batch modes.
// Just start your session as below.
// --------------------------------------------------------------------
session-> SessionStart();
session->SessionStart();
// --------------------------------------------------------------------
// termination
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
/// @file ActionInitialization.hh
/// @file ActionInitialization.hh
/// @brief Define action initialization
#ifndef ACTION_INITIALIZATION_H
@@ -32,13 +32,14 @@
#include "G4VUserActionInitialization.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
~ActionInitialization();
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
virtual void BuildForMaster() const;
virtual void Build() const;
};
#endif
@@ -39,32 +39,33 @@
class TH1D;
class TH2D;
class Analysis {
public:
~Analysis();
class Analysis
{
public:
~Analysis();
static Analysis* GetAnalysis();
static Analysis* GetAnalysis();
void Update();
void Clear();
void Save(const G4String& fname);
void Update();
void Clear();
void Save(const G4String& fname);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void ClearIncidentFlag();
void ClearIncidentFlag();
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
TH2D* fincident_map;
TH1D* fincident_x_hist;
TH2D* fincident_map;
TH1D* fincident_x_hist;
TH2D* fdose_map;
TH1D* fdose_hist;
TH2D* fdose_map;
TH1D* fdose_hist;
static G4ThreadLocal G4int fincidentFlag;
static G4ThreadLocal G4int fincidentFlag;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,17 +34,17 @@
class G4LogicalVolume;
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
~DetectorConstruction();
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
};
#endif
@@ -32,13 +32,14 @@
#include "G4UserEventAction.hh"
class EventAction : public G4UserEventAction {
public:
EventAction();
~EventAction();
class EventAction : public G4UserEventAction
{
public:
EventAction();
~EventAction();
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
};
#endif
@@ -30,58 +30,62 @@
#ifndef MEDICAL_BEAM_H
#define MEDICAL_BEAM_H
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4ParticleDefinition;
class MedicalBeam : public G4VUserPrimaryGeneratorAction {
public:
enum FieldShape{ kSQUARE=0, kCIRCLE };
class MedicalBeam : public G4VUserPrimaryGeneratorAction
{
public:
enum FieldShape
{
kSQUARE = 0,
kCIRCLE
};
MedicalBeam();
~MedicalBeam();
MedicalBeam();
~MedicalBeam();
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -112,7 +116,7 @@ inline void MedicalBeam::SetSourcePosition(const G4ThreeVector& pos)
inline G4ThreeVector MedicalBeam::GetSourcePosition() const
{
return fsourcePosition;
return fsourcePosition;
}
inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
@@ -122,7 +126,7 @@ inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
inline MedicalBeam::FieldShape MedicalBeam::GetFieldShape() const
{
return ffieldShape;
return ffieldShape;
}
inline void MedicalBeam::SetSSD(G4double ssd)
@@ -32,13 +32,14 @@
#include "G4UserRunAction.hh"
class RunAction : public G4UserRunAction {
public:
RunAction();
~RunAction();
class RunAction : public G4UserRunAction
{
public:
RunAction();
~RunAction();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
};
#endif
@@ -32,54 +32,39 @@
#include "G4VPVParameterisation.hh"
class VoxelParam : public G4VPVParameterisation {
public:
VoxelParam();
~VoxelParam();
class VoxelParam : public G4VPVParameterisation
{
public:
VoxelParam();
~VoxelParam();
virtual void ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const;
virtual void ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id,
const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id, const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions
(G4Trd&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trd&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Trap&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trap&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Cons&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Cons&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Sphere&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Sphere&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Orb&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Orb&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Ellipsoid&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Ellipsoid&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Torus&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Torus&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Para&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Para&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Hype&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Hype&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Tubs&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Tubs&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polycone&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polyhedra&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polycone&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polyhedra&, const G4int, const G4VPhysicalVolume*) const {}
};
#endif
@@ -32,15 +32,16 @@
#include "G4VSensitiveDetector.hh"
class VoxelSD : public G4VSensitiveDetector {
public:
VoxelSD(const G4String& name);
~VoxelSD();
class VoxelSD : public G4VSensitiveDetector
{
public:
VoxelSD(const G4String& name);
~VoxelSD();
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
};
#endif
@@ -28,20 +28,16 @@
/// @brief Define action initialization
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "MedicalBeam.hh"
#include "RunAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization()
: G4VUserActionInitialization()
{
}
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
}
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
@@ -27,13 +27,15 @@
/// @file Analysis.cc
/// @brief Define histograms
#include "Analysis.hh"
#include "TFile.h"
#include "TH1.h"
#include "TH2.h"
#include "TROOT.h"
#include "G4SystemOfUnits.hh"
#include "Analysis.hh"
#include "G4AutoLock.hh"
#include "G4SystemOfUnits.hh"
G4ThreadLocal G4int Analysis::fincidentFlag = false;
G4ThreadLocal Analysis* the_analysis = 0;
@@ -43,8 +45,8 @@ G4Mutex rootm = G4MUTEX_INITIALIZER;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis* Analysis::GetAnalysis()
{
if ( ! the_analysis ) the_analysis = new Analysis;
return the_analysis;
if (!the_analysis) the_analysis = new Analysis;
return the_analysis;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -52,29 +54,25 @@ Analysis::Analysis()
{
G4AutoLock l(&rootm);
// define histograms
fincident_map = new TH2D("incident map", "Incident Distributuon",
50, -5., 5.,
50, -5., 5.);
fincident_map-> GetXaxis()-> SetTitle("X (cm)");
fincident_map-> GetYaxis()-> SetTitle("Y (cm)");
fincident_map-> SetStats(0);
fincident_map = new TH2D("incident map", "Incident Distributuon", 50, -5., 5., 50, -5., 5.);
fincident_map->GetXaxis()->SetTitle("X (cm)");
fincident_map->GetYaxis()->SetTitle("Y (cm)");
fincident_map->SetStats(0);
fincident_x_hist = new TH1D("incident x", "Incident X", 100, -5., 5.);
fincident_x_hist-> GetXaxis()-> SetTitle("X (cm)");
fincident_x_hist-> SetFillColor(kRed);
fincident_x_hist->GetXaxis()->SetTitle("X (cm)");
fincident_x_hist->SetFillColor(kRed);
fdose_map = new TH2D("dose map", "Dose Distribution",
500, 0., 50.,
200, -10., 10.);
fdose_map-> GetXaxis()-> SetTitle("Z (cm)");
fdose_map-> GetYaxis()-> SetTitle("X (cm)");
fdose_map-> SetStats(0);
fdose_map = new TH2D("dose map", "Dose Distribution", 500, 0., 50., 200, -10., 10.);
fdose_map->GetXaxis()->SetTitle("Z (cm)");
fdose_map->GetYaxis()->SetTitle("X (cm)");
fdose_map->SetStats(0);
fdose_hist = new TH1D("dose", "Dose Distribution", 500, 0., 50.);
fdose_hist-> GetXaxis()-> SetTitle("Z (cm)");
fdose_hist-> GetYaxis()-> SetTitle("Dose (GeV)");
fdose_hist-> SetFillColor(kBlue);
fdose_hist-> SetStats(0);
fdose_hist->GetXaxis()->SetTitle("Z (cm)");
fdose_hist->GetYaxis()->SetTitle("Dose (GeV)");
fdose_hist->SetFillColor(kBlue);
fdose_hist->SetStats(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -95,10 +93,10 @@ void Analysis::Update()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Analysis::Clear()
{
fincident_map-> Reset();
fincident_x_hist-> Reset();
fdose_map-> Reset();
fdose_hist-> Reset();
fincident_map->Reset();
fincident_x_hist->Reset();
fdose_map->Reset();
fdose_hist->Reset();
return;
}
@@ -109,12 +107,12 @@ void Analysis::Save(const G4String& fname)
G4AutoLock l(&rootm);
TFile* file = new TFile(fname.c_str(), "RECREATE", "Geant4 ROOT analysis");
fincident_map-> Write();
fincident_x_hist-> Write();
fdose_map-> Write();
fdose_hist-> Write();
fincident_map->Write();
fincident_x_hist->Write();
fdose_map->Write();
fdose_hist->Write();
file-> Close();
file->Close();
delete file;
@@ -124,9 +122,9 @@ void Analysis::Save(const G4String& fname)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Analysis::FillIncident(const G4ThreeVector& p)
{
if ( ! fincidentFlag ) {
fincident_map-> Fill(p.x()/cm, p.y()/cm);
fincident_x_hist-> Fill(p.x()/cm);
if (!fincidentFlag) {
fincident_map->Fill(p.x() / cm, p.y() / cm);
fincident_x_hist->Fill(p.x() / cm);
fincidentFlag = true;
}
@@ -135,14 +133,14 @@ void Analysis::FillIncident(const G4ThreeVector& p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
{
const G4double Z0 = 25.*cm;
const G4double dxy = 10.*mm;
const G4double Z0 = 25. * cm;
const G4double dxy = 10. * mm;
if ( std::abs(p.y()) < dxy ) {
fdose_map-> Fill((p.z()+Z0)/cm, p.x()/cm, dedx/GeV);
if (std::abs(p.y()) < dxy) {
fdose_map->Fill((p.z() + Z0) / cm, p.x() / cm, dedx / GeV);
if ( std::abs(p.x()) < dxy ) {
fdose_hist-> Fill((p.z()+Z0)/cm, dedx/GeV);
if (std::abs(p.x()) < dxy) {
fdose_hist->Fill((p.z() + Z0) / cm, dedx / GeV);
}
}
}
@@ -27,6 +27,11 @@
/// @file DetectorConstruction.hh
/// @brief Define geometry
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4NistManager.hh"
@@ -34,24 +39,16 @@
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisAttributes.hh"
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
typedef G4LogicalVolume G4LV;
typedef G4PVPlacement G4PVP;
typedef G4VisAttributes G4VA;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: flv_voxel(NULL)
{
}
DetectorConstruction::DetectorConstruction() : flv_voxel(NULL) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
}
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
@@ -60,63 +57,57 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
G4VisAttributes* va;
// world volume
const G4double DXYZ_WORLD = 200.*cm;
G4Box* sld_world = new G4Box("world",
DXYZ_WORLD/2., DXYZ_WORLD/2., DXYZ_WORLD/2.);
const G4double DXYZ_WORLD = 200. * cm;
G4Box* sld_world = new G4Box("world", DXYZ_WORLD / 2., DXYZ_WORLD / 2., DXYZ_WORLD / 2.);
G4Material* vacuum = nistManager-> FindOrBuildMaterial("G4_Galactic");
G4Material* vacuum = nistManager->FindOrBuildMaterial("G4_Galactic");
G4LV* lv_world = new G4LogicalVolume(sld_world, vacuum, "world");
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA",
lv_world, 0, false, 0);
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA", lv_world, 0, false, 0);
// vis. attributes
va = new G4VA(G4Color(1.,1.,1.));
va-> SetVisibility(false);
lv_world-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 1., 1.));
va->SetVisibility(false);
lv_world->SetVisAttributes(va);
// water phantom
const G4double DXY_PHANTOM = 20.*cm;
const G4double DZ_PHANTOM = 50.*cm;
const G4double DXY_PHANTOM = 20. * cm;
const G4double DZ_PHANTOM = 50. * cm;
G4Box* sld_phantom = new G4Box("phantom",
DXY_PHANTOM/2., DXY_PHANTOM/2., DZ_PHANTOM/2.);
G4Box* sld_phantom = new G4Box("phantom", DXY_PHANTOM / 2., DXY_PHANTOM / 2., DZ_PHANTOM / 2.);
G4Material* water = nistManager-> FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom,
water, "phantom");
G4Material* water = nistManager->FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom, water, "phantom");
va = new G4VA(G4Color(0.,1.,1.));
lv_phantom-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
lv_phantom->SetVisAttributes(va);
new G4PVP(0, G4ThreeVector(), lv_phantom, "phantom", lv_world, false, 0);
// voxel planes
const G4double DXY_VXP = 20.*cm;
const G4double DZ_VXP = 1.*mm;
const G4double DXY_VXP = 20. * cm;
const G4double DZ_VXP = 1. * mm;
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP/2., DXY_VXP/2., DZ_VXP/2.);
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP / 2., DXY_VXP / 2., DZ_VXP / 2.);
G4LV* lv_vxp = new G4LV(sld_vxp, water, "vxplane");
va = new G4VA(G4Color(1.,0.,0.));
va-> SetVisibility(false);
lv_vxp-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 0., 0.));
va->SetVisibility(false);
lv_vxp->SetVisAttributes(va);
for (G4int iz =0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM/2. + (iz+0.5)*DZ_VXP;
new G4PVP(0, G4ThreeVector(0.,0.,z0),
lv_vxp, "vxplane", lv_phantom, false, 1000+iz);
for (G4int iz = 0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM / 2. + (iz + 0.5) * DZ_VXP;
new G4PVP(0, G4ThreeVector(0., 0., z0), lv_vxp, "vxplane", lv_phantom, false, 1000 + iz);
}
// voxel parameterized
G4Box* sld_voxel = new G4Box("voxel",1.,1.,1.); // dummy
G4Box* sld_voxel = new G4Box("voxel", 1., 1., 1.); // dummy
flv_voxel = new G4LV(sld_voxel, water, "voxel");
va = new G4VA(G4Color(0.,1.,1.));
va-> SetVisibility(false);
flv_voxel-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
va->SetVisibility(false);
flv_voxel->SetVisAttributes(va);
const G4int nvoxels = 100*100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels,
new VoxelParam());
const G4int nvoxels = 100 * 100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels, new VoxelParam());
return world;
}
@@ -124,5 +115,5 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField()
{
flv_voxel-> SetSensitiveDetector(new VoxelSD("voxel"));
flv_voxel->SetSensitiveDetector(new VoxelSD("voxel"));
}
@@ -27,28 +27,24 @@
/// @file EventAction.cc
/// @brief Describe event actions
#include "G4Event.hh"
#include "Analysis.hh"
#include "EventAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction()
{
}
#include "Analysis.hh"
#include "G4Event.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{
}
EventAction::EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> ClearIncidentFlag();
myana->ClearIncidentFlag();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event*)
{
}
void EventAction::EndOfEventAction(const G4Event*) {}
@@ -27,47 +27,52 @@
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
#include <cmath>
#include "MedicalBeam.hh"
#include "G4Event.hh"
#include "G4ParticleTable.hh"
#include "G4PrimaryVertex.hh"
#include "Randomize.hh"
#include "MedicalBeam.hh"
#include <cmath>
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::MedicalBeam()
: fparticle(0), fkineticE(1.*MeV), fsourcePosition(G4ThreeVector()),
fSSD(1.*m), ffieldShape(MedicalBeam::kSQUARE), ffieldR(10.*cm)
: fparticle(0),
fkineticE(1. * MeV),
fsourcePosition(G4ThreeVector()),
fSSD(1. * m),
ffieldShape(MedicalBeam::kSQUARE),
ffieldR(10. * cm)
{
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
fparticle = particleTable-> FindParticle("proton");
fparticle = particleTable->FindParticle("proton");
fkineticE = 200.*MeV;
fsourcePosition = G4ThreeVector(0.,0.,-125.*cm);
fSSD = 100.*cm;
ffieldXY[0] = ffieldXY[1] = 5.*cm;
fkineticE = 200. * MeV;
fsourcePosition = G4ThreeVector(0., 0., -125. * cm);
fSSD = 100. * cm;
ffieldXY[0] = ffieldXY[1] = 5. * cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::~MedicalBeam()
{
}
MedicalBeam::~MedicalBeam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ThreeVector MedicalBeam::GenerateBeamDirection() const
{
// uniform distribution in a limitted solid angle
G4double dr;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
dr = std::sqrt(sqr(ffieldXY[0]/2.) + sqr(ffieldXY[1]/2.));
} else {
if (ffieldShape == MedicalBeam::kSQUARE) {
dr = std::sqrt(sqr(ffieldXY[0] / 2.) + sqr(ffieldXY[1] / 2.));
}
else {
dr = ffieldR;
}
G4double sin0 = dr/fSSD;
G4double cos0 = std::sqrt(1.-sqr(sin0));
G4double sin0 = dr / fSSD;
G4double cos0 = std::sqrt(1. - sqr(sin0));
G4double dcos = 0.;
G4double dsin, dphi, z;
@@ -76,44 +81,44 @@ G4ThreeVector MedicalBeam::GenerateBeamDirection() const
G4double y = DBL_MAX;
G4double xmax, ymax;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
xmax = ffieldXY[0]/2./fSSD;
ymax = ffieldXY[1]/2./fSSD;
} else {
xmax = ymax = DBL_MAX-1.;
if (ffieldShape == MedicalBeam::kSQUARE) {
xmax = ffieldXY[0] / 2. / fSSD;
ymax = ffieldXY[1] / 2. / fSSD;
}
else {
xmax = ymax = DBL_MAX - 1.;
}
while(! (std::abs(x) < xmax && std::abs(y) < ymax) ) {
while (!(std::abs(x) < xmax && std::abs(y) < ymax)) {
dcos = G4RandFlat::shoot(cos0, 1.);
dsin = std::sqrt(1.-sqr(dcos));
dsin = std::sqrt(1. - sqr(dcos));
dphi = G4RandFlat::shoot(0., twopi);
x = std::cos(dphi)*dsin*dcos;
y = std::sin(dphi)*dsin*dcos;
x = std::cos(dphi) * dsin * dcos;
y = std::sin(dphi) * dsin * dcos;
}
z = dcos;
return G4ThreeVector(x,y,z);
return G4ThreeVector(x, y, z);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void MedicalBeam::GeneratePrimaries(G4Event* anEvent)
{
if ( fparticle == NULL ) return;
if (fparticle == NULL) return;
// create a new vertex
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0.*ns);
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0. * ns);
// momentum
G4double mass = fparticle-> GetPDGMass();
G4double p = std::sqrt(sqr(mass+fkineticE)-sqr(mass));
G4ThreeVector pmon = p*GenerateBeamDirection();
G4PrimaryParticle* primary =
new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
G4double mass = fparticle->GetPDGMass();
G4double p = std::sqrt(sqr(mass + fkineticE) - sqr(mass));
G4ThreeVector pmon = p * GenerateBeamDirection();
G4PrimaryParticle* primary = new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
// set primary to vertex
vertex-> SetPrimary(primary);
vertex->SetPrimary(primary);
// set vertex to event
anEvent-> AddPrimaryVertex(vertex);
anEvent->AddPrimaryVertex(vertex);
}
@@ -27,38 +27,37 @@
/// @file RunAction.cc
/// @brief Describe run actions
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction()
{
}
#include "Analysis.hh"
#include "G4MPImanager.hh"
#include "G4Threading.hh"
#include <stdio.h>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{
}
RunAction::RunAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> Clear();
myana->Clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run*)
{
G4int rank = G4MPImanager::GetManager()-> GetRank();
G4int rank = G4MPImanager::GetManager()->GetRank();
char str[64];
sprintf(str, "dose-rank%03d.root", rank);
G4String fname(str);
Analysis* myana = Analysis::GetAnalysis();
myana-> Save(fname);
myana->Save(fname);
}
@@ -27,45 +27,40 @@
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
#include "VoxelParam.hh"
#include "G4Box.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
#include "VoxelParam.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::VoxelParam()
{
}
VoxelParam::VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::~VoxelParam()
{
}
VoxelParam::~VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const
void VoxelParam::ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const
{
const G4int NX = 100;
G4int iy = id / NX;
G4int ix = id % NX;
const G4double dxyz = 1.*mm;
const G4double DXY = 10.*cm;
const G4double dxyz = 1. * mm;
const G4double DXY = 10. * cm;
G4double x0 = -DXY/2. + ix*dxyz;
G4double y0 = -DXY/2. + iy*dxyz;
G4double x0 = -DXY / 2. + ix * dxyz;
G4double y0 = -DXY / 2. + iy * dxyz;
vol-> SetTranslation(G4ThreeVector(x0,y0,0.));
vol-> SetRotation(0);
vol->SetTranslation(G4ThreeVector(x0, y0, 0.));
vol->SetRotation(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeDimensions(G4Box& box, const G4int,
const G4VPhysicalVolume*) const
void VoxelParam::ComputeDimensions(G4Box& box, const G4int, const G4VPhysicalVolume*) const
{
const G4double dxyz = 0.5*mm;
const G4double dxyz = 0.5 * mm;
box.SetXHalfLength(dxyz);
box.SetYHalfLength(dxyz);
@@ -27,58 +27,53 @@
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
//#include "G4MPImanager.hh"
// #include "G4MPImanager.hh"
#include "VoxelSD.hh"
#include "Analysis.hh"
#include "G4SDManager.hh"
#include "G4Step.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VTouchable.hh"
#include "Randomize.hh"
#include "Analysis.hh"
#include "VoxelSD.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::VoxelSD(const G4String& name)
: G4VSensitiveDetector(name)
VoxelSD::VoxelSD(const G4String& name) : G4VSensitiveDetector(name)
{
G4SDManager::GetSDMpointer()-> AddNewDetector(this);
G4SDManager::GetSDMpointer()->AddNewDetector(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::~VoxelSD()
{
}
VoxelSD::~VoxelSD() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool VoxelSD::ProcessHits(G4Step* astep, G4TouchableHistory*)
{
G4ThreeVector x0 = astep-> GetPreStepPoint()-> GetPosition();
G4ThreeVector x1 = astep-> GetPostStepPoint()-> GetPosition();
G4ThreeVector x0 = astep->GetPreStepPoint()->GetPosition();
G4ThreeVector x1 = astep->GetPostStepPoint()->GetPosition();
G4int tid = astep-> GetTrack()-> GetTrackID();
G4int iz = astep-> GetPreStepPoint()-> GetTouchable()-> GetReplicaNumber(1);
G4int tid = astep->GetTrack()->GetTrackID();
G4int iz = astep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(1);
Analysis* myana = Analysis::GetAnalysis();
// incident position
if ( tid == 1 && iz == 1000 ) { // scored @ first layer
myana-> FillIncident(x0);
if (tid == 1 && iz == 1000) { // scored @ first layer
myana->FillIncident(x0);
}
// energy deposit
G4ThreeVector p = G4UniformRand()*(x1-x0) + x0; // position sampling
G4double edep = astep-> GetTotalEnergyDeposit();
myana-> FillDose(p, edep);
G4ThreeVector p = G4UniformRand() * (x1 - x0) + x0; // position sampling
G4double edep = astep->GetTotalEnergyDeposit();
myana->FillDose(p, edep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::Initialize(G4HCofThisEvent*)
{
}
void VoxelSD::Initialize(G4HCofThisEvent*) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::EndOfEvent(G4HCofThisEvent*)
{
}
void VoxelSD::EndOfEvent(G4HCofThisEvent*) {}
@@ -30,19 +30,18 @@
#include "G4MPIsession.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
# include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
# include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "FTFP_BERT.hh"
#include "G4ScoringManager.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
int main(int argc, char** argv)
{
// --------------------------------------------------------------------
@@ -53,34 +52,34 @@ int main(int argc, char** argv)
// MPI session (G4MPIsession) instead of G4UIterminal
// Terminal availability depends on your MPI implementation.
G4MPIsession* session = g4MPI-> GetMPIsession();
G4MPIsession* session = g4MPI->GetMPIsession();
// LAM/MPI users can use G4tcsh.
G4String prompt = "";
prompt += "G4MPI";
prompt += "(%s)[%/]:";
session-> SetPrompt(prompt);
session->SetPrompt(prompt);
// --------------------------------------------------------------------
// user application setting
// --------------------------------------------------------------------
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager();
runManager-> SetNumberOfThreads(4);
runManager->SetNumberOfThreads(4);
#else
G4RunManager* runManager = new G4RunManager();
#endif
G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
scManager->SetVerboseLevel(1);
G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
scManager->SetVerboseLevel(1);
// setup your application
runManager-> SetUserInitialization(new DetectorConstruction);
runManager-> SetUserInitialization(new FTFP_BERT);
runManager-> SetUserInitialization(new ActionInitialization);
runManager->SetUserInitialization(new DetectorConstruction);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization);
runManager-> Initialize();
runManager->Initialize();
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
visManager->Initialize();
G4cout << G4endl;
// --------------------------------------------------------------------
@@ -88,7 +87,7 @@ G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
// MPIsession treats both interactive and batch modes.
// Just start your session as below.
// --------------------------------------------------------------------
session-> SessionStart();
session->SessionStart();
// --------------------------------------------------------------------
// termination
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
/// @file ActionInitialization.hh
/// @file ActionInitialization.hh
/// @brief Define action initialization
#ifndef ACTION_INITIALIZATION_H
@@ -32,13 +32,14 @@
#include "G4VUserActionInitialization.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
~ActionInitialization();
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
virtual void BuildForMaster() const;
virtual void Build() const;
};
#endif
@@ -31,6 +31,7 @@
#define ANALYSIS_MANAGER_H
#include "G4ThreeVector.hh"
#include <tools/histo/h1d>
#include <tools/histo/h2d>
@@ -38,39 +39,40 @@
TypeName(const TypeName&); \
void operator=(const TypeName&)
class Analysis {
public:
~Analysis();
class Analysis
{
public:
~Analysis();
static Analysis* GetAnalysis();
static Analysis* GetAnalysis();
void Book();
void EndOfRun();
void Book();
void EndOfRun();
void Update();
void Clear();
void Save(const G4String& fname);
void Close(G4bool reset = true);
void Update();
void Clear();
void Save(const G4String& fname);
void Close(G4bool reset = true);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void ClearIncidentFlag();
void ClearIncidentFlag();
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
//Histograms handlers
G4int fincident_x_hist;
G4int fincident_map;
G4int fdose_hist;
G4int fdose_map;
G4int fdose_prof;
G4int fdose_map_prof;
G4int fdose_map3d;
// Histograms handlers
G4int fincident_x_hist;
G4int fincident_map;
G4int fdose_hist;
G4int fdose_map;
G4int fdose_prof;
G4int fdose_map_prof;
G4int fdose_map3d;
static G4ThreadLocal G4int fincidentFlag;
static G4ThreadLocal G4int fincidentFlag;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,17 +34,17 @@
class G4LogicalVolume;
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
~DetectorConstruction();
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
};
#endif
@@ -32,13 +32,14 @@
#include "G4UserEventAction.hh"
class EventAction : public G4UserEventAction {
public:
EventAction();
~EventAction();
class EventAction : public G4UserEventAction
{
public:
EventAction();
~EventAction();
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
};
#endif
@@ -30,58 +30,62 @@
#ifndef MEDICAL_BEAM_H
#define MEDICAL_BEAM_H
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4ParticleDefinition;
class MedicalBeam : public G4VUserPrimaryGeneratorAction {
public:
enum FieldShape{ kSQUARE=0, kCIRCLE };
class MedicalBeam : public G4VUserPrimaryGeneratorAction
{
public:
enum FieldShape
{
kSQUARE = 0,
kCIRCLE
};
MedicalBeam();
~MedicalBeam();
MedicalBeam();
~MedicalBeam();
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -112,7 +116,7 @@ inline void MedicalBeam::SetSourcePosition(const G4ThreeVector& pos)
inline G4ThreeVector MedicalBeam::GetSourcePosition() const
{
return fsourcePosition;
return fsourcePosition;
}
inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
@@ -122,7 +126,7 @@ inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
inline MedicalBeam::FieldShape MedicalBeam::GetFieldShape() const
{
return ffieldShape;
return ffieldShape;
}
inline void MedicalBeam::SetSSD(G4double ssd)
@@ -28,17 +28,20 @@
#include <G4Run.hh>
//Dummy class to show how to use MPI merging of
//user defined G4Run. The dummycounter it's a unique number among threads.
//Merge actually sums the dummyCounter so for the global run that is Sum(i, 0<i<Nt)
class Run : public G4Run {
friend class RunMerger;
public:
Run();
virtual ~Run() {}
void Merge(const G4Run*);
G4int GetCounter() const { return fDummyCounter; }
private:
G4int fDummyCounter;
// Dummy class to show how to use MPI merging of
// user defined G4Run. The dummycounter it's a unique number among threads.
// Merge actually sums the dummyCounter so for the global run that is Sum(i, 0<i<Nt)
class Run : public G4Run
{
friend class RunMerger;
public:
Run();
virtual ~Run() {}
void Merge(const G4Run*);
G4int GetCounter() const { return fDummyCounter; }
private:
G4int fDummyCounter;
};
#endif //RUN_HH
#endif // RUN_HH
@@ -32,14 +32,15 @@
#include "G4UserRunAction.hh"
class RunAction : public G4UserRunAction {
public:
RunAction();
~RunAction();
class RunAction : public G4UserRunAction
{
public:
RunAction();
~RunAction();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
};
#endif
@@ -32,14 +32,15 @@
#include "G4UserRunAction.hh"
class RunActionMaster : public G4UserRunAction {
public:
RunActionMaster();
~RunActionMaster();
class RunActionMaster : public G4UserRunAction
{
public:
RunActionMaster();
~RunActionMaster();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
};
#endif
@@ -25,20 +25,23 @@
//
#ifndef MPIRUNMERGER_HH
#define MPIRUNMERGER_HH
#include <G4VUserMPIrunMerger.hh>
#include "Run.hh"
//Simple class showing how to reduce via MPI user defined run
class RunMerger : public G4VUserMPIrunMerger {
public:
RunMerger(const Run* arun,G4int destination=G4MPImanager::kRANK_MASTER,
G4int verb=0)
: G4VUserMPIrunMerger(arun,destination,verb ) , fMyRun(arun) {}
protected:
void Pack();
G4Run* UnPack();
private:
const Run* fMyRun;
#include <G4VUserMPIrunMerger.hh>
// Simple class showing how to reduce via MPI user defined run
class RunMerger : public G4VUserMPIrunMerger
{
public:
RunMerger(const Run* arun, G4int destination = G4MPImanager::kRANK_MASTER, G4int verb = 0)
: G4VUserMPIrunMerger(arun, destination, verb), fMyRun(arun)
{}
protected:
void Pack();
G4Run* UnPack();
private:
const Run* fMyRun;
};
#endif
@@ -32,54 +32,39 @@
#include "G4VPVParameterisation.hh"
class VoxelParam : public G4VPVParameterisation {
public:
VoxelParam();
~VoxelParam();
class VoxelParam : public G4VPVParameterisation
{
public:
VoxelParam();
~VoxelParam();
virtual void ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const;
virtual void ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id,
const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id, const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions
(G4Trd&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trd&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Trap&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trap&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Cons&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Cons&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Sphere&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Sphere&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Orb&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Orb&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Ellipsoid&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Ellipsoid&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Torus&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Torus&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Para&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Para&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Hype&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Hype&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Tubs&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Tubs&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polycone&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polyhedra&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polycone&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polyhedra&, const G4int, const G4VPhysicalVolume*) const {}
};
#endif
@@ -32,15 +32,16 @@
#include "G4VSensitiveDetector.hh"
class VoxelSD : public G4VSensitiveDetector {
public:
VoxelSD(const G4String& name);
~VoxelSD();
class VoxelSD : public G4VSensitiveDetector
{
public:
VoxelSD(const G4String& name);
~VoxelSD();
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
};
#endif
@@ -28,22 +28,19 @@
/// @brief Define action initialization
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "MedicalBeam.hh"
#include "RunAction.hh"
#include "RunActionMaster.hh"
#include "G4Threading.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization()
: G4VUserActionInitialization()
{
}
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
}
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
@@ -56,8 +53,8 @@ void ActionInitialization::Build() const
{
SetUserAction(new MedicalBeam);
SetUserAction(new EventAction);
if ( G4Threading::IsMultithreadedApplication() )
SetUserAction(new RunAction);
else
SetUserAction(new RunActionMaster);//Use master version for sequential
if (G4Threading::IsMultithreadedApplication())
SetUserAction(new RunAction);
else
SetUserAction(new RunActionMaster); // Use master version for sequential
}
@@ -27,80 +27,74 @@
/// @file Analysis.cc
/// @brief Define histograms
#include "G4AutoDelete.hh"
#include "G4SystemOfUnits.hh"
#include "G4AnalysisManager.hh"
#include "Analysis.hh"
//Select format of output here
#include "G4AnalysisManager.hh"
#include "G4AutoDelete.hh"
#include "G4SystemOfUnits.hh"
// Select format of output here
G4ThreadLocal G4int Analysis::fincidentFlag = false;
G4ThreadLocal Analysis* the_analysis = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis*
Analysis::GetAnalysis()
Analysis* Analysis::GetAnalysis()
{
if (!the_analysis)
{
the_analysis = new Analysis();
G4AutoDelete::Register(the_analysis);
}
if (!the_analysis) {
the_analysis = new Analysis();
G4AutoDelete::Register(the_analysis);
}
return the_analysis;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::Analysis() :
fincident_x_hist(0), fincident_map(0), fdose_hist(0), fdose_map(0),
fdose_prof(0), fdose_map_prof(0), fdose_map3d(0)
{
}
Analysis::Analysis()
: fincident_x_hist(0),
fincident_map(0),
fdose_hist(0),
fdose_map(0),
fdose_prof(0),
fdose_map_prof(0),
fdose_map3d(0)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Book()
void Analysis::Book()
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->SetDefaultFileType("root");
mgr->SetVerboseLevel(1);
fincident_x_hist = mgr->CreateH1("incident_x", "Incident X", 100, -5 * cm,
5 * cm, "cm");
fincident_map = mgr->CreateH2("incident_map", "Incident Map", 50, -5 * cm,
5 * cm, 50, -5 * cm, 5 * cm, "cm", "cm");
fdose_hist
= mgr->CreateH1("dose", "Dose distribution", 500, 0, 50 * cm, "cm");
fdose_map = mgr->CreateH2("dose_map", "Dose distribution", 500, 0, 50 * cm,
200, -10 * cm, 10 * cm, "cm", "cm");
fdose_map3d = mgr->CreateH3("dose_map_3d", "Dose distribution", 30, 0,
50 * cm, 20, -10 * cm, 10 * cm, 20, -10 * cm, 10 * cm, "cm", "cm", "cm");
fdose_prof = mgr->CreateP1("dose_prof", "Dose distribution", 300, 0, 30 * cm,
0, 100 * MeV, "cm", "MeV");
fdose_map_prof = mgr->CreateP2("dose_map_prof", "Dose distribution", 300, 0,
30 * cm, 80, -4 * cm, 4 * cm, 0, 100 * MeV, "cm", "cm", "MeV");
fincident_x_hist = mgr->CreateH1("incident_x", "Incident X", 100, -5 * cm, 5 * cm, "cm");
fincident_map = mgr->CreateH2("incident_map", "Incident Map", 50, -5 * cm, 5 * cm, 50, -5 * cm,
5 * cm, "cm", "cm");
fdose_hist = mgr->CreateH1("dose", "Dose distribution", 500, 0, 50 * cm, "cm");
fdose_map = mgr->CreateH2("dose_map", "Dose distribution", 500, 0, 50 * cm, 200, -10 * cm,
10 * cm, "cm", "cm");
fdose_map3d = mgr->CreateH3("dose_map_3d", "Dose distribution", 30, 0, 50 * cm, 20, -10 * cm,
10 * cm, 20, -10 * cm, 10 * cm, "cm", "cm", "cm");
fdose_prof =
mgr->CreateP1("dose_prof", "Dose distribution", 300, 0, 30 * cm, 0, 100 * MeV, "cm", "MeV");
fdose_map_prof = mgr->CreateP2("dose_map_prof", "Dose distribution", 300, 0, 30 * cm, 80, -4 * cm,
4 * cm, 0, 100 * MeV, "cm", "cm", "MeV");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::~Analysis()
{
}
Analysis::~Analysis() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Update()
void Analysis::Update()
{
return;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Clear()
void Analysis::Clear()
{
return;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Save(const G4String& fname)
void Analysis::Save(const G4String& fname)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->OpenFile(fname.c_str());
@@ -109,8 +103,7 @@ Analysis::Save(const G4String& fname)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Close(G4bool reset)
void Analysis::Close(G4bool reset)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->CloseFile(reset);
@@ -118,36 +111,30 @@ Analysis::Close(G4bool reset)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillIncident(const G4ThreeVector& p)
void Analysis::FillIncident(const G4ThreeVector& p)
{
if (!fincidentFlag)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->FillH2(fincident_map, p.x(), p.y());
mgr->FillH1(fincident_x_hist, p.x());
fincidentFlag = true;
}
if (!fincidentFlag) {
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->FillH2(fincident_map, p.x(), p.y());
mgr->FillH1(fincident_x_hist, p.x());
fincidentFlag = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
void Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
{
const G4double dxy = 10. * mm;
if (std::abs(p.y()) < dxy)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
const G4double Z0 = 25. * cm;
if (std::abs(p.y()) < dxy) {
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
const G4double Z0 = 25. * cm;
mgr->FillH2(fdose_map, p.z() + Z0, p.x(), dedx / GeV);
mgr->FillP2(fdose_map_prof, p.z() + Z0, p.x(), dedx);
mgr->FillH3(fdose_map3d, p.z() + Z0, p.x(), p.y(), dedx / GeV);
if (std::abs(p.x()) < dxy)
{
mgr->FillH1(fdose_hist, p.z() + Z0, dedx / GeV);
mgr->FillP1(fdose_prof, p.z() + Z0, dedx);
}
mgr->FillH2(fdose_map, p.z() + Z0, p.x(), dedx / GeV);
mgr->FillP2(fdose_map_prof, p.z() + Z0, p.x(), dedx);
mgr->FillH3(fdose_map3d, p.z() + Z0, p.x(), p.y(), dedx / GeV);
if (std::abs(p.x()) < dxy) {
mgr->FillH1(fdose_hist, p.z() + Z0, dedx / GeV);
mgr->FillP1(fdose_prof, p.z() + Z0, dedx);
}
}
}
@@ -27,6 +27,11 @@
/// @file DetectorConstruction.hh
/// @brief Define geometry
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4NistManager.hh"
@@ -34,24 +39,16 @@
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisAttributes.hh"
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
typedef G4LogicalVolume G4LV;
typedef G4PVPlacement G4PVP;
typedef G4VisAttributes G4VA;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: flv_voxel(NULL)
{
}
DetectorConstruction::DetectorConstruction() : flv_voxel(NULL) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
}
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
@@ -60,63 +57,57 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
G4VisAttributes* va;
// world volume
const G4double DXYZ_WORLD = 200.*cm;
G4Box* sld_world = new G4Box("world",
DXYZ_WORLD/2., DXYZ_WORLD/2., DXYZ_WORLD/2.);
const G4double DXYZ_WORLD = 200. * cm;
G4Box* sld_world = new G4Box("world", DXYZ_WORLD / 2., DXYZ_WORLD / 2., DXYZ_WORLD / 2.);
G4Material* vacuum = nistManager-> FindOrBuildMaterial("G4_Galactic");
G4Material* vacuum = nistManager->FindOrBuildMaterial("G4_Galactic");
G4LV* lv_world = new G4LogicalVolume(sld_world, vacuum, "world");
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA",
lv_world, 0, false, 0);
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA", lv_world, 0, false, 0);
// vis. attributes
va = new G4VA(G4Color(1.,1.,1.));
va-> SetVisibility(false);
lv_world-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 1., 1.));
va->SetVisibility(false);
lv_world->SetVisAttributes(va);
// water phantom
const G4double DXY_PHANTOM = 20.*cm;
const G4double DZ_PHANTOM = 50.*cm;
const G4double DXY_PHANTOM = 20. * cm;
const G4double DZ_PHANTOM = 50. * cm;
G4Box* sld_phantom = new G4Box("phantom",
DXY_PHANTOM/2., DXY_PHANTOM/2., DZ_PHANTOM/2.);
G4Box* sld_phantom = new G4Box("phantom", DXY_PHANTOM / 2., DXY_PHANTOM / 2., DZ_PHANTOM / 2.);
G4Material* water = nistManager-> FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom,
water, "phantom");
G4Material* water = nistManager->FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom, water, "phantom");
va = new G4VA(G4Color(0.,1.,1.));
lv_phantom-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
lv_phantom->SetVisAttributes(va);
new G4PVP(0, G4ThreeVector(), lv_phantom, "phantom", lv_world, false, 0);
// voxel planes
const G4double DXY_VXP = 20.*cm;
const G4double DZ_VXP = 1.*mm;
const G4double DXY_VXP = 20. * cm;
const G4double DZ_VXP = 1. * mm;
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP/2., DXY_VXP/2., DZ_VXP/2.);
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP / 2., DXY_VXP / 2., DZ_VXP / 2.);
G4LV* lv_vxp = new G4LV(sld_vxp, water, "vxplane");
va = new G4VA(G4Color(1.,0.,0.));
va-> SetVisibility(false);
lv_vxp-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 0., 0.));
va->SetVisibility(false);
lv_vxp->SetVisAttributes(va);
for (G4int iz =0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM/2. + (iz+0.5)*DZ_VXP;
new G4PVP(0, G4ThreeVector(0.,0.,z0),
lv_vxp, "vxplane", lv_phantom, false, 1000+iz);
for (G4int iz = 0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM / 2. + (iz + 0.5) * DZ_VXP;
new G4PVP(0, G4ThreeVector(0., 0., z0), lv_vxp, "vxplane", lv_phantom, false, 1000 + iz);
}
// voxel parameterized
G4Box* sld_voxel = new G4Box("voxel",1.,1.,1.); // dummy
G4Box* sld_voxel = new G4Box("voxel", 1., 1., 1.); // dummy
flv_voxel = new G4LV(sld_voxel, water, "voxel");
va = new G4VA(G4Color(0.,1.,1.));
va-> SetVisibility(false);
flv_voxel-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
va->SetVisibility(false);
flv_voxel->SetVisAttributes(va);
const G4int nvoxels = 100*100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels,
new VoxelParam());
const G4int nvoxels = 100 * 100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels, new VoxelParam());
return world;
}
@@ -124,5 +115,5 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField()
{
flv_voxel-> SetSensitiveDetector(new VoxelSD("voxel"));
flv_voxel->SetSensitiveDetector(new VoxelSD("voxel"));
}
@@ -27,28 +27,24 @@
/// @file EventAction.cc
/// @brief Describe event actions
#include "G4Event.hh"
#include "Analysis.hh"
#include "EventAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction()
{
}
#include "Analysis.hh"
#include "G4Event.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{
}
EventAction::EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> ClearIncidentFlag();
myana->ClearIncidentFlag();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event*)
{
}
void EventAction::EndOfEventAction(const G4Event*) {}
@@ -27,47 +27,52 @@
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
#include <cmath>
#include "MedicalBeam.hh"
#include "G4Event.hh"
#include "G4ParticleTable.hh"
#include "G4PrimaryVertex.hh"
#include "Randomize.hh"
#include "MedicalBeam.hh"
#include <cmath>
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::MedicalBeam()
: fparticle(0), fkineticE(1.*MeV), fsourcePosition(G4ThreeVector()),
fSSD(1.*m), ffieldShape(MedicalBeam::kSQUARE), ffieldR(10.*cm)
: fparticle(0),
fkineticE(1. * MeV),
fsourcePosition(G4ThreeVector()),
fSSD(1. * m),
ffieldShape(MedicalBeam::kSQUARE),
ffieldR(10. * cm)
{
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
fparticle = particleTable-> FindParticle("proton");
fparticle = particleTable->FindParticle("proton");
fkineticE = 200.*MeV;
fsourcePosition = G4ThreeVector(0.,0.,-125.*cm);
fSSD = 100.*cm;
ffieldXY[0] = ffieldXY[1] = 5.*cm;
fkineticE = 200. * MeV;
fsourcePosition = G4ThreeVector(0., 0., -125. * cm);
fSSD = 100. * cm;
ffieldXY[0] = ffieldXY[1] = 5. * cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::~MedicalBeam()
{
}
MedicalBeam::~MedicalBeam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ThreeVector MedicalBeam::GenerateBeamDirection() const
{
// uniform distribution in a limitted solid angle
G4double dr;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
dr = std::sqrt(sqr(ffieldXY[0]/2.) + sqr(ffieldXY[1]/2.));
} else {
if (ffieldShape == MedicalBeam::kSQUARE) {
dr = std::sqrt(sqr(ffieldXY[0] / 2.) + sqr(ffieldXY[1] / 2.));
}
else {
dr = ffieldR;
}
G4double sin0 = dr/fSSD;
G4double cos0 = std::sqrt(1.-sqr(sin0));
G4double sin0 = dr / fSSD;
G4double cos0 = std::sqrt(1. - sqr(sin0));
G4double dcos = 0.;
G4double dsin, dphi, z;
@@ -76,44 +81,44 @@ G4ThreeVector MedicalBeam::GenerateBeamDirection() const
G4double y = DBL_MAX;
G4double xmax, ymax;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
xmax = ffieldXY[0]/2./fSSD;
ymax = ffieldXY[1]/2./fSSD;
} else {
xmax = ymax = DBL_MAX-1.;
if (ffieldShape == MedicalBeam::kSQUARE) {
xmax = ffieldXY[0] / 2. / fSSD;
ymax = ffieldXY[1] / 2. / fSSD;
}
else {
xmax = ymax = DBL_MAX - 1.;
}
while(! (std::abs(x) < xmax && std::abs(y) < ymax) ) {
while (!(std::abs(x) < xmax && std::abs(y) < ymax)) {
dcos = G4RandFlat::shoot(cos0, 1.);
dsin = std::sqrt(1.-sqr(dcos));
dsin = std::sqrt(1. - sqr(dcos));
dphi = G4RandFlat::shoot(0., twopi);
x = std::cos(dphi)*dsin*dcos;
y = std::sin(dphi)*dsin*dcos;
x = std::cos(dphi) * dsin * dcos;
y = std::sin(dphi) * dsin * dcos;
}
z = dcos;
return G4ThreeVector(x,y,z);
return G4ThreeVector(x, y, z);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void MedicalBeam::GeneratePrimaries(G4Event* anEvent)
{
if ( fparticle == NULL ) return;
if (fparticle == NULL) return;
// create a new vertex
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0.*ns);
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0. * ns);
// momentum
G4double mass = fparticle-> GetPDGMass();
G4double p = std::sqrt(sqr(mass+fkineticE)-sqr(mass));
G4ThreeVector pmon = p*GenerateBeamDirection();
G4PrimaryParticle* primary =
new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
G4double mass = fparticle->GetPDGMass();
G4double p = std::sqrt(sqr(mass + fkineticE) - sqr(mass));
G4ThreeVector pmon = p * GenerateBeamDirection();
G4PrimaryParticle* primary = new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
// set primary to vertex
vertex-> SetPrimary(primary);
vertex->SetPrimary(primary);
// set vertex to event
anEvent-> AddPrimaryVertex(vertex);
anEvent->AddPrimaryVertex(vertex);
}
@@ -24,20 +24,24 @@
// ********************************************************************
//
#include "Run.hh"
#include <atomic>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
namespace {
std::atomic_int g_ctr(0);
namespace
{
std::atomic_int g_ctr(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() {
Run::Run()
{
fDummyCounter = g_ctr++;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge(const G4Run* other ) {
void Run::Merge(const G4Run* other)
{
G4Run::Merge(other);
fDummyCounter += static_cast<const Run*>(other)->fDummyCounter;
}
@@ -27,25 +27,23 @@
/// @file RunAction.cc
/// @brief Describe run actions
#include <G4VUserMPIrunMerger.hh>
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunAction.hh"
#include "Analysis.hh"
#include "Run.hh"
#include "G4MPImanager.hh"
#include "G4MPIscorerMerger.hh"
#include "G4Threading.hh"
#include <G4VUserMPIrunMerger.hh>
#include <stdio.h>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction()
{
}
RunAction::RunAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{
}
RunAction::~RunAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun()
@@ -56,18 +54,18 @@ G4Run* RunAction::GenerateRun()
void RunAction::BeginOfRunAction(const G4Run*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> Clear();
myana->Clear();
myana->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run*)
{
G4int rank = G4MPImanager::GetManager()-> GetRank();
//NOTE: if only histograms are active actually we do not create the per-thread
//ntuple file
G4int rank = G4MPImanager::GetManager()->GetRank();
// NOTE: if only histograms are active actually we do not create the per-thread
// ntuple file
std::ostringstream fname;
fname<<"dose-rank"<<rank<<"-thread"<<G4Threading::G4GetThreadId();
fname << "dose-rank" << rank << "-thread" << G4Threading::G4GetThreadId();
Analysis* myana = Analysis::GetAnalysis();
myana-> Save(fname.str());
myana->Save(fname.str());
}
@@ -27,21 +27,22 @@
/// @file RunActionMaster.cc
/// @brief Describe run actions
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunActionMaster.hh"
#include "G4AnalysisManager.hh"
#include "RunMerger.hh"
#include "G4MPIscorerMerger.hh"
#include "G4MPIhistoMerger.hh" // New code with use of g4analysis
#include "Analysis.hh"
#include "Run.hh"
#include "RunMerger.hh"
#include "G4AnalysisManager.hh"
#include "G4MPIhistoMerger.hh" // New code with use of g4analysis
#include "G4MPImanager.hh"
#include "G4MPIscorerMerger.hh"
#include "G4Threading.hh"
#include <stdio.h>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunActionMaster::RunActionMaster()
{
}
RunActionMaster::RunActionMaster() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunActionMaster::GenerateRun()
@@ -50,13 +51,10 @@ G4Run* RunActionMaster::GenerateRun()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunActionMaster::~RunActionMaster()
{
}
RunActionMaster::~RunActionMaster() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::BeginOfRunAction(const G4Run*)
void RunActionMaster::BeginOfRunAction(const G4Run*)
{
Analysis* myana = Analysis::GetAnalysis();
myana->Clear();
@@ -64,16 +62,15 @@ RunActionMaster::BeginOfRunAction(const G4Run*)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::EndOfRunAction(const G4Run* arun)
void RunActionMaster::EndOfRunAction(const G4Run* arun)
{
//This is executed by master thread only. Worker threads have already
//merged their results into this master threads.
// This is executed by master thread only. Worker threads have already
// merged their results into this master threads.
//We are going to merge the results via MPI for:
// 1. User-defined "Run" object
// 2. Command line scorers, if exists
// 3. G4Analysis objects
// We are going to merge the results via MPI for:
// 1. User-defined "Run" object
// 2. Command line scorers, if exists
// 3. G4Analysis objects
// For debugging purposes in the following we write out results twice:
// BEFORE and AFTER the merging, so that rank 0 actually
@@ -82,124 +79,122 @@ RunActionMaster::EndOfRunAction(const G4Run* arun)
// the file *merged* contains the reduction from all ranks.
// It should be very easy to adapt this code
const G4int rank = G4MPImanager::GetManager()-> GetRank();
const G4int rank = G4MPImanager::GetManager()->GetRank();
G4cout << "=====================================================" << G4endl;
G4cout << "Start EndOfRunAction for master thread in rank: " << rank<<G4endl;
G4cout << "Start EndOfRunAction for master thread in rank: " << rank << G4endl;
G4cout << "=====================================================" << G4endl;
//Merging of G4Run object:
//All ranks > 0 merge to rank #0
// Merging of G4Run object:
// All ranks > 0 merge to rank #0
RunMerger rm(static_cast<const Run*>(arun));
G4int ver = 0 ; //Use 4 for lots of info
if ( rank == 0 && ver == 0) ver = 1;
G4int ver = 0; // Use 4 for lots of info
if (rank == 0 && ver == 0) ver = 1;
if ( ver > 1 ) {
G4cout<<"Before merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()<<G4endl;
if (ver > 1) {
G4cout << "Before merge the Run object has test counter value: "
<< static_cast<const Run*>(arun)->GetCounter() << G4endl;
}
rm.SetVerbosity( ver );
rm.SetVerbosity(ver);
rm.Merge();
if ( ver > 1 ) {
G4cout<<"After merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()
<<" (with 1 thread== number of ranks)"<<G4endl;
if (ver > 1) {
G4cout << "After merge the Run object has test counter value: "
<< static_cast<const Run*>(arun)->GetCounter() << " (with 1 thread== number of ranks)"
<< G4endl;
}
//Merge of scorers
// Merge of scorers
ver = 0;
if (G4ScoringManager::GetScoringManagerIfExist()) {
const auto scor = G4ScoringManager::GetScoringManager();
G4MPIscorerMerger sm(scor);
sm.SetVerbosity(ver);
//Debug!
auto debugme = [&scor](){
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto map = m->GetScoreMap();
std::for_each(map.begin(),map.end(),
[](const G4VScoringMesh::MeshScoreMap::value_type& e) {
G4cout<<e.first<<"("<<e.second<<"):"<<G4endl;
const auto data = e.second->GetMap();
for( auto it = data->begin() ; it != data->end() ; ++it ) {
G4cout<<it->first<<" => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): "
<<it->second->n()<<" "<<it->second->sum_w()<<" "
<<it->second->sum_w2()<<" "<<it->second->sum_wx()<<" "
<<it->second->sum_wx2()<<G4endl;
}
});
}
};
//Debug!
if ( ver > 4 ) {
G4cout<<"Before merging: Meshes dump"<<G4endl;
debugme();
const auto scor = G4ScoringManager::GetScoringManager();
G4MPIscorerMerger sm(scor);
sm.SetVerbosity(ver);
// Debug!
auto debugme = [&scor]() {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto map = m->GetScoreMap();
std::for_each(
map.begin(), map.end(), [](const G4VScoringMesh::MeshScoreMap::value_type& e) {
G4cout << e.first << "(" << e.second << "):" << G4endl;
const auto data = e.second->GetMap();
for (auto it = data->begin(); it != data->end(); ++it) {
G4cout << it->first
<< " => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): " << it->second->n()
<< " " << it->second->sum_w() << " " << it->second->sum_w2() << " "
<< it->second->sum_wx() << " " << it->second->sum_wx2() << G4endl;
}
});
}
//Write partial scorers from single ranks *before* merging
//Do not rely on UI command to write out scorers, because rank-specific
//files will have same file name: need to add rank # to file name
if ( true ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-rank"<<rank<<".csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
};
// Debug!
if (ver > 4) {
G4cout << "Before merging: Meshes dump" << G4endl;
debugme();
}
// Write partial scorers from single ranks *before* merging
// Do not rely on UI command to write out scorers, because rank-specific
// files will have same file name: need to add rank # to file name
if (true) {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname << "scorer-" << mn << "-rank" << rank << ".csv";
scor->DumpAllQuantitiesToFile(mn, fname.str());
}
}
//Now reduce all scorers to rank #0
sm.Merge();
// Now reduce all scorers to rank #0
sm.Merge();
//Debug!
if ( ver > 4 ) {
G4cout<<"After merging: Meshes dump"<<G4endl;
debugme();
// Debug!
if (ver > 4) {
G4cout << "After merging: Meshes dump" << G4endl;
debugme();
}
// For rank #0 write out the merged files
if (rank == 0) {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname << "scorer-" << mn << "-merged.csv";
scor->DumpAllQuantitiesToFile(mn, fname.str());
}
//For rank #0 write out the merged files
if ( rank == 0 ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-merged.csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
}
}
//Save histograms *before* MPI merging for rank #0
if (rank == 0)
{
G4String fname("dose-rank0");
Analysis* myana = Analysis::GetAnalysis();
myana-> Save(fname);
myana-> Close(false); // close file withour resetting data
}
//Merge of g4analysis objects
ver=0;
// Save histograms *before* MPI merging for rank #0
if (rank == 0) {
G4String fname("dose-rank0");
Analysis* myana = Analysis::GetAnalysis();
myana->Save(fname);
myana->Close(false); // close file withour resetting data
}
// Merge of g4analysis objects
ver = 0;
G4MPIhistoMerger hm(G4AnalysisManager::Instance());
hm.SetVerbosity(ver);
hm.Merge();
//Save g4analysis objects to a file
//NB: It is important that the save is done *after* MPI-merging of histograms
// Save g4analysis objects to a file
// NB: It is important that the save is done *after* MPI-merging of histograms
//One can save all ranks or just rank0, chane the if
// One can save all ranks or just rank0, chane the if
if (true /*rank == 0*/) {
std::ostringstream fname;
fname<<"dose-rank"<<rank;
fname << "dose-rank" << rank;
if (rank == 0) {
fname.str("dose-merged");
}
Analysis* myana = Analysis::GetAnalysis();
myana-> Save(fname.str());
myana->Save(fname.str());
}
Analysis* myana = Analysis::GetAnalysis();
myana-> Close();
myana->Close();
G4cout << "===================================================" << G4endl;
G4cout << "End EndOfRunAction for master thread in rank: " << rank << G4endl;
G4cout << "===================================================" << G4endl;
}
@@ -24,20 +24,22 @@
// ********************************************************************
//
#include "RunMerger.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunMerger::Pack() {
//Very imporant, here fMyRun is const!
//Register a user-data in the user Run class with MPI merger
InputUserData(const_cast<int*>(&(fMyRun->fDummyCounter)),MPI::INT,1);
void RunMerger::Pack()
{
// Very imporant, here fMyRun is const!
// Register a user-data in the user Run class with MPI merger
InputUserData(const_cast<int*>(&(fMyRun->fDummyCounter)), MPI::INT, 1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunMerger::UnPack() {
//Create a dummy user-Run, used to contain data received via MPI
G4Run* RunMerger::UnPack()
{
// Create a dummy user-Run, used to contain data received via MPI
Run* aDummyRun = new Run;
OutputUserData(&(aDummyRun->fDummyCounter),MPI::INT,1);
OutputUserData(&(aDummyRun->fDummyCounter), MPI::INT, 1);
return aDummyRun;
}
@@ -27,45 +27,40 @@
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
#include "VoxelParam.hh"
#include "G4Box.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
#include "VoxelParam.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::VoxelParam()
{
}
VoxelParam::VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::~VoxelParam()
{
}
VoxelParam::~VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const
void VoxelParam::ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const
{
const G4int NX = 100;
G4int iy = id / NX;
G4int ix = id % NX;
const G4double dxyz = 1.*mm;
const G4double DXY = 10.*cm;
const G4double dxyz = 1. * mm;
const G4double DXY = 10. * cm;
G4double x0 = -DXY/2. + ix*dxyz;
G4double y0 = -DXY/2. + iy*dxyz;
G4double x0 = -DXY / 2. + ix * dxyz;
G4double y0 = -DXY / 2. + iy * dxyz;
vol-> SetTranslation(G4ThreeVector(x0,y0,0.));
vol-> SetRotation(0);
vol->SetTranslation(G4ThreeVector(x0, y0, 0.));
vol->SetRotation(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeDimensions(G4Box& box, const G4int,
const G4VPhysicalVolume*) const
void VoxelParam::ComputeDimensions(G4Box& box, const G4int, const G4VPhysicalVolume*) const
{
const G4double dxyz = 0.5*mm;
const G4double dxyz = 0.5 * mm;
box.SetXHalfLength(dxyz);
box.SetYHalfLength(dxyz);
@@ -27,58 +27,53 @@
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
//#include "G4MPImanager.hh"
// #include "G4MPImanager.hh"
#include "VoxelSD.hh"
#include "Analysis.hh"
#include "G4SDManager.hh"
#include "G4Step.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VTouchable.hh"
#include "Randomize.hh"
#include "Analysis.hh"
#include "VoxelSD.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::VoxelSD(const G4String& name)
: G4VSensitiveDetector(name)
VoxelSD::VoxelSD(const G4String& name) : G4VSensitiveDetector(name)
{
G4SDManager::GetSDMpointer()-> AddNewDetector(this);
G4SDManager::GetSDMpointer()->AddNewDetector(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::~VoxelSD()
{
}
VoxelSD::~VoxelSD() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool VoxelSD::ProcessHits(G4Step* astep, G4TouchableHistory*)
{
G4ThreeVector x0 = astep-> GetPreStepPoint()-> GetPosition();
G4ThreeVector x1 = astep-> GetPostStepPoint()-> GetPosition();
G4ThreeVector x0 = astep->GetPreStepPoint()->GetPosition();
G4ThreeVector x1 = astep->GetPostStepPoint()->GetPosition();
G4int tid = astep-> GetTrack()-> GetTrackID();
G4int iz = astep-> GetPreStepPoint()-> GetTouchable()-> GetReplicaNumber(1);
G4int tid = astep->GetTrack()->GetTrackID();
G4int iz = astep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(1);
Analysis* myana = Analysis::GetAnalysis();
// incident position
if ( tid == 1 && iz == 1000 ) { // scored @ first layer
myana-> FillIncident(x0);
if (tid == 1 && iz == 1000) { // scored @ first layer
myana->FillIncident(x0);
}
// energy deposit
G4ThreeVector p = G4UniformRand()*(x1-x0) + x0; // position sampling
G4double edep = astep-> GetTotalEnergyDeposit();
myana-> FillDose(p, edep);
G4ThreeVector p = G4UniformRand() * (x1 - x0) + x0; // position sampling
G4double edep = astep->GetTotalEnergyDeposit();
myana->FillDose(p, edep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::Initialize(G4HCofThisEvent*)
{
}
void VoxelSD::Initialize(G4HCofThisEvent*) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::EndOfEvent(G4HCofThisEvent*)
{
}
void VoxelSD::EndOfEvent(G4HCofThisEvent*) {}
@@ -26,25 +26,25 @@
//
/// @brief A MPI example code
#include "G4MPIextraWorker.hh"
#include "G4MPImanager.hh"
#include "G4MPIsession.hh"
#include "G4MPIextraWorker.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
# include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
# include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4UserRunAction.hh"
#include "G4VisExecutive.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "RunActionMaster.hh"
#include "FTFP_BERT.hh"
#include "RunActionMaster.hh"
#include "G4ScoringManager.hh"
#include "G4UImanager.hh"
#include "G4UserRunAction.hh"
#include "G4VisExecutive.hh"
#include "globals.hh"
int main(int argc, char** argv)
@@ -61,50 +61,48 @@ int main(int argc, char** argv)
// At first, G4MPImanager/G4MPIsession should be created.
G4int nofExtraWorkers = 0;
#ifndef G4MULTITHREADED
if ( mergeNtuple ) nofExtraWorkers = 1;
if (mergeNtuple) nofExtraWorkers = 1;
#endif
G4MPImanager* g4MPI = new G4MPImanager(argc, argv, nofExtraWorkers);
g4MPI->SetVerbose(1);
// MPI session (G4MPIsession) instead of G4UIterminal
// Terminal availability depends on your MPI implementation.
G4MPIsession* session = g4MPI-> GetMPIsession();
G4MPIsession* session = g4MPI->GetMPIsession();
// LAM/MPI users can use G4tcsh.
G4String prompt = "";
prompt += "G4MPI";
prompt += "(%s)[%/]:";
session-> SetPrompt(prompt);
session->SetPrompt(prompt);
// --------------------------------------------------------------------
// user application setting
// --------------------------------------------------------------------
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager();
runManager-> SetNumberOfThreads(4);
runManager->SetNumberOfThreads(4);
#else
G4RunManager* runManager = new G4RunManager();
#endif
G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
scManager->SetVerboseLevel(1);
G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
scManager->SetVerboseLevel(1);
// setup your application
runManager-> SetUserInitialization(new DetectorConstruction);
runManager-> SetUserInitialization(new FTFP_BERT);
runManager-> SetUserInitialization(
new ActionInitialization(useNtuple, mergeNtuple));
runManager->SetUserInitialization(new DetectorConstruction);
runManager->SetUserInitialization(new FTFP_BERT);
runManager->SetUserInitialization(new ActionInitialization(useNtuple, mergeNtuple));
runManager-> Initialize();
runManager->Initialize();
// extra worker (for collecting ntuple data)
if ( g4MPI->IsExtraWorker() ) {
if (g4MPI->IsExtraWorker()) {
G4cout << "Set extra worker" << G4endl;
G4UserRunAction* runAction
= const_cast<G4UserRunAction*>(runManager->GetUserRunAction());
G4UserRunAction* runAction = const_cast<G4UserRunAction*>(runManager->GetUserRunAction());
g4MPI->SetExtraWorker(new G4MPIextraWorker(runAction));
}
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
visManager->Initialize();
G4cout << G4endl;
// --------------------------------------------------------------------
@@ -112,7 +110,7 @@ G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
// MPIsession treats both interactive and batch modes.
// Just start your session as below.
// --------------------------------------------------------------------
session-> SessionStart();
session->SessionStart();
// --------------------------------------------------------------------
// termination
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
/// @file ActionInitialization.hh
/// @file ActionInitialization.hh
/// @brief Define action initialization
#ifndef ACTION_INITIALIZATION_H
@@ -33,16 +33,18 @@
#include "G4VUserActionInitialization.hh"
#include "globals.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization(G4bool useNtuple, G4bool mergeNtuple);
~ActionInitialization();
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization(G4bool useNtuple, G4bool mergeNtuple);
~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
private:
G4bool fUseNtuple;
G4bool fMergeNtuple;
virtual void BuildForMaster() const;
virtual void Build() const;
private:
G4bool fUseNtuple;
G4bool fMergeNtuple;
};
#endif
@@ -31,59 +31,62 @@
#define ANALYSIS_MANAGER_H
#include "G4ThreeVector.hh"
#include <tools/histo/h1d>
#include <tools/histo/h2d>
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
class Analysis {
public:
~Analysis();
class Analysis
{
public:
~Analysis();
static Analysis* GetAnalysis();
static Analysis* GetAnalysis();
void Book();
void EndOfRun();
void Book();
void EndOfRun();
void OpenFile(const G4String& fname);
void Save();
void Close(G4bool reset = true);
void OpenFile(const G4String& fname);
void Save();
void Close(G4bool reset = true);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void ClearIncidentFlag();
void ClearIncidentFlag();
void SetUseNtuple(G4bool useNtuple) {
G4cout << "Set useNtuple: " << useNtuple << G4endl;
fUseNtuple = useNtuple;
}
void SetUseNtuple(G4bool useNtuple)
{
G4cout << "Set useNtuple: " << useNtuple << G4endl;
fUseNtuple = useNtuple;
}
void SetMergeNtuple(G4bool mergeNtuple) {
G4cout << "Set mergeNtuple: " << mergeNtuple << G4endl;
fMergeNtuple = mergeNtuple;
}
void SetMergeNtuple(G4bool mergeNtuple)
{
G4cout << "Set mergeNtuple: " << mergeNtuple << G4endl;
fMergeNtuple = mergeNtuple;
}
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
G4bool fUseNtuple;
G4bool fMergeNtuple;
G4bool fUseNtuple;
G4bool fMergeNtuple;
//Histograms handlers
G4int fincident_x_hist;
G4int fincident_map;
G4int fdose_hist;
G4int fdose_map;
G4int fdose_prof;
G4int fdose_map_prof;
G4int fdose_map3d;
// Histograms handlers
G4int fincident_x_hist;
G4int fincident_map;
G4int fdose_hist;
G4int fdose_map;
G4int fdose_prof;
G4int fdose_map_prof;
G4int fdose_map3d;
static G4ThreadLocal G4int fincidentFlag;
static G4ThreadLocal G4int fincidentFlag;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,17 +34,17 @@
class G4LogicalVolume;
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
~DetectorConstruction();
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
};
#endif
@@ -32,13 +32,14 @@
#include "G4UserEventAction.hh"
class EventAction : public G4UserEventAction {
public:
EventAction();
~EventAction();
class EventAction : public G4UserEventAction
{
public:
EventAction();
~EventAction();
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
};
#endif
@@ -30,58 +30,62 @@
#ifndef MEDICAL_BEAM_H
#define MEDICAL_BEAM_H
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4ParticleDefinition;
class MedicalBeam : public G4VUserPrimaryGeneratorAction {
public:
enum FieldShape{ kSQUARE=0, kCIRCLE };
class MedicalBeam : public G4VUserPrimaryGeneratorAction
{
public:
enum FieldShape
{
kSQUARE = 0,
kCIRCLE
};
MedicalBeam();
~MedicalBeam();
MedicalBeam();
~MedicalBeam();
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -112,7 +116,7 @@ inline void MedicalBeam::SetSourcePosition(const G4ThreeVector& pos)
inline G4ThreeVector MedicalBeam::GetSourcePosition() const
{
return fsourcePosition;
return fsourcePosition;
}
inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
@@ -122,7 +126,7 @@ inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
inline MedicalBeam::FieldShape MedicalBeam::GetFieldShape() const
{
return ffieldShape;
return ffieldShape;
}
inline void MedicalBeam::SetSSD(G4double ssd)
@@ -28,17 +28,20 @@
#include <G4Run.hh>
//Dummy class to show how to use MPI merging of
//user defined G4Run. The dummycounter it's a unique number among threads.
//Merge actually sums the dummyCounter so for the global run that is Sum(i, 0<i<Nt)
class Run : public G4Run {
friend class RunMerger;
public:
Run();
virtual ~Run() {}
void Merge(const G4Run*);
G4int GetCounter() const { return fDummyCounter; }
private:
G4int fDummyCounter;
// Dummy class to show how to use MPI merging of
// user defined G4Run. The dummycounter it's a unique number among threads.
// Merge actually sums the dummyCounter so for the global run that is Sum(i, 0<i<Nt)
class Run : public G4Run
{
friend class RunMerger;
public:
Run();
virtual ~Run() {}
void Merge(const G4Run*);
G4int GetCounter() const { return fDummyCounter; }
private:
G4int fDummyCounter;
};
#endif //RUN_HH
#endif // RUN_HH
@@ -32,14 +32,15 @@
#include "G4UserRunAction.hh"
class RunAction : public G4UserRunAction {
public:
RunAction(G4bool useNtuple, G4bool mergeNtuple);
~RunAction();
class RunAction : public G4UserRunAction
{
public:
RunAction(G4bool useNtuple, G4bool mergeNtuple);
~RunAction();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
};
#endif
@@ -34,17 +34,18 @@
class G4MPIntupleMerger;
class RunActionMaster : public G4UserRunAction {
public:
RunActionMaster(G4bool useNtuple, G4bool mergeNtuple);
~RunActionMaster();
class RunActionMaster : public G4UserRunAction
{
public:
RunActionMaster(G4bool useNtuple, G4bool mergeNtuple);
~RunActionMaster();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
private:
G4MPIntupleMerger* fMPIntupleMerger;
private:
G4MPIntupleMerger* fMPIntupleMerger;
};
#endif
@@ -25,20 +25,23 @@
//
#ifndef MPIRUNMERGER_HH
#define MPIRUNMERGER_HH
#include <G4VUserMPIrunMerger.hh>
#include "Run.hh"
//Simple class showing how to reduce via MPI user defined run
class RunMerger : public G4VUserMPIrunMerger {
public:
RunMerger(const Run* arun,G4int destination=G4MPImanager::kRANK_MASTER,
G4int verb=0)
: G4VUserMPIrunMerger(arun,destination,verb ) , fMyRun(arun) {}
protected:
void Pack();
G4Run* UnPack();
private:
const Run* fMyRun;
#include <G4VUserMPIrunMerger.hh>
// Simple class showing how to reduce via MPI user defined run
class RunMerger : public G4VUserMPIrunMerger
{
public:
RunMerger(const Run* arun, G4int destination = G4MPImanager::kRANK_MASTER, G4int verb = 0)
: G4VUserMPIrunMerger(arun, destination, verb), fMyRun(arun)
{}
protected:
void Pack();
G4Run* UnPack();
private:
const Run* fMyRun;
};
#endif
@@ -32,54 +32,39 @@
#include "G4VPVParameterisation.hh"
class VoxelParam : public G4VPVParameterisation {
public:
VoxelParam();
~VoxelParam();
class VoxelParam : public G4VPVParameterisation
{
public:
VoxelParam();
~VoxelParam();
virtual void ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const;
virtual void ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id,
const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id, const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions
(G4Trd&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trd&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Trap&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Trap&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Cons&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Cons&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Sphere&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Sphere&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Orb&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Orb&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Ellipsoid&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Ellipsoid&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Torus&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Torus&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Para&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Para&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Hype&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Hype&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Tubs&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Tubs&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polycone&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polyhedra&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polycone&, const G4int, const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions(G4Polyhedra&, const G4int, const G4VPhysicalVolume*) const {}
};
#endif
@@ -32,15 +32,16 @@
#include "G4VSensitiveDetector.hh"
class VoxelSD : public G4VSensitiveDetector {
public:
VoxelSD(const G4String& name);
~VoxelSD();
class VoxelSD : public G4VSensitiveDetector
{
public:
VoxelSD(const G4String& name);
~VoxelSD();
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
};
#endif
@@ -28,24 +28,21 @@
/// @brief Define action initialization
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "MedicalBeam.hh"
#include "RunAction.hh"
#include "RunActionMaster.hh"
#include "G4Threading.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization(G4bool useNtuple, G4bool mergeNtuple)
: G4VUserActionInitialization(),
fUseNtuple(useNtuple),
fMergeNtuple(mergeNtuple)
{
}
: G4VUserActionInitialization(), fUseNtuple(useNtuple), fMergeNtuple(mergeNtuple)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
}
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
@@ -60,8 +57,9 @@ void ActionInitialization::Build() const
SetUserAction(new MedicalBeam);
SetUserAction(new EventAction);
if ( G4Threading::IsMultithreadedApplication() )
SetUserAction(new RunAction(fUseNtuple, fMergeNtuple));
else
SetUserAction(new RunActionMaster(fUseNtuple, fMergeNtuple));//Use master version for sequential
if (G4Threading::IsMultithreadedApplication())
SetUserAction(new RunAction(fUseNtuple, fMergeNtuple));
else
SetUserAction(
new RunActionMaster(fUseNtuple, fMergeNtuple)); // Use master version for sequential
}
@@ -27,16 +27,17 @@
/// @file Analysis.cc
/// @brief Define histograms and ntuples
#include "G4AutoDelete.hh"
#include "G4SystemOfUnits.hh"
#include "Analysis.hh"
//Note: ntuple merging is supported only with Root format
#include "G4AutoDelete.hh"
#include "G4SystemOfUnits.hh"
// Note: ntuple merging is supported only with Root format
#ifndef G4MULTITHREADED
#include "G4RootMpiAnalysisManager.hh"
# include "G4RootMpiAnalysisManager.hh"
using G4AnalysisManager = G4RootMpiAnalysisManager;
#else
#include "G4RootAnalysisManager.hh"
# include "G4RootAnalysisManager.hh"
using G4AnalysisManager = G4RootAnalysisManager;
#endif
@@ -44,29 +45,30 @@ G4ThreadLocal G4int Analysis::fincidentFlag = false;
G4ThreadLocal Analysis* the_analysis = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis*
Analysis::GetAnalysis()
Analysis* Analysis::GetAnalysis()
{
if (!the_analysis)
{
the_analysis = new Analysis();
G4AutoDelete::Register(the_analysis);
}
if (!the_analysis) {
the_analysis = new Analysis();
G4AutoDelete::Register(the_analysis);
}
return the_analysis;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::Analysis() :
fUseNtuple(true),
fMergeNtuple(true),
fincident_x_hist(0), fincident_map(0), fdose_hist(0), fdose_map(0),
fdose_prof(0), fdose_map_prof(0), fdose_map3d(0)
{
}
Analysis::Analysis()
: fUseNtuple(true),
fMergeNtuple(true),
fincident_x_hist(0),
fincident_map(0),
fdose_hist(0),
fdose_map(0),
fdose_prof(0),
fdose_map_prof(0),
fdose_map3d(0)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Book()
void Analysis::Book()
{
G4cout << "Analysis::Book start, fUseNtuple: " << fUseNtuple << G4endl;
@@ -77,22 +79,20 @@ Analysis::Book()
mgr->SetNtupleMerging(fMergeNtuple);
#endif
fincident_x_hist = mgr->CreateH1("incident_x", "Incident X", 100, -5 * cm,
5 * cm, "cm");
fincident_map = mgr->CreateH2("incident_map", "Incident Map", 50, -5 * cm,
5 * cm, 50, -5 * cm, 5 * cm, "cm", "cm");
fdose_hist
= mgr->CreateH1("dose", "Dose distribution", 500, 0, 50 * cm, "cm");
fdose_map = mgr->CreateH2("dose_map", "Dose distribution", 500, 0, 50 * cm,
200, -10 * cm, 10 * cm, "cm", "cm");
fdose_map3d = mgr->CreateH3("dose_map_3d", "Dose distribution", 30, 0,
50 * cm, 20, -10 * cm, 10 * cm, 20, -10 * cm, 10 * cm, "cm", "cm", "cm");
fdose_prof = mgr->CreateP1("dose_prof", "Dose distribution", 300, 0, 30 * cm,
0, 100 * MeV, "cm", "MeV");
fdose_map_prof = mgr->CreateP2("dose_map_prof", "Dose distribution", 300, 0,
30 * cm, 80, -4 * cm, 4 * cm, 0, 100 * MeV, "cm", "cm", "MeV");
fincident_x_hist = mgr->CreateH1("incident_x", "Incident X", 100, -5 * cm, 5 * cm, "cm");
fincident_map = mgr->CreateH2("incident_map", "Incident Map", 50, -5 * cm, 5 * cm, 50, -5 * cm,
5 * cm, "cm", "cm");
fdose_hist = mgr->CreateH1("dose", "Dose distribution", 500, 0, 50 * cm, "cm");
fdose_map = mgr->CreateH2("dose_map", "Dose distribution", 500, 0, 50 * cm, 200, -10 * cm,
10 * cm, "cm", "cm");
fdose_map3d = mgr->CreateH3("dose_map_3d", "Dose distribution", 30, 0, 50 * cm, 20, -10 * cm,
10 * cm, 20, -10 * cm, 10 * cm, "cm", "cm", "cm");
fdose_prof =
mgr->CreateP1("dose_prof", "Dose distribution", 300, 0, 30 * cm, 0, 100 * MeV, "cm", "MeV");
fdose_map_prof = mgr->CreateP2("dose_map_prof", "Dose distribution", 300, 0, 30 * cm, 80, -4 * cm,
4 * cm, 0, 100 * MeV, "cm", "cm", "MeV");
if ( fUseNtuple) {
if (fUseNtuple) {
mgr->CreateNtuple("Dose", "Dose distribution"); // ntuple Id = 0
mgr->CreateNtupleDColumn("pz");
mgr->CreateNtupleDColumn("px");
@@ -104,73 +104,62 @@ Analysis::Book()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::~Analysis()
{
}
Analysis::~Analysis() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::OpenFile(const G4String& fname)
void Analysis::OpenFile(const G4String& fname)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->OpenFile(fname.c_str());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Save()
void Analysis::Save()
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->Write();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Close(G4bool reset)
void Analysis::Close(G4bool reset)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->CloseFile(reset);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillIncident(const G4ThreeVector& p)
void Analysis::FillIncident(const G4ThreeVector& p)
{
if (!fincidentFlag)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->FillH2(fincident_map, p.x(), p.y());
mgr->FillH1(fincident_x_hist, p.x());
fincidentFlag = true;
}
if (!fincidentFlag) {
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->FillH2(fincident_map, p.x(), p.y());
mgr->FillH1(fincident_x_hist, p.x());
fincidentFlag = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
void Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
{
const G4double dxy = 10. * mm;
if (std::abs(p.y()) < dxy)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
const G4double Z0 = 25. * cm;
if (std::abs(p.y()) < dxy) {
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
const G4double Z0 = 25. * cm;
mgr->FillH2(fdose_map, p.z() + Z0, p.x(), dedx / GeV);
mgr->FillP2(fdose_map_prof, p.z() + Z0, p.x(), dedx);
mgr->FillH3(fdose_map3d, p.z() + Z0, p.x(), p.y(), dedx / GeV);
if (std::abs(p.x()) < dxy)
{
mgr->FillH1(fdose_hist, p.z() + Z0, dedx / GeV);
mgr->FillP1(fdose_prof, p.z() + Z0, dedx);
}
if ( fUseNtuple ) {
// the same fill frequency as H2 "dose_map"
mgr->FillNtupleDColumn(0, p.z() + Z0);
mgr->FillNtupleDColumn(1, p.x());
mgr->FillNtupleDColumn(2, dedx / GeV);
mgr->AddNtupleRow();
}
mgr->FillH2(fdose_map, p.z() + Z0, p.x(), dedx / GeV);
mgr->FillP2(fdose_map_prof, p.z() + Z0, p.x(), dedx);
mgr->FillH3(fdose_map3d, p.z() + Z0, p.x(), p.y(), dedx / GeV);
if (std::abs(p.x()) < dxy) {
mgr->FillH1(fdose_hist, p.z() + Z0, dedx / GeV);
mgr->FillP1(fdose_prof, p.z() + Z0, dedx);
}
if (fUseNtuple) {
// the same fill frequency as H2 "dose_map"
mgr->FillNtupleDColumn(0, p.z() + Z0);
mgr->FillNtupleDColumn(1, p.x());
mgr->FillNtupleDColumn(2, dedx / GeV);
mgr->AddNtupleRow();
}
}
}
@@ -27,6 +27,11 @@
/// @file DetectorConstruction.hh
/// @brief Define geometry
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4NistManager.hh"
@@ -34,24 +39,16 @@
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisAttributes.hh"
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
typedef G4LogicalVolume G4LV;
typedef G4PVPlacement G4PVP;
typedef G4VisAttributes G4VA;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: flv_voxel(NULL)
{
}
DetectorConstruction::DetectorConstruction() : flv_voxel(NULL) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
}
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
@@ -60,63 +57,57 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
G4VisAttributes* va;
// world volume
const G4double DXYZ_WORLD = 200.*cm;
G4Box* sld_world = new G4Box("world",
DXYZ_WORLD/2., DXYZ_WORLD/2., DXYZ_WORLD/2.);
const G4double DXYZ_WORLD = 200. * cm;
G4Box* sld_world = new G4Box("world", DXYZ_WORLD / 2., DXYZ_WORLD / 2., DXYZ_WORLD / 2.);
G4Material* vacuum = nistManager-> FindOrBuildMaterial("G4_Galactic");
G4Material* vacuum = nistManager->FindOrBuildMaterial("G4_Galactic");
G4LV* lv_world = new G4LogicalVolume(sld_world, vacuum, "world");
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA",
lv_world, 0, false, 0);
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA", lv_world, 0, false, 0);
// vis. attributes
va = new G4VA(G4Color(1.,1.,1.));
va-> SetVisibility(false);
lv_world-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 1., 1.));
va->SetVisibility(false);
lv_world->SetVisAttributes(va);
// water phantom
const G4double DXY_PHANTOM = 20.*cm;
const G4double DZ_PHANTOM = 50.*cm;
const G4double DXY_PHANTOM = 20. * cm;
const G4double DZ_PHANTOM = 50. * cm;
G4Box* sld_phantom = new G4Box("phantom",
DXY_PHANTOM/2., DXY_PHANTOM/2., DZ_PHANTOM/2.);
G4Box* sld_phantom = new G4Box("phantom", DXY_PHANTOM / 2., DXY_PHANTOM / 2., DZ_PHANTOM / 2.);
G4Material* water = nistManager-> FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom,
water, "phantom");
G4Material* water = nistManager->FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom, water, "phantom");
va = new G4VA(G4Color(0.,1.,1.));
lv_phantom-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
lv_phantom->SetVisAttributes(va);
new G4PVP(0, G4ThreeVector(), lv_phantom, "phantom", lv_world, false, 0);
// voxel planes
const G4double DXY_VXP = 20.*cm;
const G4double DZ_VXP = 1.*mm;
const G4double DXY_VXP = 20. * cm;
const G4double DZ_VXP = 1. * mm;
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP/2., DXY_VXP/2., DZ_VXP/2.);
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP / 2., DXY_VXP / 2., DZ_VXP / 2.);
G4LV* lv_vxp = new G4LV(sld_vxp, water, "vxplane");
va = new G4VA(G4Color(1.,0.,0.));
va-> SetVisibility(false);
lv_vxp-> SetVisAttributes(va);
va = new G4VA(G4Color(1., 0., 0.));
va->SetVisibility(false);
lv_vxp->SetVisAttributes(va);
for (G4int iz =0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM/2. + (iz+0.5)*DZ_VXP;
new G4PVP(0, G4ThreeVector(0.,0.,z0),
lv_vxp, "vxplane", lv_phantom, false, 1000+iz);
for (G4int iz = 0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM / 2. + (iz + 0.5) * DZ_VXP;
new G4PVP(0, G4ThreeVector(0., 0., z0), lv_vxp, "vxplane", lv_phantom, false, 1000 + iz);
}
// voxel parameterized
G4Box* sld_voxel = new G4Box("voxel",1.,1.,1.); // dummy
G4Box* sld_voxel = new G4Box("voxel", 1., 1., 1.); // dummy
flv_voxel = new G4LV(sld_voxel, water, "voxel");
va = new G4VA(G4Color(0.,1.,1.));
va-> SetVisibility(false);
flv_voxel-> SetVisAttributes(va);
va = new G4VA(G4Color(0., 1., 1.));
va->SetVisibility(false);
flv_voxel->SetVisAttributes(va);
const G4int nvoxels = 100*100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels,
new VoxelParam());
const G4int nvoxels = 100 * 100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels, new VoxelParam());
return world;
}
@@ -124,5 +115,5 @@ G4VPhysicalVolume* DetectorConstruction::Construct()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField()
{
flv_voxel-> SetSensitiveDetector(new VoxelSD("voxel"));
flv_voxel->SetSensitiveDetector(new VoxelSD("voxel"));
}
@@ -27,28 +27,24 @@
/// @file EventAction.cc
/// @brief Describe event actions
#include "G4Event.hh"
#include "Analysis.hh"
#include "EventAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction()
{
}
#include "Analysis.hh"
#include "G4Event.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{
}
EventAction::EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> ClearIncidentFlag();
myana->ClearIncidentFlag();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event*)
{
}
void EventAction::EndOfEventAction(const G4Event*) {}
@@ -27,47 +27,52 @@
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
#include <cmath>
#include "MedicalBeam.hh"
#include "G4Event.hh"
#include "G4ParticleTable.hh"
#include "G4PrimaryVertex.hh"
#include "Randomize.hh"
#include "MedicalBeam.hh"
#include <cmath>
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::MedicalBeam()
: fparticle(0), fkineticE(1.*MeV), fsourcePosition(G4ThreeVector()),
fSSD(1.*m), ffieldShape(MedicalBeam::kSQUARE), ffieldR(10.*cm)
: fparticle(0),
fkineticE(1. * MeV),
fsourcePosition(G4ThreeVector()),
fSSD(1. * m),
ffieldShape(MedicalBeam::kSQUARE),
ffieldR(10. * cm)
{
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
fparticle = particleTable-> FindParticle("proton");
fparticle = particleTable->FindParticle("proton");
fkineticE = 200.*MeV;
fsourcePosition = G4ThreeVector(0.,0.,-125.*cm);
fSSD = 100.*cm;
ffieldXY[0] = ffieldXY[1] = 5.*cm;
fkineticE = 200. * MeV;
fsourcePosition = G4ThreeVector(0., 0., -125. * cm);
fSSD = 100. * cm;
ffieldXY[0] = ffieldXY[1] = 5. * cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::~MedicalBeam()
{
}
MedicalBeam::~MedicalBeam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ThreeVector MedicalBeam::GenerateBeamDirection() const
{
// uniform distribution in a limitted solid angle
G4double dr;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
dr = std::sqrt(sqr(ffieldXY[0]/2.) + sqr(ffieldXY[1]/2.));
} else {
if (ffieldShape == MedicalBeam::kSQUARE) {
dr = std::sqrt(sqr(ffieldXY[0] / 2.) + sqr(ffieldXY[1] / 2.));
}
else {
dr = ffieldR;
}
G4double sin0 = dr/fSSD;
G4double cos0 = std::sqrt(1.-sqr(sin0));
G4double sin0 = dr / fSSD;
G4double cos0 = std::sqrt(1. - sqr(sin0));
G4double dcos = 0.;
G4double dsin, dphi, z;
@@ -76,44 +81,44 @@ G4ThreeVector MedicalBeam::GenerateBeamDirection() const
G4double y = DBL_MAX;
G4double xmax, ymax;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
xmax = ffieldXY[0]/2./fSSD;
ymax = ffieldXY[1]/2./fSSD;
} else {
xmax = ymax = DBL_MAX-1.;
if (ffieldShape == MedicalBeam::kSQUARE) {
xmax = ffieldXY[0] / 2. / fSSD;
ymax = ffieldXY[1] / 2. / fSSD;
}
else {
xmax = ymax = DBL_MAX - 1.;
}
while(! (std::abs(x) < xmax && std::abs(y) < ymax) ) {
while (!(std::abs(x) < xmax && std::abs(y) < ymax)) {
dcos = G4RandFlat::shoot(cos0, 1.);
dsin = std::sqrt(1.-sqr(dcos));
dsin = std::sqrt(1. - sqr(dcos));
dphi = G4RandFlat::shoot(0., twopi);
x = std::cos(dphi)*dsin*dcos;
y = std::sin(dphi)*dsin*dcos;
x = std::cos(dphi) * dsin * dcos;
y = std::sin(dphi) * dsin * dcos;
}
z = dcos;
return G4ThreeVector(x,y,z);
return G4ThreeVector(x, y, z);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void MedicalBeam::GeneratePrimaries(G4Event* anEvent)
{
if ( fparticle == NULL ) return;
if (fparticle == NULL) return;
// create a new vertex
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0.*ns);
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0. * ns);
// momentum
G4double mass = fparticle-> GetPDGMass();
G4double p = std::sqrt(sqr(mass+fkineticE)-sqr(mass));
G4ThreeVector pmon = p*GenerateBeamDirection();
G4PrimaryParticle* primary =
new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
G4double mass = fparticle->GetPDGMass();
G4double p = std::sqrt(sqr(mass + fkineticE) - sqr(mass));
G4ThreeVector pmon = p * GenerateBeamDirection();
G4PrimaryParticle* primary = new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
// set primary to vertex
vertex-> SetPrimary(primary);
vertex->SetPrimary(primary);
// set vertex to event
anEvent-> AddPrimaryVertex(vertex);
anEvent->AddPrimaryVertex(vertex);
}
@@ -24,20 +24,24 @@
// ********************************************************************
//
#include "Run.hh"
#include <atomic>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
namespace {
std::atomic_int g_ctr(0);
namespace
{
std::atomic_int g_ctr(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() {
Run::Run()
{
fDummyCounter = g_ctr++;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge(const G4Run* other ) {
void Run::Merge(const G4Run* other)
{
G4Run::Merge(other);
fDummyCounter += static_cast<const Run*>(other)->fDummyCounter;
}
@@ -27,34 +27,33 @@
/// @file RunAction.cc
/// @brief Describe run actions
#include <G4VUserMPIrunMerger.hh>
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunAction.hh"
#include "Run.hh"
#include "G4MPIscorerMerger.hh"
#include "Analysis.hh"
#include "Run.hh"
#include "toolx/mpi/wrmpi"
#include "G4MPImanager.hh"
#include "G4MPIscorerMerger.hh"
#include "G4Threading.hh"
#include <G4VUserMPIrunMerger.hh>
#include <stdio.h>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(G4bool useNtuple, G4bool mergeNtuple)
: G4UserRunAction()
RunAction::RunAction(G4bool useNtuple, G4bool mergeNtuple) : G4UserRunAction()
{
// Book analysis in ctor
Analysis* myana = Analysis::GetAnalysis();
myana->SetUseNtuple(useNtuple);
myana->SetMergeNtuple(mergeNtuple);
G4cout<<"Book analysis on rank: " << G4MPImanager::GetManager()-> GetRank() << G4endl;;
G4cout << "Book analysis on rank: " << G4MPImanager::GetManager()->GetRank() << G4endl;
;
myana->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{
}
RunAction::~RunAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun()
@@ -71,10 +70,10 @@ void RunAction::BeginOfRunAction(const G4Run*)
// ntuples will be written on each rank
G4int rank = G4MPImanager::GetManager()->GetRank();
std::ostringstream fname;
fname<<"dose-rank"<<rank;
fname << "dose-rank" << rank;
myana->OpenFile(fname.str());
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -83,5 +82,5 @@ void RunAction::EndOfRunAction(const G4Run*)
G4cout << "RunAction::EndOfRunAction" << G4endl;
Analysis* myana = Analysis::GetAnalysis();
myana-> Save();
myana->Save();
}
@@ -27,39 +27,41 @@
/// @file RunActionMaster.cc
/// @brief Describe run actions
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunActionMaster.hh"
#include "Analysis.hh"
#include "RunMerger.hh"
#include "G4MPImanager.hh"
#include "G4Threading.hh"
#include <stdio.h>
#ifndef G4MULTITHREADED
#include "G4RootMpiAnalysisManager.hh"
# include "G4RootMpiAnalysisManager.hh"
using G4AnalysisManager = G4RootMpiAnalysisManager;
#else
#include "G4RootAnalysisManager.hh"
# include "G4RootAnalysisManager.hh"
using G4AnalysisManager = G4RootAnalysisManager;
#endif
#include "G4MPIscorerMerger.hh"
#include "G4MPIhistoMerger.hh"
#include "G4MPIntupleMerger.hh"
#include "G4Filesystem.hh"
#include "Run.hh"
#include "G4Filesystem.hh"
#include "G4MPIhistoMerger.hh"
#include "G4MPIntupleMerger.hh"
#include "G4MPIscorerMerger.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunActionMaster::RunActionMaster(G4bool useNtuple, G4bool mergeNtuple)
: G4UserRunAction(),
fMPIntupleMerger(nullptr)
: G4UserRunAction(), fMPIntupleMerger(nullptr)
{
#ifndef G4MULTITHREADED
if ( mergeNtuple &&
G4MPImanager::GetManager()->GetTotalSize() >= 2 ) {
if (mergeNtuple && G4MPImanager::GetManager()->GetTotalSize() >= 2) {
// Activate MPI ntuple merging
// The merger must be created before creating G4AnalysisManager:
// (= the first call to G4AnalysisManager::Instance())
// and deleted only at the end of program
G4int nofReducedNtupleFiles = 0;
// Multiple reduced ntuple files are not yet supported
G4int nofReducedNtupleFiles = 0;
// Multiple reduced ntuple files are not yet supported
G4bool rowWise = false;
G4bool rowMode = true;
fMPIntupleMerger = new G4MPIntupleMerger(nofReducedNtupleFiles, rowWise, rowMode);
@@ -70,7 +72,8 @@ RunActionMaster::RunActionMaster(G4bool useNtuple, G4bool mergeNtuple)
Analysis* myana = Analysis::GetAnalysis();
myana->SetUseNtuple(useNtuple);
myana->SetMergeNtuple(mergeNtuple);
G4cout<<"Book analysis on master on rank: " << G4MPImanager::GetManager()-> GetRank() << G4endl;;
G4cout << "Book analysis on master on rank: " << G4MPImanager::GetManager()->GetRank() << G4endl;
;
myana->Book();
}
@@ -87,8 +90,7 @@ RunActionMaster::~RunActionMaster()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::BeginOfRunAction(const G4Run*)
void RunActionMaster::BeginOfRunAction(const G4Run*)
{
G4cout << "RunActionMaster::BeginOfRunAction" << G4endl;
@@ -96,25 +98,24 @@ RunActionMaster::BeginOfRunAction(const G4Run*)
G4int rank = G4MPImanager::GetManager()->GetRank();
std::ostringstream fname;
fname<<"dose-rank"<<rank;
fname << "dose-rank" << rank;
myana->OpenFile(fname.str());
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::EndOfRunAction(const G4Run* arun)
void RunActionMaster::EndOfRunAction(const G4Run* arun)
{
G4cout << "RunActionMaster::EndOfRunAction" << G4endl;
//This is executed by master thread only. Worker threads have already
//merged their results into this master threads.
// This is executed by master thread only. Worker threads have already
// merged their results into this master threads.
//We are going to merge the results via MPI for:
// 1. User-defined "Run" object
// 2. Command line scorers, if exists
// 3. G4Analysis objects
// We are going to merge the results via MPI for:
// 1. User-defined "Run" object
// 2. Command line scorers, if exists
// 3. G4Analysis objects
// For debugging purposes in the following we write out results twice:
// BEFORE and AFTER the merging, so that rank 0 actually
@@ -123,109 +124,108 @@ RunActionMaster::EndOfRunAction(const G4Run* arun)
// the file *merged* contains the reduction from all ranks.
// It should be very easy to adapt this code
const G4int rank = G4MPImanager::GetManager()-> GetRank();
const G4int rank = G4MPImanager::GetManager()->GetRank();
G4cout << "=====================================================" << G4endl;
G4cout << "Start EndOfRunAction for master thread in rank: " << rank<<G4endl;
G4cout << "Start EndOfRunAction for master thread in rank: " << rank << G4endl;
G4cout << "=====================================================" << G4endl;
if ( ! G4MPImanager::GetManager()->IsExtraWorker() ) {
if (!G4MPImanager::GetManager()->IsExtraWorker()) {
G4cout << "Go to merge on processing workers" << G4endl;
//Merging of G4Run object:
//All ranks > 0 merge to rank #0
// Merging of G4Run object:
// All ranks > 0 merge to rank #0
RunMerger rm(static_cast<const Run*>(arun), G4MPImanager::kRANK_MASTER, 5);
G4int ver = 0 ; //Use 4 for lots of info
if ( rank == 0 && ver == 0) ver = 1;
if ( ver > 1 ) {
G4cout<<"Before merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()<<G4endl;
G4int ver = 0; // Use 4 for lots of info
if (rank == 0 && ver == 0) ver = 1;
if (ver > 1) {
G4cout << "Before merge the Run object has test counter value: "
<< static_cast<const Run*>(arun)->GetCounter() << G4endl;
}
rm.SetVerbosity( ver );
rm.SetVerbosity(ver);
rm.Merge();
if ( ver > 1 ) {
G4cout<<"After merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()
<<" (with 1 thread== number of ranks)"<<G4endl;
if (ver > 1) {
G4cout << "After merge the Run object has test counter value: "
<< static_cast<const Run*>(arun)->GetCounter() << " (with 1 thread== number of ranks)"
<< G4endl;
}
//Merge of scorers
// Merge of scorers
ver = 0;
if (G4ScoringManager::GetScoringManagerIfExist()) {
const auto scor = G4ScoringManager::GetScoringManager();
G4MPIscorerMerger sm(scor);
sm.SetVerbosity(ver);
//Debug!
auto debugme = [&scor](){
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto map = m->GetScoreMap();
std::for_each(map.begin(),map.end(),
[](const G4VScoringMesh::MeshScoreMap::value_type& e) {
G4cout<<e.first<<"("<<e.second<<"):"<<G4endl;
const auto data = e.second->GetMap();
for( auto it = data->begin() ; it != data->end() ; ++it ) {
G4cout<<it->first<<" => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): "
<<it->second->n()<<" "<<it->second->sum_w()<<" "
<<it->second->sum_w2()<<" "<<it->second->sum_wx()<<" "
<<it->second->sum_wx2()<<G4endl;
}
});
}
};
//Debug!
if ( ver > 4 ) {
G4cout<<"Before merging: Meshes dump"<<G4endl;
debugme();
const auto scor = G4ScoringManager::GetScoringManager();
G4MPIscorerMerger sm(scor);
sm.SetVerbosity(ver);
// Debug!
auto debugme = [&scor]() {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto map = m->GetScoreMap();
std::for_each(
map.begin(), map.end(), [](const G4VScoringMesh::MeshScoreMap::value_type& e) {
G4cout << e.first << "(" << e.second << "):" << G4endl;
const auto data = e.second->GetMap();
for (auto it = data->begin(); it != data->end(); ++it) {
G4cout << it->first
<< " => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): " << it->second->n()
<< " " << it->second->sum_w() << " " << it->second->sum_w2() << " "
<< it->second->sum_wx() << " " << it->second->sum_wx2() << G4endl;
}
});
}
//Write partial scorers from single ranks *before* merging
//Do not rely on UI command to write out scorers, because rank-specific
//files will have same file name: need to add rank # to file name
if ( true ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-rank"<<rank<<".csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
};
// Debug!
if (ver > 4) {
G4cout << "Before merging: Meshes dump" << G4endl;
debugme();
}
// Write partial scorers from single ranks *before* merging
// Do not rely on UI command to write out scorers, because rank-specific
// files will have same file name: need to add rank # to file name
if (true) {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname << "scorer-" << mn << "-rank" << rank << ".csv";
scor->DumpAllQuantitiesToFile(mn, fname.str());
}
//Now reduce all scorers to rank #0
sm.Merge();
//Debug!
if ( ver > 4 ) {
G4cout<<"After merging: Meshes dump"<<G4endl;
debugme();
}
// Now reduce all scorers to rank #0
sm.Merge();
// Debug!
if (ver > 4) {
G4cout << "After merging: Meshes dump" << G4endl;
debugme();
}
// For rank #0 write out the merged files
if (rank == 0) {
for (size_t idx = 0; idx < scor->GetNumberOfMesh(); ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname << "scorer-" << mn << "-merged.csv";
scor->DumpAllQuantitiesToFile(mn, fname.str());
}
//For rank #0 write out the merged files
if ( rank == 0 ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-merged.csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
}
}
//Save histograms *before* MPI merging for rank #0
//Can be done only if MPI merging is not activated
if (rank == 0 && (fMPIntupleMerger == nullptr) ) {
// Save histograms *before* MPI merging for rank #0
// Can be done only if MPI merging is not activated
if (rank == 0 && (fMPIntupleMerger == nullptr)) {
Analysis* myana = Analysis::GetAnalysis();
myana-> Save();
myana-> Close(false); // close without resetting histograms
myana->Save();
myana->Close(false); // close without resetting histograms
// Rename file in another file
G4fs::rename("dose-rank0.root", "dose-rank0-part.root");
}
//Merge of g4analysis objects
// Merge of g4analysis objects
G4cout << "Go to merge histograms " << G4endl;
ver=1;
ver = 1;
G4MPIhistoMerger hm(G4AnalysisManager::Instance());
hm.SetVerbosity(ver);
hm.Merge();
@@ -235,11 +235,11 @@ RunActionMaster::EndOfRunAction(const G4Run* arun)
G4cout << "Skip merging on the extra worker" << G4endl;
}
//Save g4analysis objects to a file
// Save g4analysis objects to a file
Analysis* myana = Analysis::GetAnalysis();
myana->OpenFile("dose-rank0.root");
myana-> Save();
myana-> Close();
myana->Save();
myana->Close();
if (rank == 0) {
// Rename files
@@ -24,20 +24,22 @@
// ********************************************************************
//
#include "RunMerger.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunMerger::Pack() {
//Very imporant, here fMyRun is const!
//Register a user-data in the user Run class with MPI merger
InputUserData(const_cast<int*>(&(fMyRun->fDummyCounter)),MPI::INT,1);
void RunMerger::Pack()
{
// Very imporant, here fMyRun is const!
// Register a user-data in the user Run class with MPI merger
InputUserData(const_cast<int*>(&(fMyRun->fDummyCounter)), MPI::INT, 1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunMerger::UnPack() {
//Create a dummy user-Run, used to contain data received via MPI
G4Run* RunMerger::UnPack()
{
// Create a dummy user-Run, used to contain data received via MPI
Run* aDummyRun = new Run;
OutputUserData(&(aDummyRun->fDummyCounter),MPI::INT,1);
OutputUserData(&(aDummyRun->fDummyCounter), MPI::INT, 1);
return aDummyRun;
}
@@ -27,45 +27,40 @@
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
#include "VoxelParam.hh"
#include "G4Box.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
#include "VoxelParam.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::VoxelParam()
{
}
VoxelParam::VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::~VoxelParam()
{
}
VoxelParam::~VoxelParam() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const
void VoxelParam::ComputeTransformation(const G4int id, G4VPhysicalVolume* vol) const
{
const G4int NX = 100;
G4int iy = id / NX;
G4int ix = id % NX;
const G4double dxyz = 1.*mm;
const G4double DXY = 10.*cm;
const G4double dxyz = 1. * mm;
const G4double DXY = 10. * cm;
G4double x0 = -DXY/2. + ix*dxyz;
G4double y0 = -DXY/2. + iy*dxyz;
G4double x0 = -DXY / 2. + ix * dxyz;
G4double y0 = -DXY / 2. + iy * dxyz;
vol-> SetTranslation(G4ThreeVector(x0,y0,0.));
vol-> SetRotation(0);
vol->SetTranslation(G4ThreeVector(x0, y0, 0.));
vol->SetRotation(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeDimensions(G4Box& box, const G4int,
const G4VPhysicalVolume*) const
void VoxelParam::ComputeDimensions(G4Box& box, const G4int, const G4VPhysicalVolume*) const
{
const G4double dxyz = 0.5*mm;
const G4double dxyz = 0.5 * mm;
box.SetXHalfLength(dxyz);
box.SetYHalfLength(dxyz);
@@ -27,58 +27,53 @@
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
//#include "G4MPImanager.hh"
// #include "G4MPImanager.hh"
#include "VoxelSD.hh"
#include "Analysis.hh"
#include "G4SDManager.hh"
#include "G4Step.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VTouchable.hh"
#include "Randomize.hh"
#include "Analysis.hh"
#include "VoxelSD.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::VoxelSD(const G4String& name)
: G4VSensitiveDetector(name)
VoxelSD::VoxelSD(const G4String& name) : G4VSensitiveDetector(name)
{
G4SDManager::GetSDMpointer()-> AddNewDetector(this);
G4SDManager::GetSDMpointer()->AddNewDetector(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::~VoxelSD()
{
}
VoxelSD::~VoxelSD() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool VoxelSD::ProcessHits(G4Step* astep, G4TouchableHistory*)
{
G4ThreeVector x0 = astep-> GetPreStepPoint()-> GetPosition();
G4ThreeVector x1 = astep-> GetPostStepPoint()-> GetPosition();
G4ThreeVector x0 = astep->GetPreStepPoint()->GetPosition();
G4ThreeVector x1 = astep->GetPostStepPoint()->GetPosition();
G4int tid = astep-> GetTrack()-> GetTrackID();
G4int iz = astep-> GetPreStepPoint()-> GetTouchable()-> GetReplicaNumber(1);
G4int tid = astep->GetTrack()->GetTrackID();
G4int iz = astep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(1);
Analysis* myana = Analysis::GetAnalysis();
// incident position
if ( tid == 1 && iz == 1000 ) { // scored @ first layer
myana-> FillIncident(x0);
if (tid == 1 && iz == 1000) { // scored @ first layer
myana->FillIncident(x0);
}
// energy deposit
G4ThreeVector p = G4UniformRand()*(x1-x0) + x0; // position sampling
G4double edep = astep-> GetTotalEnergyDeposit();
myana-> FillDose(p, edep);
G4ThreeVector p = G4UniformRand() * (x1 - x0) + x0; // position sampling
G4double edep = astep->GetTotalEnergyDeposit();
myana->FillDose(p, edep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::Initialize(G4HCofThisEvent*)
{
}
void VoxelSD::Initialize(G4HCofThisEvent*) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::EndOfEvent(G4HCofThisEvent*)
{
}
void VoxelSD::EndOfEvent(G4HCofThisEvent*) {}
@@ -37,33 +37,33 @@
class G4RootMpiNtupleFileManager;
namespace tools {
class impi;
}
namespace tools
{
class impi;
}
class G4RootMpiAnalysisManager : public G4RootAnalysisManager
class G4RootMpiAnalysisManager : public G4RootAnalysisManager
{
public:
explicit G4RootMpiAnalysisManager(G4bool isMaster = true);
virtual ~G4RootMpiAnalysisManager();
// Static methods
static G4RootMpiAnalysisManager* Instance();
// MPI
void SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
void SetMpiNtupleMerging(tools::impi* impi, G4int mpiRank, G4int mpiSize,
G4int nofReducedNtupleFiles = 0);
protected:
// virtual methods from base class
virtual G4bool OpenFileImpl(const G4String& fileName) final;
virtual G4bool WriteImpl() final;
virtual G4bool CloseFileImpl(G4bool reset) final;
virtual G4bool WriteImpl() final;
virtual G4bool CloseFileImpl(G4bool reset) final;
private:
// Static data members
inline static G4RootMpiAnalysisManager* fgInstance { nullptr };
inline static G4RootMpiAnalysisManager* fgInstance{nullptr};
};
#endif
@@ -38,25 +38,25 @@
class G4RootMpiNtupleManager;
class G4RootMpiPNtupleManager;
namespace tools {
class impi;
}
namespace tools
{
class impi;
}
class G4RootMpiNtupleFileManager : public G4RootNtupleFileManager
class G4RootMpiNtupleFileManager : public G4RootNtupleFileManager
{
public:
explicit G4RootMpiNtupleFileManager(const G4AnalysisManagerState& state);
virtual ~G4RootMpiNtupleFileManager();
// MPI
void SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
void SetMpiNtupleMerging(tools::impi* impi, G4int mpiRank, G4int mpiSize,
G4int nofReducedNtupleFiles = 0);
// virtual methods from base class
virtual G4bool ActionAtOpenFile(const G4String& fileName) final;
virtual G4bool ActionAtWrite() final;
virtual G4bool ActionAtCloseFile() final;
virtual G4bool ActionAtCloseFile() final;
virtual G4bool Reset() final;
virtual std::shared_ptr<G4VNtupleManager> CreateNtupleManager() override;
@@ -68,12 +68,12 @@ class G4RootMpiNtupleFileManager : public G4RootNtupleFileManager
void SetMpiNtupleMergingMode(G4int nofNtupleFiles);
void CreateMpiNtupleManagers(tools::impi* impi, G4int mpiRank, G4int mpiSize);
// data members
// data members
tools::impi* fImpi;
G4int fMpiRank;
G4int fMpiSize;
// std::shared_ptr<G4RootMpiNtupleManager> fMpiNtupleManager;
std::shared_ptr<G4RootMpiPNtupleManager> fMpiSlaveNtupleManager;
// std::shared_ptr<G4RootMpiNtupleManager> fMpiNtupleManager;
std::shared_ptr<G4RootMpiPNtupleManager> fMpiSlaveNtupleManager;
G4bool fNtupleBooked;
};
@@ -36,37 +36,35 @@
#include "G4RootNtupleManager.hh"
namespace tools {
class impi;
namespace tools
{
class impi;
}
class G4RootMpiNtupleManager : public G4RootNtupleManager
{
public:
G4RootMpiNtupleManager(const G4AnalysisManagerState& state,
std::shared_ptr<G4NtupleBookingManager> bookingManger,
G4bool rowWise, G4bool rowMode,
tools::impi* impi, G4int mpiSize);
std::shared_ptr<G4NtupleBookingManager> bookingManger, G4bool rowWise,
G4bool rowMode, tools::impi* impi, G4int mpiSize);
virtual ~G4RootMpiNtupleManager();
virtual void CreateNtuplesFromBooking(
const std::vector<G4NtupleBooking*>& ntupleBookings) final;
virtual void
CreateNtuplesFromBooking(const std::vector<G4NtupleBooking*>& ntupleBookings) final;
// Methods from the templated base class
virtual G4bool Merge() final;
private:
private:
// MPI
G4RootFile* GetNtupleFile(G4int id);
G4RootFile* GetNtupleFile(G4int id);
G4bool Send(G4int id, RootNtupleDescription* ntupleDescription);
G4bool InitializeRanks();
G4bool WaitBuffer();
tools::impi* fImpi;
std::vector<G4int> fSlaveRanks;
tools::impi* fImpi;
std::vector<G4int> fSlaveRanks;
G4int fMainRank;
};
};
#endif
@@ -33,35 +33,35 @@
#ifndef G4RootMpiPNtupleDescription_h
#define G4RootMpiPNtupleDescription_h 1
#include "globals.hh"
#include "G4TNtupleDescription.hh"
#include "G4RootFileDef.hh"
#include "tools/ntuple_booking"
#include "tools/impi"
#include "tools/ntuple_booking"
#include "tools/wroot/impi_ntuple"
#include "tools/wroot/ntuple"
namespace tools {
namespace wroot {
#include "G4RootFileDef.hh"
#include "G4TNtupleDescription.hh"
#include "globals.hh"
namespace tools
{
namespace wroot
{
class branch;
class base_pntuple;
}
}
} // namespace wroot
} // namespace tools
using RootNtupleDescription = G4TNtupleDescription<tools::wroot::ntuple, G4RootFile>;
class G4RootMpiPNtupleDescription
{
public:
G4RootMpiPNtupleDescription(G4NtupleBooking* g4NtupleBooking)
: fDescription(g4NtupleBooking) {}
G4RootMpiPNtupleDescription(G4NtupleBooking* g4NtupleBooking) : fDescription(g4NtupleBooking) {}
~G4RootMpiPNtupleDescription()
{
if ( fDescription.GetIsNtupleOwner() ) delete fNtuple;
}
{
if (fDescription.GetIsNtupleOwner()) delete fNtuple;
}
// Set methods
void SetNtuple(tools::wroot::impi_ntuple* intuple);
@@ -79,53 +79,64 @@ class G4RootMpiPNtupleDescription
private:
RootNtupleDescription fDescription;
tools::wroot::impi_ntuple* fNtuple { nullptr };
tools::wroot::base_pntuple* fBasePNtuple { nullptr };
tools::wroot::impi_ntuple* fNtuple{nullptr};
tools::wroot::base_pntuple* fBasePNtuple{nullptr};
std::vector<tools::wroot::branch*> fMainBranches;
G4int fMainNtupleRank { 0 };
tools::impi* fImpi { nullptr };
G4int fMainNtupleRank{0};
tools::impi* fImpi{nullptr};
};
// inline function
inline void G4RootMpiPNtupleDescription::SetNtuple(
tools::wroot::impi_ntuple* intuple)
{ fNtuple = intuple; }
inline void G4RootMpiPNtupleDescription::SetNtuple(tools::wroot::impi_ntuple* intuple)
{
fNtuple = intuple;
}
inline void G4RootMpiPNtupleDescription::SetBasePNtuple(
tools::wroot::base_pntuple* basePNtuple)
{ fBasePNtuple = basePNtuple; }
inline void G4RootMpiPNtupleDescription::SetBasePNtuple(tools::wroot::base_pntuple* basePNtuple)
{
fBasePNtuple = basePNtuple;
}
inline void G4RootMpiPNtupleDescription::SetMainNtupleRank(G4int value)
{ fMainNtupleRank = value; }
{
fMainNtupleRank = value;
}
inline void G4RootMpiPNtupleDescription::SetImpi(tools::impi* value)
{ fImpi = value; }
{
fImpi = value;
}
inline void G4RootMpiPNtupleDescription::Reset()
{
if ( fDescription.GetIsNtupleOwner() ) delete fNtuple;
if (fDescription.GetIsNtupleOwner()) delete fNtuple;
fNtuple = nullptr;
}
inline RootNtupleDescription&
G4RootMpiPNtupleDescription::GetDescription()
{ return fDescription; }
inline RootNtupleDescription& G4RootMpiPNtupleDescription::GetDescription()
{
return fDescription;
}
inline tools::wroot::impi_ntuple*
G4RootMpiPNtupleDescription::GetNtuple() const
{ return fNtuple; }
inline tools::wroot::impi_ntuple* G4RootMpiPNtupleDescription::GetNtuple() const
{
return fNtuple;
}
inline tools::wroot::base_pntuple*
G4RootMpiPNtupleDescription::GetBasePNtuple() const
{ return fBasePNtuple; }
inline tools::wroot::base_pntuple* G4RootMpiPNtupleDescription::GetBasePNtuple() const
{
return fBasePNtuple;
}
inline std::vector<tools::wroot::branch*>&
G4RootMpiPNtupleDescription::GetMainBranches()
{ return fMainBranches; }
inline std::vector<tools::wroot::branch*>& G4RootMpiPNtupleDescription::GetMainBranches()
{
return fMainBranches;
}
inline G4int
G4RootMpiPNtupleDescription::GetMainNtupleRank() const
{ return fMainNtupleRank; }
inline G4int G4RootMpiPNtupleDescription::GetMainNtupleRank() const
{
return fMainNtupleRank;
}
#endif
#endif
@@ -25,7 +25,7 @@
//
// Class for Root MPI pntuple management.
// The class handles ntuples on the processing MPI ranks when MPI ntuple merging
// The class handles ntuples on the processing MPI ranks when MPI ntuple merging
// is activated.
// This class is temporarily provided with g4mpi,
// it will be integrated in Geant4 analysis category in future.
@@ -35,36 +35,38 @@
#ifndef G4RootMpiPNtupleManager_h
#define G4RootMpiPNtupleManager_h 1
#include "G4BaseNtupleManager.hh"
#include "G4RootMpiPNtupleDescription.hh"
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "globals.hh"
#include "tools/wroot/base_pntuple"
#include <vector>
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "G4BaseNtupleManager.hh"
#include "G4RootMpiPNtupleDescription.hh"
#include "globals.hh"
#include <string_view>
#include <vector>
using std::to_string;
class G4RootFileManager;
namespace tools {
namespace wroot {
namespace tools
{
namespace wroot
{
class file;
class directory;
class impi_ntuple;
}
}
} // namespace wroot
} // namespace tools
class G4RootMpiPNtupleManager : public G4BaseNtupleManager
class G4RootMpiPNtupleManager : public G4BaseNtupleManager
{
friend class G4RootMpiNtupleFileManager;
friend class G4RootMpiNtupleFileManager;
public:
G4RootMpiPNtupleManager(const G4AnalysisManagerState& state,
tools::impi* impi, G4int mpiRank, G4int destinationRank);
G4RootMpiPNtupleManager(const G4AnalysisManagerState& state, tools::impi* impi, G4int mpiRank,
G4int destinationRank);
~G4RootMpiPNtupleManager();
private:
@@ -81,18 +83,17 @@ class G4RootMpiPNtupleManager : public G4BaseNtupleManager
virtual G4int CreateNtuple(G4NtupleBooking* booking) final;
// Methods to fill ntuples
// Methods for ntuple with id = FirstNtupleId (from base class)
using G4BaseNtupleManager::FillNtupleIColumn;
using G4BaseNtupleManager::FillNtupleFColumn;
using G4BaseNtupleManager::FillNtupleDColumn;
using G4BaseNtupleManager::FillNtupleSColumn;
// Methods for ntuple with id = FirstNtupleId (from base class)
using G4BaseNtupleManager::AddNtupleRow;
// Methods for ntuple with id > FirstNtupleId (when more ntuples exist)
using G4BaseNtupleManager::FillNtupleDColumn;
using G4BaseNtupleManager::FillNtupleFColumn;
using G4BaseNtupleManager::FillNtupleIColumn;
using G4BaseNtupleManager::FillNtupleSColumn;
// Methods for ntuple with id > FirstNtupleId (when more ntuples exist)
virtual G4bool FillNtupleIColumn(G4int ntupleId, G4int columnId, G4int value) final;
virtual G4bool FillNtupleFColumn(G4int ntupleId, G4int columnId, G4float value) final;
virtual G4bool FillNtupleDColumn(G4int ntupleId, G4int columnId, G4double value) final;
virtual G4bool FillNtupleSColumn(G4int ntupleId, G4int columnId,
const G4String& value) final;
virtual G4bool FillNtupleSColumn(G4int ntupleId, G4int columnId, const G4String& value) final;
virtual G4bool AddNtupleRow(G4int ntupleId) final;
virtual G4bool Merge() final;
@@ -105,9 +106,9 @@ class G4RootMpiPNtupleManager : public G4BaseNtupleManager
// Activation option
//
virtual void SetActivation(G4bool activation) final;
virtual void SetActivation(G4int ntupleId, G4bool activation) final;
virtual G4bool GetActivation(G4int ntupleId) const final;
virtual void SetActivation(G4bool activation) final;
virtual void SetActivation(G4int ntupleId, G4bool activation) final;
virtual G4bool GetActivation(G4int ntupleId) const final;
// New cycle option
void SetNewCycle(G4bool value) final;
@@ -117,142 +118,134 @@ class G4RootMpiPNtupleManager : public G4BaseNtupleManager
virtual G4int GetNofNtuples() const final;
private:
G4RootMpiPNtupleDescription*
GetNtupleDescriptionInFunction(G4int id, G4String function, G4bool warn = true) const;
tools::wroot::base_pntuple*
GetNtupleInFunction(G4int id, G4String function, G4bool warn = true) const;
G4RootMpiPNtupleDescription* GetNtupleDescriptionInFunction(G4int id, G4String function,
G4bool warn = true) const;
tools::wroot::base_pntuple* GetNtupleInFunction(G4int id, G4String function,
G4bool warn = true) const;
template <typename T>
template<typename T>
G4bool FillNtupleTColumn(G4int ntupleId, G4int columnId, const T& value);
// Static data members
static constexpr std::string_view fkClass { "G4RootMpiPNtupleManager" };
static constexpr std::string_view fkClass{"G4RootMpiPNtupleManager"};
// Data members
// G4RootMpiMainNtupleManager* fMpiMainNtupleManager;
std::shared_ptr<G4RootFileManager> fFileManager;
std::vector<G4RootMpiPNtupleDescription*> fNtupleDescriptionVector;
std::vector<tools::wroot::impi_ntuple*> fNtupleVector;
tools::impi* fImpi;
G4int fMpiRank;
G4int fDestinationRank;
G4bool fNewCycle { false };
tools::impi* fImpi;
G4int fMpiRank;
G4int fDestinationRank;
G4bool fNewCycle{false};
};
// inline functions
inline void
G4RootMpiPNtupleManager::SetFileManager(std::shared_ptr<G4RootFileManager> fileManager)
{ fFileManager = fileManager; }
//_____________________________________________________________________________
template <>
inline G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(
G4int ntupleId, G4int columnId, const std::string& value)
inline void G4RootMpiPNtupleManager::SetFileManager(std::shared_ptr<G4RootFileManager> fileManager)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
if ( IsVerbose(G4Analysis::kVL4) ) {
Message(G4Analysis::kVL4, "fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) + " columnId " + to_string(columnId) +
" value " + G4Analysis::ToString(value));
}
auto ntuple = GetNtupleInFunction(ntupleId, "FillNtupleTColumn");
if ( ! ntuple ) return false;
auto index = columnId - fFirstNtupleColumnId;
if ( index < 0 || index >= G4int(ntuple->columns().size()) ) {
G4ExceptionDescription description;
description << " " << "ntupleId " << ntupleId
<< " columnId " << columnId << " does not exist.";
G4Exception("G4RootNtupleManager::FillNtupleTColumn()",
"Analysis_W011", JustWarning, description);
return false;
}
auto icolumn = ntuple->columns()[index];
auto column = dynamic_cast<tools::wroot::base_pntuple::column_string* >(icolumn);
if ( ! column ) {
G4ExceptionDescription description;
description << " Column type does not match: "
<< " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
G4Exception("G4RootNtupleManager:FillNtupleColumn",
"Analysis_W011", JustWarning, description);
return false;
}
column->fill(value);
if ( IsVerbose(G4Analysis::kVL4) ) {
Message(G4Analysis::kVL4, "done fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) +
" columnId " + to_string(columnId) +
" value " + value);
}
return true;
fFileManager = fileManager;
}
//_____________________________________________________________________________
template <typename T>
G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(
G4int ntupleId, G4int columnId, const T& value)
template<>
inline G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(G4int ntupleId, G4int columnId,
const std::string& value)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
if (fState.GetIsActivation() && (!GetActivation(ntupleId))) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
if ( IsVerbose(G4Analysis::kVL4) ) {
if (IsVerbose(G4Analysis::kVL4)) {
Message(G4Analysis::kVL4, "fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) +
" columnId " + to_string(columnId) +
" value " + G4Analysis::ToString(value));
" ntupleId " + to_string(ntupleId) + " columnId " + to_string(columnId) + " value "
+ G4Analysis::ToString(value));
}
auto ntuple = GetNtupleInFunction(ntupleId, "FillNtupleTColumn");
if (!ntuple) return false;
auto index = columnId - fFirstNtupleColumnId;
if (index < 0 || index >= G4int(ntuple->columns().size())) {
G4ExceptionDescription description;
description << " "
<< "ntupleId " << ntupleId << " columnId " << columnId << " does not exist.";
G4Exception("G4RootNtupleManager::FillNtupleTColumn()", "Analysis_W011", JustWarning,
description);
return false;
}
auto icolumn = ntuple->columns()[index];
auto column = dynamic_cast<tools::wroot::base_pntuple::column_string*>(icolumn);
if (!column) {
G4ExceptionDescription description;
description << " Column type does not match: "
<< " ntupleId " << ntupleId << " columnId " << columnId << " value " << value;
G4Exception("G4RootNtupleManager:FillNtupleColumn", "Analysis_W011", JustWarning, description);
return false;
}
column->fill(value);
if (IsVerbose(G4Analysis::kVL4)) {
Message(G4Analysis::kVL4, "done fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) + " columnId " + to_string(columnId) + " value "
+ value);
}
return true;
}
//_____________________________________________________________________________
template<typename T>
G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(G4int ntupleId, G4int columnId, const T& value)
{
if (fState.GetIsActivation() && (!GetActivation(ntupleId))) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
if (IsVerbose(G4Analysis::kVL4)) {
Message(G4Analysis::kVL4, "fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) + " columnId " + to_string(columnId) + " value "
+ G4Analysis::ToString(value));
}
// get ntuple
auto ntuple = GetNtupleInFunction(ntupleId, "FillNtupleTColumn");
if ( ! ntuple ) return false;
if (!ntuple) return false;
// get generic column
auto index = columnId - fFirstNtupleColumnId;
if ( index < 0 || index >= G4int(ntuple->columns().size()) ) {
if (index < 0 || index >= G4int(ntuple->columns().size())) {
G4ExceptionDescription description;
description << " " << "ntupleId " << ntupleId
<< " columnId " << columnId << " does not exist.";
G4Exception("G4TNtupleManager::FillNtupleTColumn()",
"Analysis_W011", JustWarning, description);
description << " "
<< "ntupleId " << ntupleId << " columnId " << columnId << " does not exist.";
G4Exception("G4TNtupleManager::FillNtupleTColumn()", "Analysis_W011", JustWarning, description);
return false;
}
auto icolumn = ntuple->columns()[index];
auto icolumn = ntuple->columns()[index];
// get column and check its type
auto column = dynamic_cast<tools::wroot::base_pntuple::column<T>* >(icolumn);
if ( ! column ) {
auto column = dynamic_cast<tools::wroot::base_pntuple::column<T>*>(icolumn);
if (!column) {
G4ExceptionDescription description;
description << " Column type does not match: "
<< " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
G4Exception("G4TNtupleManager:FillNtupleTColumn",
"Analysis_W011", JustWarning, description);
<< " ntupleId " << ntupleId << " columnId " << columnId << " value " << value;
G4Exception("G4TNtupleManager:FillNtupleTColumn", "Analysis_W011", JustWarning, description);
return false;
}
}
column->fill(value);
if ( IsVerbose(G4Analysis::kVL4) ) {
if (IsVerbose(G4Analysis::kVL4)) {
Message(G4Analysis::kVL4, "done fill", "pntuple T column",
" ntupleId " + to_string(ntupleId) +
" columnId " + to_string(columnId) +
" value " + G4Analysis::ToString(value));
" ntupleId " + to_string(ntupleId) + " columnId " + to_string(columnId) + " value "
+ G4Analysis::ToString(value));
}
return true;
return true;
}
#endif
@@ -27,10 +27,11 @@
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiAnalysisManager.hh"
#include "G4AnalysisUtilities.hh"
#include "G4RootMpiNtupleFileManager.hh"
#include "G4RootMpiNtupleManager.hh"
#include "G4RootMpiPNtupleManager.hh"
#include "G4AnalysisUtilities.hh"
#include <tools/impi>
@@ -43,8 +44,7 @@ G4RootMpiAnalysisManager* G4RootMpiAnalysisManager::Instance()
}
//_____________________________________________________________________________
G4RootMpiAnalysisManager::G4RootMpiAnalysisManager(G4bool /*isMaster*/)
: G4RootAnalysisManager()
G4RootMpiAnalysisManager::G4RootMpiAnalysisManager(G4bool /*isMaster*/) : G4RootAnalysisManager()
{
fgInstance = this;
@@ -69,9 +69,8 @@ G4RootMpiAnalysisManager::~G4RootMpiAnalysisManager()
//
//_____________________________________________________________________________
void G4RootMpiAnalysisManager::SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
G4int nofNtupleFiles)
void G4RootMpiAnalysisManager::SetMpiNtupleMerging(tools::impi* impi, G4int mpiRank, G4int mpiSize,
G4int nofNtupleFiles)
{
// G4cout << "SetMpiNtupleMerging: "
// << impi << ", "
@@ -83,20 +82,20 @@ void G4RootMpiAnalysisManager::SetMpiNtupleMerging(tools::impi* impi,
->SetMpiNtupleMerging(impi, mpiRank, mpiSize, nofNtupleFiles);
}
//
//
// protected methods
//
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::OpenFileImpl(const G4String& fileName)
{
if ( fNtupleFileManager->GetMergeMode() == G4NtupleMergeMode::kNone ) {
if (fNtupleFileManager->GetMergeMode() == G4NtupleMergeMode::kNone) {
return G4ToolsAnalysisManager::OpenFileImpl(fileName);
}
// Create ntuple manager(s)
// and set it to base class which takes then their ownership
if ( ! fVNtupleManager ) {
if (!fVNtupleManager) {
SetNtupleManager(fNtupleFileManager->CreateNtupleManager());
}
@@ -110,12 +109,11 @@ G4bool G4RootMpiAnalysisManager::OpenFileImpl(const G4String& fileName)
result &= fNtupleFileManager->ActionAtOpenFile(fFileManager->GetFullFileName());
return result;
}
}
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::WriteImpl()
G4bool G4RootMpiAnalysisManager::WriteImpl()
{
auto result = true;
// Call base class method
@@ -123,7 +121,7 @@ G4bool G4RootMpiAnalysisManager::WriteImpl()
// Write file also on Slave
// (skipped in base class)
if ( fNtupleFileManager->GetMergeMode() == G4NtupleMergeMode::kSlave ) {
if (fNtupleFileManager->GetMergeMode() == G4NtupleMergeMode::kSlave) {
// write all open files
result &= fFileManager->WriteFiles();
}
@@ -136,8 +134,8 @@ G4bool G4RootMpiAnalysisManager::WriteImpl()
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::CloseFileImpl(G4bool reset)
{
// Cannot call base class function, as we need to close files also
// on slave; an option in the base class can be added for this in future
// Cannot call base class function, as we need to close files also
// on slave; an option in the base class can be added for this in future
Message(kVL4, "close", "files");
@@ -150,21 +148,21 @@ G4bool G4RootMpiAnalysisManager::CloseFileImpl(G4bool reset)
// - the conditoon used in the base class is commented out
// if ( (fVNtupleFileManager == nullptr) ||
// (fVNtupleFileManager->GetMergeMode() != G4NtupleMergeMode::kSlave) ) {
if ( ! fVFileManager->CloseFiles() ) {
Warn("Closing files failed", fkClass, "CloseFileImpl");
result = false;
}
if (!fVFileManager->CloseFiles()) {
Warn("Closing files failed", fkClass, "CloseFileImpl");
result = false;
}
// }
// delete empty files
if ( ! fVFileManager->DeleteEmptyFiles() ) {
if (!fVFileManager->DeleteEmptyFiles()) {
Warn("Deleting empty files failed", fkClass, "CloseFileImpl");
result = false;
}
// reset histograms
if ( reset ) {
if ( ! Reset() ) {
if (reset) {
if (!Reset()) {
Warn("Resetting data failed", fkClass, "CloseFileImpl");
result = false;
}
@@ -27,9 +27,10 @@
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiNtupleFileManager.hh"
#include "G4AnalysisUtilities.hh"
#include "G4RootMpiNtupleManager.hh"
#include "G4RootMpiPNtupleManager.hh"
#include "G4AnalysisUtilities.hh"
#include <tools/impi>
@@ -38,58 +39,56 @@ using std::make_shared;
//_____________________________________________________________________________
G4RootMpiNtupleFileManager::G4RootMpiNtupleFileManager(const G4AnalysisManagerState& state)
: G4RootNtupleFileManager(state),
fImpi(nullptr),
fMpiRank(-1),
fMpiSize(0),
fMpiSlaveNtupleManager(nullptr),
fNtupleBooked(false)
: G4RootNtupleFileManager(state),
fImpi(nullptr),
fMpiRank(-1),
fMpiSize(0),
fMpiSlaveNtupleManager(nullptr),
fNtupleBooked(false)
{}
//_____________________________________________________________________________
G4RootMpiNtupleFileManager::~G4RootMpiNtupleFileManager()
{}
G4RootMpiNtupleFileManager::~G4RootMpiNtupleFileManager() {}
//
//
// private methods
//
//_____________________________________________________________________________
void G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode(
G4int nofNtupleFiles)
void G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode(G4int nofNtupleFiles)
{
Message(kVL2, "set", "mpi ntuple merging mode");
auto canMerge = true;
// Illegal situations
if ( fMpiSize < 2 ) {
if (fMpiSize < 2) {
G4ExceptionDescription description;
description
<< "Merging ntuples is not applicable on a single rank." << G4endl
<< "Setting was ignored.";
G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode()",
"Analysis_W013", JustWarning, description);
canMerge = false;
description << "Merging ntuples is not applicable on a single rank." << G4endl
<< "Setting was ignored.";
G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode()", "Analysis_W013",
JustWarning, description);
canMerge = false;
}
G4String mergingMode;
if ( ! canMerge ) {
if (!canMerge) {
fNtupleMergeMode = G4NtupleMergeMode::kNone;
mergingMode = "G4NtupleMergeMode::kNone";
mergingMode = "G4NtupleMergeMode::kNone";
}
else {
// Set the number of reduced ntuple files
// (multiple output files are not yet supported)
fNofNtupleFiles = nofNtupleFiles;
// Forced merging mode
// MPI
if ( fMpiRank >= fMpiSize ) {
if (fMpiRank >= fMpiSize) {
// the extra worker
fNtupleMergeMode = G4NtupleMergeMode::kMain;
mergingMode = "G4NtupleMergeMode::kMain";
} else {
}
else {
// processing worker
fNtupleMergeMode = G4NtupleMergeMode::kSlave;
mergingMode = "G4NtupleMergeMode::kSlave";
@@ -99,23 +98,21 @@ void G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode(
Message(kVL1, "set", "mpi ntuple merging mode", mergingMode);
}
//
//
// public methods
//
//_____________________________________________________________________________
void G4RootMpiNtupleFileManager::SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
G4int nofNtupleFiles)
void G4RootMpiNtupleFileManager::SetMpiNtupleMerging(tools::impi* impi, G4int mpiRank,
G4int mpiSize, G4int nofNtupleFiles)
{
if ( fIsInitialized ) {
G4ExceptionDescription description;
description
<< "Cannot change merging mode." << G4endl
<< "The function must be called before OpenFile().";
G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMerging",
"Analysis_W013", JustWarning, description);
return;
if (fIsInitialized) {
G4ExceptionDescription description;
description << "Cannot change merging mode." << G4endl
<< "The function must be called before OpenFile().";
G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMerging", "Analysis_W013", JustWarning,
description);
return;
}
// Save MPI merging parameters
@@ -123,7 +120,7 @@ void G4RootMpiNtupleFileManager::SetMpiNtupleMerging(tools::impi* impi,
fMpiRank = mpiRank;
fMpiSize = mpiSize;
// Set ntuple merging mode
// Set ntuple merging mode
SetMpiNtupleMergingMode(nofNtupleFiles);
}
@@ -133,20 +130,17 @@ std::shared_ptr<G4VNtupleManager> G4RootMpiNtupleFileManager::CreateNtupleManage
Message(kVL4, "create", "mpi ntuple manager");
std::shared_ptr<G4VNtupleManager> activeNtupleManager = nullptr;
switch ( fNtupleMergeMode )
{
switch (fNtupleMergeMode) {
case G4NtupleMergeMode::kNone:
fNtupleManager
= make_shared<G4RootNtupleManager>(fState, fBookingManager,
0, 0, fNtupleRowWise, fNtupleRowMode);
fNtupleManager = make_shared<G4RootNtupleManager>(fState, fBookingManager, 0, 0,
fNtupleRowWise, fNtupleRowMode);
fNtupleManager->SetFileManager(fFileManager);
activeNtupleManager = fNtupleManager;
break;
case G4NtupleMergeMode::kMain: {
fNtupleManager
= make_shared<G4RootMpiNtupleManager>(fState, fBookingManager,
fNtupleRowWise, fNtupleRowMode, fImpi, fMpiSize);
fNtupleManager = make_shared<G4RootMpiNtupleManager>(fState, fBookingManager, fNtupleRowWise,
fNtupleRowMode, fImpi, fMpiSize);
fNtupleManager->SetFileManager(fFileManager);
activeNtupleManager = fNtupleManager;
break;
@@ -154,15 +148,15 @@ std::shared_ptr<G4VNtupleManager> G4RootMpiNtupleFileManager::CreateNtupleManage
case G4NtupleMergeMode::kSlave: {
auto destinationRank = fMpiSize;
fMpiSlaveNtupleManager
= make_shared<G4RootMpiPNtupleManager>(fState, fImpi, fMpiRank, destinationRank);
fMpiSlaveNtupleManager =
make_shared<G4RootMpiPNtupleManager>(fState, fImpi, fMpiRank, destinationRank);
activeNtupleManager = fMpiSlaveNtupleManager;
break;
}
}
G4String mergeMode;
switch ( fNtupleMergeMode ) {
switch (fNtupleMergeMode) {
case G4NtupleMergeMode::kNone:
mergeMode = "";
break;
@@ -184,30 +178,26 @@ std::shared_ptr<G4VNtupleManager> G4RootMpiNtupleFileManager::CreateNtupleManage
G4bool G4RootMpiNtupleFileManager::ActionAtOpenFile(const G4String& fileName)
{
// No MPI merging, call base class
if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kNone) {
return G4RootNtupleFileManager::ActionAtOpenFile(fileName);
}
if ( ! fNtupleBooked ) {
if (!fNtupleBooked) {
G4String objectType = "analysis file";
if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kMain) {
objectType = "main analysis file";
}
Message(kVL4, "open", objectType, fileName);
if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
// Creating files is triggered from CreateNtuple
fNtupleManager->CreateNtuplesFromBooking(
fBookingManager->GetNtupleBookingVector());
if (fNtupleMergeMode == G4NtupleMergeMode::kMain) {
// Creating files is triggered from CreateNtuple
fNtupleManager->CreateNtuplesFromBooking(fBookingManager->GetNtupleBookingVector());
}
if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) {
// G4cout << "Slave: Go to create ntuples from booking" << G4endl;
// No file is open by Slave manager
fMpiSlaveNtupleManager->CreateNtuplesFromBooking(
fBookingManager->GetNtupleBookingVector());
fMpiSlaveNtupleManager->CreateNtuplesFromBooking(fBookingManager->GetNtupleBookingVector());
}
Message(kVL1, "open", objectType, fileName);
@@ -216,29 +206,29 @@ G4bool G4RootMpiNtupleFileManager::ActionAtOpenFile(const G4String& fileName)
}
return true;
}
}
//_____________________________________________________________________________
G4bool G4RootMpiNtupleFileManager::ActionAtWrite()
{
// No MPI merging, call base class
if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kNone) {
return G4RootNtupleFileManager::ActionAtWrite();
}
auto result = true;
G4String ntupleType;
if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) ntupleType = "main ntuples";
if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) ntupleType = "slave ntuples";
if (fNtupleMergeMode == G4NtupleMergeMode::kMain) ntupleType = "main ntuples";
if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) ntupleType = "slave ntuples";
Message(kVL4, "merge", ntupleType);
if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kMain) {
result &= fNtupleManager->Merge();
}
if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
}
if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) {
result &= fMpiSlaveNtupleManager->Merge();
}
@@ -249,13 +239,13 @@ G4bool G4RootMpiNtupleFileManager::ActionAtWrite()
//_____________________________________________________________________________
G4bool G4RootMpiNtupleFileManager::ActionAtCloseFile()
{
{
// No MPI merging, call base class
if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kNone) {
return G4RootNtupleFileManager::ActionAtCloseFile();
}
if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave) {
if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) {
fMpiSlaveNtupleManager->SetNewCycle(false);
return true;
}
@@ -266,22 +256,22 @@ G4bool G4RootMpiNtupleFileManager::ActionAtCloseFile()
//_____________________________________________________________________________
G4bool G4RootMpiNtupleFileManager::Reset()
{
// Reset ntuples
// Reset ntuples
// No MPI merging, call base class
if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
if (fNtupleMergeMode == G4NtupleMergeMode::kNone) {
return G4RootNtupleFileManager::Reset();
}
auto result = true;
if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
result &= fNtupleManager->Reset();
}
if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
auto result = true;
if (fNtupleMergeMode == G4NtupleMergeMode::kMain) {
result &= fNtupleManager->Reset();
}
if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) {
result &= fMpiSlaveNtupleManager->Reset();
}
}
return result;
}
@@ -27,49 +27,47 @@
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiNtupleManager.hh"
#include "G4RootMainNtupleManager.hh"
#include "G4RootFileManager.hh"
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "tools/wroot/file"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "tools/wroot/mpi_ntuple_column_wise"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "G4RootFileManager.hh"
#include "G4RootMainNtupleManager.hh"
using namespace G4Analysis;
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
//_____________________________________________________________________________
G4RootMpiNtupleManager::G4RootMpiNtupleManager(
const G4AnalysisManagerState& state,
std::shared_ptr<G4NtupleBookingManager> bookingManager,
G4bool rowWise, G4bool rowMode,
tools::impi* impi, G4int mpiSize)
: G4RootNtupleManager(state, bookingManager, 0, 0, rowWise, rowMode),
fImpi(impi),
fSlaveRanks(),
fMainRank(0)
const G4AnalysisManagerState& state, std::shared_ptr<G4NtupleBookingManager> bookingManager,
G4bool rowWise, G4bool rowMode, tools::impi* impi, G4int mpiSize)
: G4RootNtupleManager(state, bookingManager, 0, 0, rowWise, rowMode),
fImpi(impi),
fSlaveRanks(),
fMainRank(0)
{
for ( G4int rank = 0; rank < mpiSize; rank++ ) {
for (G4int rank = 0; rank < mpiSize; rank++) {
fSlaveRanks.push_back(rank);
}
fMainRank = mpiSize;
}
//_____________________________________________________________________________
G4RootMpiNtupleManager::~G4RootMpiNtupleManager()
{}
G4RootMpiNtupleManager::~G4RootMpiNtupleManager() {}
//
//
// private methods
//
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::Send(G4int id, RootNtupleDescription* ntupleDescription)
{
// Pack and send the main ntuple data to the slave ranks
// Pack and send the main ntuple data to the slave ranks
// G4cout << "Going to send main ntuple data " << G4endl;
// G4cout << "ntupleDescription: " << ntupleDescription << G4endl;
@@ -78,11 +76,12 @@ G4bool G4RootMpiNtupleManager::Send(G4int id, RootNtupleDescription* ntupleDescr
// Get ntuple
auto ntuple = ntupleDescription->GetNtuple();
// Get basket sizes
// Get basket sizes
std::vector<tools::wroot::branch*> mainBranches;
ntuple->get_branches(mainBranches);
std::vector<tools::uint32> basketSizes;
tools_vforcit(tools::wroot::branch*, mainBranches, it) {
tools_vforcit(tools::wroot::branch*, mainBranches, it)
{
basketSizes.push_back((*it)->basket_size());
}
@@ -92,57 +91,58 @@ G4bool G4RootMpiNtupleManager::Send(G4int id, RootNtupleDescription* ntupleDescr
tools::uint32 basketSize = fFileManager->GetBasketSize();
unsigned int basketEntries = fFileManager->GetBasketEntries();
for ( auto slaveRank : fSlaveRanks ) {
for (auto slaveRank : fSlaveRanks) {
// G4cout << "Going to send main ntuple data to slave rank " << slaveRank << G4endl;
fImpi->pack_reset();
if ( ! fImpi->pack(id)) {
G4cerr << "pack(id) failed." << G4endl;
return false;
}
if ( ! fImpi->bpack(fRowWise) ) {
G4cerr << "bpack(fRowWise) failed."<< G4endl;
if (!fImpi->pack(id)) {
G4cerr << "pack(id) failed." << G4endl;
return false;
}
if ( ! fImpi->bpack(ntupleFile->byte_swap())) {
G4cerr << "bpack(byte_swap) failed." << G4endl;
if (!fImpi->bpack(fRowWise)) {
G4cerr << "bpack(fRowWise) failed." << G4endl;
return false;
}
if ( ! fImpi->pack(ntupleFile->compression()) ) {
G4cerr << "pack(compression) failed." << G4endl;
return false;
if (!fImpi->bpack(ntupleFile->byte_swap())) {
G4cerr << "bpack(byte_swap) failed." << G4endl;
return false;
}
if ( ! fImpi->pack(ntupleFile->dir().seek_directory())) {
if (!fImpi->pack(ntupleFile->compression())) {
G4cerr << "pack(compression) failed." << G4endl;
return false;
}
if (!fImpi->pack(ntupleFile->dir().seek_directory())) {
// Should be used fNtupleDirectory ??
G4cerr << "pack(seek) failed." << G4endl;
return false;
}
if ( fRowWise ) {
if ( ! fImpi->pack(basketSize) ) {
if (fRowWise) {
if (!fImpi->pack(basketSize)) {
G4cerr << "pack(basketSize) failed." << G4endl;
return false;
}
} else {
if ( ! fImpi->bpack(fRowMode) ) {
}
else {
if (!fImpi->bpack(fRowMode)) {
G4cerr << "bpack(fRowMode) failed." << G4endl;
return false;
}
if ( ! fImpi->vpack(basketSizes) ) {
}
if (!fImpi->vpack(basketSizes)) {
G4cerr << "vpack(basketSizes) failed." << G4endl;
return false;
}
if ( ! fImpi->pack(basketEntries) ) {
if (!fImpi->pack(basketEntries)) {
G4cerr << "pack(basketEntries) failed." << G4endl;
return false;
}
}
}
if ( ! fImpi->send_buffer(slaveRank, kTAG_NTUPLE )) {
if (!fImpi->send_buffer(slaveRank, kTAG_NTUPLE)) {
G4cerr << "send_buffer() failed." << G4endl;
return false;
}
@@ -150,7 +150,7 @@ G4bool G4RootMpiNtupleManager::Send(G4int id, RootNtupleDescription* ntupleDescr
G4cout << "Sent ntuple description to slave on rank " << slaveRank << G4endl;
}
// G4cout << "Done: send main ntuple data " << G4endl;
return true;
}
@@ -163,59 +163,57 @@ G4bool G4RootMpiNtupleManager::InitializeRanks()
auto finalResult = true;
auto counter = 0;
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->GetActivation() ) ) continue;
for (auto ntupleDescription : fNtupleDescriptionVector) {
// Do not create ntuple if it is inactivated
if (fState.GetIsActivation() && (!ntupleDescription->GetActivation())) continue;
auto result = Send(counter++, ntupleDescription);
finalResult = finalResult && result;
}
return finalResult;
}
}
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::WaitBuffer()
{
// Receive the pntuple data from the slave ranks
// For the time being only one ntuple
// Receive the pntuple data from the slave ranks
// For the time being only one ntuple
// G4cout << "G4RootMpiNtupleManager::WaitBuffer" << G4endl;
unsigned long numberOfEndFill = 0;
G4bool verbose = IsVerbose(kVL2);
while ( true ) {
while (true) {
fImpi->pack_reset();
// loop until receiving end_fill from all ranks
// G4cout << "G4RootMpiNtupleManager::WaitBuffer entering loop" << G4endl;
int probe_src;
if ( ! fImpi->wait_buffer(fMainRank, kTAG_NTUPLE, probe_src, verbose)) {
if (!fImpi->wait_buffer(fMainRank, kTAG_NTUPLE, probe_src, verbose)) {
G4cerr << "!!! wait_buffer() failed." << std::endl;
return EXIT_FAILURE;
}
tools::uint32 protocol;
if ( ! fImpi->unpack(protocol)) {
G4cerr << "unpack(protocol) failed."<< G4endl;
if (!fImpi->unpack(protocol)) {
G4cerr << "unpack(protocol) failed." << G4endl;
return false;
}
if ( protocol == tools::wroot::mpi_protocol_basket() ) {
if (protocol == tools::wroot::mpi_protocol_basket()) {
// G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_basket" << G4endl;
// get ntuple Id
tools::uint32 ntupleId;
if ( ! fImpi->unpack(ntupleId) ) {
G4cerr << "unpack(ntuple_id) failed."<< std::endl;
if (!fImpi->unpack(ntupleId)) {
G4cerr << "unpack(ntuple_id) failed." << std::endl;
return false;
}
if ( ntupleId >= fNtupleVector.size() ) {
if (ntupleId >= fNtupleVector.size()) {
std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
return false;
}
@@ -224,24 +222,24 @@ G4bool G4RootMpiNtupleManager::WaitBuffer()
auto mainNtuple = fNtupleVector[ntupleId];
// add basket to main ntuple
if ( ! mainNtuple->mpi_add_basket(*fImpi)) {
std::cerr << "mainNtuple->mpi_add_basket() failed." << std::endl;
return EXIT_FAILURE;
if (!mainNtuple->mpi_add_basket(*fImpi)) {
std::cerr << "mainNtuple->mpi_add_basket() failed." << std::endl;
return EXIT_FAILURE;
}
}
else if ( protocol == tools::wroot::mpi_protocol_baskets() ) {
//column_wise and row_mode only.
}
else if (protocol == tools::wroot::mpi_protocol_baskets()) {
// column_wise and row_mode only.
// G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_baskets" << G4endl;
// get ntuple Id
tools::uint32 ntupleId;
if ( ! fImpi->unpack(ntupleId) ) {
G4cerr << "unpack(ntuple_id) failed."<< std::endl;
if (!fImpi->unpack(ntupleId)) {
G4cerr << "unpack(ntuple_id) failed." << std::endl;
return false;
}
if ( ntupleId >= fNtupleVector.size() ) {
if (ntupleId >= fNtupleVector.size()) {
std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
return false;
}
@@ -250,40 +248,39 @@ G4bool G4RootMpiNtupleManager::WaitBuffer()
auto mainNtuple = fNtupleVector[ntupleId];
// add basket to main ntuple
if ( ! mainNtuple->mpi_add_baskets(*fImpi)) {
std::cerr << "mainNtuple->mpi_add_baskets() failed." << std::endl;
return EXIT_FAILURE;
if (!mainNtuple->mpi_add_baskets(*fImpi)) {
std::cerr << "mainNtuple->mpi_add_baskets() failed." << std::endl;
return EXIT_FAILURE;
}
}
else if ( protocol==tools::wroot::mpi_protocol_end_fill() ) {
}
else if (protocol == tools::wroot::mpi_protocol_end_fill()) {
// G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_end_fill" << G4endl;
// get ntuple Id
tools::uint32 ntupleId;
if ( ! fImpi->unpack(ntupleId) ) {
G4cerr << "unpack(ntuple_id) failed."<< std::endl;
if (!fImpi->unpack(ntupleId)) {
G4cerr << "unpack(ntuple_id) failed." << std::endl;
return false;
}
if ( ntupleId >= fNtupleVector.size() ) {
if (ntupleId >= fNtupleVector.size()) {
std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
return false;
}
// Main ntuple
auto mainNtuple = fNtupleVector[ntupleId];
// end_fill in main ntuple
if ( ! mainNtuple->mpi_end_fill(*fImpi) ) {
G4cerr << "main_ntuple->mpi_end_fill() failed." << std::endl;
if (!mainNtuple->mpi_end_fill(*fImpi)) {
G4cerr << "main_ntuple->mpi_end_fill() failed." << std::endl;
return false;
}
numberOfEndFill++;
if ( numberOfEndFill == fSlaveRanks.size() ) break;
}
if (numberOfEndFill == fSlaveRanks.size()) break;
}
else {
G4cerr << "unknown protocol " << protocol << G4endl;
return false;
@@ -293,30 +290,28 @@ G4bool G4RootMpiNtupleManager::WaitBuffer()
return true;
}
//
//
// public methods
//
//_____________________________________________________________________________
void G4RootMpiNtupleManager::CreateNtuplesFromBooking(
const std::vector<G4NtupleBooking*>& ntupleBookings)
const std::vector<G4NtupleBooking*>& ntupleBookings)
{
// G4cout << "G4RootMpiNtupleManager::CreateNtuplesFromBooking()" << G4endl;
// Call base class method
G4TNtupleManager<tools::wroot::ntuple,G4RootFile>::CreateNtuplesFromBooking(
ntupleBookings);
G4TNtupleManager<tools::wroot::ntuple, G4RootFile>::CreateNtuplesFromBooking(ntupleBookings);
// Initialize ranks
if ( ! InitializeRanks() ) {
if (!InitializeRanks()) {
G4cerr << "InitializeRanks failed." << G4endl;
}
// Go to wait buffer mode
if ( ! WaitBuffer() ) {
if (!WaitBuffer()) {
G4cerr << "WaitBuffer failed." << G4endl;
}
}
}
//_____________________________________________________________________________
@@ -326,10 +321,9 @@ G4bool G4RootMpiNtupleManager::Merge()
auto finalResult = true;
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->GetActivation() ) ) continue;
for (auto ntupleDescription : fNtupleDescriptionVector) {
// Do not create ntuple if it is inactivated
if (fState.GetIsActivation() && (!ntupleDescription->GetActivation())) continue;
// G4cout << "Go to call merge_number_of_entries" << G4endl;
ntupleDescription->GetNtuple()->merge_number_of_entries();
@@ -27,18 +27,20 @@
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiPNtupleManager.hh"
#include "G4RootFileManager.hh"
#include "G4AnalysisUtilities.hh"
#include "tools/wroot/file"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "tools/wroot/mpi_ntuple_column_wise"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "G4AnalysisUtilities.hh"
#include "G4RootFileManager.hh"
using namespace G4Analysis;
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
namespace {
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
namespace
{
//_____________________________________________________________________________
void NotExistException(const G4String& what, G4int id, const G4String& functionName)
@@ -50,26 +52,25 @@ void NotExistException(const G4String& what, G4int id, const G4String& functionN
G4Exception(inFunction, "Analysis_W011", JustWarning, description);
}
}
} // namespace
//_____________________________________________________________________________
G4RootMpiPNtupleManager::G4RootMpiPNtupleManager(
const G4AnalysisManagerState& state,
tools::impi* impi, G4int mpiRank, G4int destinationRank)
: G4BaseNtupleManager(state),
fNtupleVector(),
fImpi(impi),
fMpiRank(mpiRank),
fDestinationRank(destinationRank)
{
}
G4RootMpiPNtupleManager::G4RootMpiPNtupleManager(const G4AnalysisManagerState& state,
tools::impi* impi, G4int mpiRank,
G4int destinationRank)
: G4BaseNtupleManager(state),
fNtupleVector(),
fImpi(impi),
fMpiRank(mpiRank),
fDestinationRank(destinationRank)
{}
//_____________________________________________________________________________
G4RootMpiPNtupleManager::~G4RootMpiPNtupleManager()
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
delete ntupleDescription;
}
}
}
//
@@ -77,34 +78,34 @@ G4RootMpiPNtupleManager::~G4RootMpiPNtupleManager()
//
//_____________________________________________________________________________
G4RootMpiPNtupleDescription*
G4RootMpiPNtupleManager::GetNtupleDescriptionInFunction(
G4int id, G4String functionName, G4bool warn) const
{
G4RootMpiPNtupleDescription*
G4RootMpiPNtupleManager::GetNtupleDescriptionInFunction(G4int id, G4String functionName,
G4bool warn) const
{
auto index = id - fFirstId;
if ( index < 0 || index >= G4int(fNtupleDescriptionVector.size()) ) {
if ( warn) {
if (index < 0 || index >= G4int(fNtupleDescriptionVector.size())) {
if (warn) {
NotExistException("ntuple description", id, functionName);
}
return nullptr;
return nullptr;
}
return fNtupleDescriptionVector[index];
}
//_____________________________________________________________________________
tools::wroot::base_pntuple* G4RootMpiPNtupleManager::GetNtupleInFunction(
G4int id, G4String functionName, G4bool warn) const
{
tools::wroot::base_pntuple*
G4RootMpiPNtupleManager::GetNtupleInFunction(G4int id, G4String functionName, G4bool warn) const
{
auto ntupleDescription = GetNtupleDescriptionInFunction(id, functionName);
if ( ! ntupleDescription ) return nullptr;
if (!ntupleDescription) return nullptr;
if ( ! ntupleDescription->GetBasePNtuple() ) {
if ( warn ) {
if (!ntupleDescription->GetBasePNtuple()) {
if (warn) {
NotExistException("ntuple", id, functionName);
}
return nullptr;
}
}
return ntupleDescription->GetBasePNtuple();
}
@@ -116,7 +117,7 @@ tools::wroot::base_pntuple* G4RootMpiPNtupleManager::GetNtupleInFunction(
void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDescription)
{
Message(kVL4, "create from booking", "mpi pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
ntupleDescription->GetDescription().GetNtupleBooking().name());
// Wait for the ntuple data from main
@@ -125,8 +126,8 @@ void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDe
G4cout << "Go to wait_buffer from " << fDestinationRank << G4endl;
fImpi->pack_reset();
int probe_src;
if ( ! fImpi->wait_buffer(fMpiRank, fDestinationRank, kTAG_NTUPLE, probe_src, verbose)) {
G4cerr << "G4RootMpiPNtupleManager::CreateNtuple: wait_buffer() failed."<< G4endl;
if (!fImpi->wait_buffer(fMpiRank, fDestinationRank, kTAG_NTUPLE, probe_src, verbose)) {
G4cerr << "G4RootMpiPNtupleManager::CreateNtuple: wait_buffer() failed." << G4endl;
return;
}
G4cout << "After wait_buffer with " << fImpi << G4endl;
@@ -141,51 +142,52 @@ void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDe
std::vector<tools::uint32> basketSizes;
unsigned int basketEntries;
if ( ! fImpi->unpack(mainNtupleId) ) {
G4cerr << "bunpack(byteSwap) failed."<< G4endl;
if (!fImpi->unpack(mainNtupleId)) {
G4cerr << "bunpack(byteSwap) failed." << G4endl;
return;
}
// G4cout << "unpack 1" << G4endl;
if ( ! fImpi->bunpack(rowWise) ) {
G4cerr << "bunpack(rowWise) failed."<< G4endl;
if (!fImpi->bunpack(rowWise)) {
G4cerr << "bunpack(rowWise) failed." << G4endl;
return;
}
// G4cout << "unpack 1/2" << G4endl;
if ( ! fImpi->bunpack(byteSwap) ) {
G4cerr << "bunpack(byteSwap) failed."<< G4endl;
if (!fImpi->bunpack(byteSwap)) {
G4cerr << "bunpack(byteSwap) failed." << G4endl;
return;
}
// G4cout << "unpack 2" << G4endl;
if ( ! fImpi->unpack(compression) ) {
G4cerr << "unpack(compression) failed."<< G4endl;
if (!fImpi->unpack(compression)) {
G4cerr << "unpack(compression) failed." << G4endl;
return;
}
// G4cout << "unpack 3" << G4endl;
if ( ! fImpi->unpack(seekDirectory) ) {
G4cerr << "unpack(seek) failed."<< G4endl;
if (!fImpi->unpack(seekDirectory)) {
G4cerr << "unpack(seek) failed." << G4endl;
return;
}
// G4cout << "unpack 4" << G4endl;
if (rowWise) {
if ( ! fImpi->unpack(basketSize) ) {
G4cerr << "unpack(basketSize) failed."<< G4endl;
if (!fImpi->unpack(basketSize)) {
G4cerr << "unpack(basketSize) failed." << G4endl;
return;
}
} else {
if ( ! fImpi->bunpack(rowMode) ) {
}
else {
if (!fImpi->bunpack(rowMode)) {
G4cerr << "bpack(rowMode) failed." << G4endl;
return;
}
if ( ! fImpi->vunpack(basketSizes) ) {
G4cerr << "vunpack(basketSizes) failed."<< G4endl;
}
if (!fImpi->vunpack(basketSizes)) {
G4cerr << "vunpack(basketSizes) failed." << G4endl;
return;
}
if( ! fImpi->unpack(basketEntries) ) {
if (!fImpi->unpack(basketEntries)) {
G4cerr << "unpack(basketEntries) failed." << G4endl;
return;
}
@@ -194,7 +196,7 @@ void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDe
// G4cout << "rank = " << fMpiRank
// << ", verbose = " << verbose
// << ", mainNtupleId = " << mainNtupleId
// << ", mainNtupleId = " << mainNtupleId
// << ", byteSwap = " << byteSwap
// << ", compression = " << compression
// << ", seekDirectory = " << seekDirectory
@@ -202,140 +204,133 @@ void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDe
// << G4endl;
// Create MPI pntuple
if ( rowWise ) {
tools::wroot::mpi_ntuple_row_wise* ntuple
= new tools::wroot::mpi_ntuple_row_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory,
basketSize, ntupleDescription->GetDescription().GetNtupleBooking(), verbose);
if (rowWise) {
tools::wroot::mpi_ntuple_row_wise* ntuple = new tools::wroot::mpi_ntuple_row_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory, basketSize,
ntupleDescription->GetDescription().GetNtupleBooking(), verbose);
ntupleDescription->SetNtuple(ntuple);
ntupleDescription->SetBasePNtuple(ntuple);
} else {
tools::wroot::mpi_ntuple_column_wise* ntuple
= new tools::wroot::mpi_ntuple_column_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory,
basketSizes, ntupleDescription->GetDescription().GetNtupleBooking(),
rowMode, basketEntries, verbose);
}
else {
tools::wroot::mpi_ntuple_column_wise* ntuple = new tools::wroot::mpi_ntuple_column_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory, basketSizes,
ntupleDescription->GetDescription().GetNtupleBooking(), rowMode, basketEntries, verbose);
ntupleDescription->SetNtuple(ntuple);
ntupleDescription->SetBasePNtuple(ntuple);
}
ntupleDescription->GetDescription().SetIsNtupleOwner(true);
ntupleDescription->SetImpi(fImpi);
// should be not needed
// pntuple object is not deleted automatically
// should be not needed
// pntuple object is not deleted automatically
fNtupleVector.push_back(ntupleDescription->GetNtuple());
Message(kVL3, "create from booking", "mpi pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
ntupleDescription->GetDescription().GetNtupleBooking().name());
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::CreateNtuplesFromBooking(
const std::vector<G4NtupleBooking*>& ntupleBookings)
{
// Create ntuple from ntuple_booking & the buffer from main rank
// Create ntuple from ntuple_booking & the buffer from main rank
// G4cout << "Start G4RootMpiPNtupleManager::CreateNtuplesFromBooking" << G4endl;
// Do not create ntuples if NtupleVector is not empty
if ( fNtupleVector.size() ) return;
if (fNtupleVector.size()) return;
// Create pntuple descriptions from ntuple booking.
// auto g4NtupleBookings = fBookingManager->GetNtupleBookingVector();
for ( auto g4NtupleBooking : ntupleBookings ) {
for (auto g4NtupleBooking : ntupleBookings) {
auto ntupleDescription = new G4RootMpiPNtupleDescription(g4NtupleBooking);
ntupleDescription->SetMainNtupleRank(fDestinationRank);
fNtupleDescriptionVector.push_back(ntupleDescription);
fNtupleDescriptionVector.push_back(ntupleDescription);
}
// Create mpi ntuples
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
// Do not create ntuple if it is inactivated
if (fState.GetIsActivation() && (!ntupleDescription->GetDescription().GetActivation()))
continue;
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->GetDescription().GetActivation() ) ) continue;
// Do not create ntuple if it already exists
if ( ntupleDescription->GetNtuple() ) continue;
if (ntupleDescription->GetNtuple()) continue;
Message(kVL4, "create from booking", "mpi pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
ntupleDescription->GetDescription().GetNtupleBooking().name());
// create ntuple
CreateNtuple(ntupleDescription);
// finish created ntuple
// finish created ntuple
// (nothing to be done ?)
// FinishTNtuple(ntupleDescription);
Message(kVL3, "create from booking", "mpi pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
ntupleDescription->GetDescription().GetNtupleBooking().name());
}
}
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtuple(G4NtupleBooking* /*booking*/)
// const G4String& name, const G4String& title)
// const G4String& name, const G4String& title)
{
// Create pntuple description from g4 ntuple booking
// Nothing to be done here.
// Create pntuple description from g4 ntuple booking
// Nothing to be done here.
return G4Analysis::kInvalidId;
}
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleIColumn(
G4int ntupleId, G4int columnId, G4int value)
G4bool G4RootMpiPNtupleManager::FillNtupleIColumn(G4int ntupleId, G4int columnId, G4int value)
{
return FillNtupleTColumn<int>(ntupleId, columnId, value);
}
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleFColumn(
G4int ntupleId, G4int columnId, G4float value)
G4bool G4RootMpiPNtupleManager::FillNtupleFColumn(G4int ntupleId, G4int columnId, G4float value)
{
return FillNtupleTColumn<float>(ntupleId, columnId, value);
}
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleDColumn(
G4int ntupleId, G4int columnId, G4double value)
G4bool G4RootMpiPNtupleManager::FillNtupleDColumn(G4int ntupleId, G4int columnId, G4double value)
{
return FillNtupleTColumn<double>(ntupleId, columnId, value);
}
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleSColumn(
G4int ntupleId, G4int columnId, const G4String& value)
G4bool G4RootMpiPNtupleManager::FillNtupleSColumn(G4int ntupleId, G4int columnId,
const G4String& value)
{
return FillNtupleTColumn<std::string>(ntupleId, columnId, value);
}
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::AddNtupleRow(G4int ntupleId)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
//G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl;
return false;
}
{
if (fState.GetIsActivation() && (!GetActivation(ntupleId))) {
// G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl;
return false;
}
Message(kVL4, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "AddNtupleRow");
if ( ! ntupleDescription ) return false;
// if(!_ntuple->add_row(_impi,rank_src,tag)) {
auto result
= ntupleDescription->GetNtuple()
->add_row(*fImpi, ntupleDescription->GetMainNtupleRank(), kTAG_NTUPLE );
if (!ntupleDescription) return false;
if ( ! result ) {
// if(!_ntuple->add_row(_impi,rank_src,tag)) {
auto result = ntupleDescription->GetNtuple()->add_row(
*fImpi, ntupleDescription->GetMainNtupleRank(), kTAG_NTUPLE);
if (!result) {
G4ExceptionDescription description;
description << " " << " ntupleId " << ntupleId
<< "adding row has failed.";
G4Exception("G4RootMpiPNtupleManager::AddNtupleRow()",
"Analysis_W002", JustWarning, description);
}
description << " "
<< " ntupleId " << ntupleId << "adding row has failed.";
G4Exception("G4RootMpiPNtupleManager::AddNtupleRow()", "Analysis_W002", JustWarning,
description);
}
Message(kVL3, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
@@ -345,41 +340,40 @@ G4bool G4RootMpiPNtupleManager::AddNtupleRow(G4int ntupleId)
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::Merge()
{
// G4cout << "Start G4RootMpiPNtupleManager::Merge" << G4endl;
auto finalResult = true;
for ( auto ntupleDescription : fNtupleDescriptionVector) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
// skip inactivated ntuples
if ( ! ntupleDescription->GetDescription().GetActivation() ) continue;
if (!ntupleDescription->GetDescription().GetActivation()) continue;
// skip if ntuple was already merged and deleted
// (this happend when the main rank re-opens a new file for merged data)
if ( ! ntupleDescription->GetNtuple() ) continue;
Message(kVL4, "merge", "pntuple", ntupleDescription->GetDescription().GetNtupleBooking().name());
if (!ntupleDescription->GetNtuple()) continue;
// G4cout << "call end_fill " << fImpi
Message(kVL4, "merge", "pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
// G4cout << "call end_fill " << fImpi
// << " to rank " << ntupleDescription->GetMainNtupleRank()
// << " pntuple: " << ntupleDescription->GetNtuple() << G4endl;
auto result
= ntupleDescription->GetNtuple()
->end_fill(*fImpi, ntupleDescription->GetMainNtupleRank(), kTAG_NTUPLE);
auto result = ntupleDescription->GetNtuple()->end_fill(
*fImpi, ntupleDescription->GetMainNtupleRank(), kTAG_NTUPLE);
if ( ! result ) {
if (!result) {
G4ExceptionDescription description;
description << " " << " ntuple " << ntupleDescription->GetDescription().GetNtupleBooking().name()
description << " "
<< " ntuple " << ntupleDescription->GetDescription().GetNtupleBooking().name()
<< "end fill has failed.";
G4Exception("G4RootMpiPNtupleManager::Merge()",
"Analysis_W002", JustWarning, description);
G4Exception("G4RootMpiPNtupleManager::Merge()", "Analysis_W002", JustWarning, description);
}
delete ntupleDescription->GetNtuple();
ntupleDescription->SetNtuple(nullptr);
Message(kVL3, "merge", "pntuple", ntupleDescription->GetDescription().GetNtupleBooking().name());
Message(kVL3, "merge", "pntuple",
ntupleDescription->GetDescription().GetNtupleBooking().name());
}
return finalResult;
@@ -392,7 +386,7 @@ G4bool G4RootMpiPNtupleManager::Reset()
// we have its ownership.
// The ntuples will be recreated with new cycle or new open file.
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
ntupleDescription->GetDescription().Reset();
}
@@ -404,7 +398,7 @@ G4bool G4RootMpiPNtupleManager::Reset()
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::Clear()
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
delete ntupleDescription->GetNtuple();
}
@@ -417,7 +411,7 @@ void G4RootMpiPNtupleManager::Clear()
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::Delete(G4int id)
{
if ( IsVerbose(G4Analysis::kVL4) ) {
if (IsVerbose(G4Analysis::kVL4)) {
Message(G4Analysis::kVL4, "delete", "pntuple ntupleId " + to_string(id));
}
@@ -442,31 +436,28 @@ G4bool G4RootMpiPNtupleManager::Delete(G4int id)
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::SetActivation(
G4bool activation)
void G4RootMpiPNtupleManager::SetActivation(G4bool activation)
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
for (auto ntupleDescription : fNtupleDescriptionVector) {
ntupleDescription->GetDescription().SetActivation(activation);
}
}
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::SetActivation(
G4int ntupleId, G4bool activation)
void G4RootMpiPNtupleManager::SetActivation(G4int ntupleId, G4bool activation)
{
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "SetActivation");
if ( ! ntupleDescription ) return;
if (!ntupleDescription) return;
ntupleDescription->GetDescription().SetActivation(activation);
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::GetActivation(
G4int ntupleId) const
G4bool G4RootMpiPNtupleManager::GetActivation(G4int ntupleId) const
{
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "GetActivation");
if ( ! ntupleDescription ) return false;
if (!ntupleDescription) return false;
return ntupleDescription->GetDescription().GetActivation();
}
@@ -28,23 +28,25 @@
#ifndef G4MPI_BATCH_H
#define G4MPI_BATCH_H
#include <fstream>
#include "G4VMPIsession.hh"
class G4MPIbatch : public G4VMPIsession {
public:
G4MPIbatch(const G4String& fname = "", G4bool qbatch = false);
~G4MPIbatch();
#include <fstream>
virtual G4UIsession* SessionStart();
class G4MPIbatch : public G4VMPIsession
{
public:
G4MPIbatch(const G4String& fname = "", G4bool qbatch = false);
~G4MPIbatch();
protected:
std::ifstream batch_stream_;
G4bool is_opened_;
G4bool is_batch_mode_;
virtual G4UIsession* SessionStart();
// get a command from a batch script file
G4String ReadCommand();
protected:
std::ifstream batch_stream_;
G4bool is_opened_;
G4bool is_batch_mode_;
// get a command from a batch script file
G4String ReadCommand();
};
#endif
@@ -33,20 +33,20 @@
#ifndef G4MPIEXTRAWORKER_HH
#include "G4VMPIextraWorker.hh"
# include "G4VMPIextraWorker.hh"
class G4UserRunAction;
class G4MPIextraWorker : public G4VMPIextraWorker
class G4MPIextraWorker : public G4VMPIextraWorker
{
public:
G4MPIextraWorker(G4UserRunAction* runAction) : fRunAction(runAction) {}
virtual ~G4MPIextraWorker() {}
public:
G4MPIextraWorker(G4UserRunAction* runAction) : fRunAction(runAction) {}
virtual ~G4MPIextraWorker() {}
virtual void BeamOn();
private:
G4UserRunAction* fRunAction;
virtual void BeamOn();
private:
G4UserRunAction* fRunAction;
};
#endif //G4MPIEXTRAWORKER_HH
#endif // G4MPIEXTRAWORKER_HH
@@ -35,24 +35,24 @@
class G4VAnalysisManager;
class G4MPIhistoMerger {
public:
G4MPIhistoMerger();
G4MPIhistoMerger(G4VAnalysisManager* mgr,
G4int destination = G4MPImanager::kRANK_MASTER,
G4int verbosity = 0);
class G4MPIhistoMerger
{
public:
G4MPIhistoMerger();
G4MPIhistoMerger(G4VAnalysisManager* mgr, G4int destination = G4MPImanager::kRANK_MASTER,
G4int verbosity = 0);
//Get/set methods
void SetDestinationRank( G4int i ) { destination = i; }
void SetScoringManager( G4VAnalysisManager* mgr ) { manager = mgr; }
void SetVerbosity( G4int ver ) { verboseLevel = ver; }
// Get/set methods
void SetDestinationRank(G4int i) { destination = i; }
void SetScoringManager(G4VAnalysisManager* mgr) { manager = mgr; }
void SetVerbosity(G4int ver) { verboseLevel = ver; }
void Merge();
void Merge();
private:
G4VAnalysisManager* manager;
G4int destination;
G4int verboseLevel;
private:
G4VAnalysisManager* manager;
G4int destination;
G4int verboseLevel;
};
#endif //G4MPIHISTOMERGERNEW_HH
#endif // G4MPIHISTOMERGERNEW_HH
@@ -29,9 +29,11 @@
#define G4MPI_MANAGER_H
#include "mpi.h"
#include "globals.hh"
#include <fstream>
#include <pthread.h>
#include "globals.hh"
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
@@ -43,143 +45,149 @@ class G4MPIstatus;
class G4VMPIseedGenerator;
class G4VMPIextraWorker;
class G4MPImanager {
public:
// MPI master rank
enum { kRANK_MASTER = 0 };
class G4MPImanager
{
public:
// MPI master rank
enum
{
kRANK_MASTER = 0
};
enum { // MPI tag
kTAG_G4COMMAND = 100,
kTAG_G4STATUS = 200,
kTAG_G4SEED = 300,
kTAG_DATA = 1000,
kTAG_HISTO = 1001,
kTAG_RUN = 1002,
kTAG_CMDSCR = 1003,
kTAG_NTUPLE = 1004
};
enum
{ // MPI tag
kTAG_G4COMMAND = 100,
kTAG_G4STATUS = 200,
kTAG_G4SEED = 300,
kTAG_DATA = 1000,
kTAG_HISTO = 1001,
kTAG_RUN = 1002,
kTAG_CMDSCR = 1003,
kTAG_NTUPLE = 1004
};
G4MPImanager(int nof_extra_workers = 0);
G4MPImanager(int argc, char** argv, int nof_extra_workers = 0);
~G4MPImanager();
G4MPImanager(int nof_extra_workers = 0);
G4MPImanager(int argc, char** argv, int nof_extra_workers = 0);
~G4MPImanager();
static G4MPImanager* GetManager();
static G4MPImanager* GetManager();
// set/get methods
G4MPIsession* GetMPIsession() const;
// set/get methods
G4MPIsession* GetMPIsession() const;
G4int GetVerbose() const;
void SetVerbose(G4int iverbose);
G4int GetVerbose() const;
void SetVerbose(G4int iverbose);
G4int GetTotalSize() const; // get size of all ranks
G4int GetActiveSize() const; // get size of ranks wher RunBeamOn is called
G4int GetRank() const;
G4int GetTotalSize() const; // get size of all ranks
G4int GetActiveSize() const; // get size of ranks wher RunBeamOn is called
G4int GetRank() const;
G4bool IsMaster() const;
G4bool IsSlave() const;
G4bool IsExtraWorker() const;
G4bool IsMaster() const;
G4bool IsSlave() const;
G4bool IsExtraWorker() const;
G4bool IsInitMacro() const;
const G4String& GetInitFileName() const;
G4bool IsInitMacro() const;
const G4String& GetInitFileName() const;
G4bool IsBatchMode() const;
const G4String& GetMacroFileName() const;
G4bool IsBatchMode() const;
const G4String& GetMacroFileName() const;
void SetMasterWeight(G4double aweight);
G4double GetMasterWeight() const;
void SetMasterWeight(G4double aweight);
G4double GetMasterWeight() const;
void SetExtraWorker(G4VMPIextraWorker* extraWorker);
G4VMPIextraWorker* GetExtraWorker() const;
void SetExtraWorker(G4VMPIextraWorker* extraWorker);
G4VMPIextraWorker* GetExtraWorker() const;
G4VMPIseedGenerator* GetSeedGenerator() const;
G4VMPIseedGenerator* GetSeedGenerator() const;
// MPI methods
G4String BcastCommand(const G4String& command);
void ShowStatus();
void ShowSeeds();
void SetSeed(G4int inode, G4long seed);
void WaitBeamOn();
// MPI methods
G4String BcastCommand(const G4String& command);
void ShowStatus();
void ShowSeeds();
void SetSeed(G4int inode, G4long seed);
void WaitBeamOn();
// methods for MPI environment
void DistributeSeeds();
void ExecuteMacroFile(const G4String& fname, G4bool qbatch=false);
G4bool CheckThreadStatus();
void ExecuteThreadCommand(const G4String& command);
void ExecuteBeamOnThread(const G4String& command);
void JoinBeamOnThread();
// methods for MPI environment
void DistributeSeeds();
void ExecuteMacroFile(const G4String& fname, G4bool qbatch = false);
G4bool CheckThreadStatus();
void ExecuteThreadCommand(const G4String& command);
void ExecuteBeamOnThread(const G4String& command);
void JoinBeamOnThread();
void BeamOn(G4int nevent, G4bool qdivide=true);
void Print(const G4String& message);
G4int GetEventsInMaster() const {return fevents_in_master;}
G4int GetEventsInSlave() const {return fevents_in_slave;}
void BeamOn(G4int nevent, G4bool qdivide = true);
void Print(const G4String& message);
G4int GetEventsInMaster() const { return fevents_in_master; }
G4int GetEventsInSlave() const { return fevents_in_slave; }
// misc
void ShowHelp() const;
// misc
void ShowHelp() const;
const MPI::Intracomm* GetComm() const { return &COMM_G4COMMAND_; }
const MPI_Comm* GetProcessingComm() const { return &processing_comm_; }
const MPI_Comm* GetCollectingComm() const { return &collecting_comm_; }
const MPI_Comm* GetAllComm() const { return &all_comm_; }
private:
DISALLOW_COPY_AND_ASSIGN(G4MPImanager);
const MPI::Intracomm* GetComm() const { return &COMM_G4COMMAND_; }
const MPI_Comm* GetProcessingComm() const { return &processing_comm_; }
const MPI_Comm* GetCollectingComm() const { return &collecting_comm_; }
const MPI_Comm* GetAllComm() const { return &all_comm_; }
// internal use
void Initialize();
void ParseArguments(G4int argc, char** argv);
void UpdateStatus();
private:
DISALLOW_COPY_AND_ASSIGN(G4MPImanager);
static G4MPImanager* g4mpi_;
G4MPImessenger* messenger_;
G4MPIsession* session_;
G4VMPIextraWorker* extra_worker_;
// internal use
void Initialize();
void ParseArguments(G4int argc, char** argv);
void UpdateStatus();
// seed generator
G4VMPIseedGenerator* seed_generator_;
static G4MPImanager* g4mpi_;
G4MPImessenger* messenger_;
G4MPIsession* session_;
G4VMPIextraWorker* extra_worker_;
G4MPIstatus* status_; // status for each node
// seed generator
G4VMPIseedGenerator* seed_generator_;
G4int verbose_;
G4MPIstatus* status_; // status for each node
// MPI rank
G4bool is_master_;
G4bool is_slave_;
G4bool is_extra_worker_;
G4int rank_;
G4int size_; // processing comm size
G4int world_size_; // world comm size
G4int verbose_;
// MPI communicator (when no extra ranks)
MPI::Intracomm COMM_G4COMMAND_;
// MPI communicator (processing ranks - if ntuple merging)
MPI_Comm processing_comm_;
// MPI communicator (collecting ranks - if ntuple merging)
MPI_Comm collecting_comm_;
// MPI communicator (all ranks - if ntuple mergins)
MPI_Comm all_comm_;
// Interim data - need to be freed
MPI_Group world_group_;
MPI_Group processing_group_;
MPI_Group collecting_group_;
MPI_Group all_group_;
// MPI rank
G4bool is_master_;
G4bool is_slave_;
G4bool is_extra_worker_;
G4int rank_;
G4int size_; // processing comm size
G4int world_size_; // world comm size
// cout/cerr control
G4bool qfcout_;
std::ofstream fscout_;
// MPI communicator (when no extra ranks)
MPI::Intracomm COMM_G4COMMAND_;
// MPI communicator (processing ranks - if ntuple merging)
MPI_Comm processing_comm_;
// MPI communicator (collecting ranks - if ntuple merging)
MPI_Comm collecting_comm_;
// MPI communicator (all ranks - if ntuple mergins)
MPI_Comm all_comm_;
// Interim data - need to be freed
MPI_Group world_group_;
MPI_Group processing_group_;
MPI_Group collecting_group_;
MPI_Group all_group_;
// init/macro file
G4bool qinitmacro_;
G4String init_file_name_;
G4bool qbatchmode_;
G4String macro_file_name_;
// cout/cerr control
G4bool qfcout_;
std::ofstream fscout_;
// for beamOn
pthread_t thread_id_;
G4int fevents_in_master = 0;
G4int fevents_in_slave = 0;
// init/macro file
G4bool qinitmacro_;
G4String init_file_name_;
G4bool qbatchmode_;
G4String macro_file_name_;
// parallel parameters
G4double master_weight_;
G4int nof_extra_workers_;
// for beamOn
pthread_t thread_id_;
G4int fevents_in_master = 0;
G4int fevents_in_slave = 0;
// parallel parameters
G4double master_weight_;
G4int nof_extra_workers_;
};
// ====================================================================
@@ -196,8 +204,8 @@ inline G4int G4MPImanager::GetVerbose() const
inline void G4MPImanager::SetVerbose(G4int iverbose)
{
G4int lv = iverbose;
if( iverbose > 1 ) lv = 1;
if( iverbose < 0 ) lv = 0;
if (iverbose > 1) lv = 1;
if (iverbose < 0) lv = 0;
verbose_ = lv;
return;
@@ -236,13 +244,11 @@ inline G4bool G4MPImanager::IsExtraWorker() const
inline G4bool G4MPImanager::IsInitMacro() const
{
return qinitmacro_;
}
inline const G4String& G4MPImanager::GetInitFileName() const
{
return init_file_name_;
}
inline G4bool G4MPImanager::IsBatchMode() const
@@ -259,8 +265,8 @@ inline void G4MPImanager::SetMasterWeight(G4double aweight)
{
master_weight_ = aweight;
if( aweight < 0. ) master_weight_ = 0.;
if( aweight > 1. ) master_weight_ = 1.;
if (aweight < 0.) master_weight_ = 0.;
if (aweight > 1.) master_weight_ = 1.;
}
inline G4double G4MPImanager::GetMasterWeight() const
@@ -42,36 +42,37 @@ class G4UIcmdWithAString;
class G4UIcmdWithADouble;
class G4UIcommand;
class G4MPImessenger : public G4UImessenger {
public:
G4MPImessenger();
~G4MPImessenger();
class G4MPImessenger : public G4UImessenger
{
public:
G4MPImessenger();
~G4MPImessenger();
virtual void SetNewValue(G4UIcommand* command, G4String newValue);
virtual G4String GetCurrentValue(G4UIcommand* command);
virtual void SetNewValue(G4UIcommand* command, G4String newValue);
virtual G4String GetCurrentValue(G4UIcommand* command);
void SetTargetObject(G4MPImanager* mpi_manager);
void SetTargetObject(G4MPImanager* mpi_manager);
private:
DISALLOW_COPY_AND_ASSIGN(G4MPImessenger);
private:
DISALLOW_COPY_AND_ASSIGN(G4MPImessenger);
G4MPImanager* g4mpi_;
G4MPImanager* g4mpi_;
// /mpi
G4UIdirectory* dir_;
// /mpi
G4UIdirectory* dir_;
G4UIcmdWithAnInteger* verbose_;
G4UIcmdWithoutParameter* status_;
G4UIcmdWithAnInteger* verbose_;
G4UIcmdWithoutParameter* status_;
G4UIcmdWithAString* execute_;
G4UIcmdWithAString* execute_;
G4UIcommand* beam_on_;
G4UIcommand* dot_beam_on_;
G4UIcmdWithADouble* master_weight_;
G4UIcommand* beam_on_;
G4UIcommand* dot_beam_on_;
G4UIcmdWithADouble* master_weight_;
G4UIcmdWithoutParameter* show_seeds_;
G4UIcmdWithAnInteger* set_master_seed_;
G4UIcommand* set_seed_;
G4UIcmdWithoutParameter* show_seeds_;
G4UIcmdWithAnInteger* set_master_seed_;
G4UIcommand* set_seed_;
};
// ====================================================================
@@ -33,23 +33,25 @@
#include "G4MPImanager.hh"
#include "G4VMPIextraWorker.hh"
namespace toolx {
namespace mpi {
class wrmpi;
}
namespace toolx
{
namespace mpi
{
class wrmpi;
}
} // namespace toolx
class G4RootMpiAnalysisManager;
class G4MPIntupleMerger
{
public:
G4MPIntupleMerger(G4int nofReducedNtupleFiles = 0,
G4bool rowWise = false, G4bool rowMode = true);
~G4MPIntupleMerger();
public:
G4MPIntupleMerger(G4int nofReducedNtupleFiles = 0, G4bool rowWise = false,
G4bool rowMode = true);
~G4MPIntupleMerger();
private:
toolx::mpi::wrmpi* fWrmpi;
private:
toolx::mpi::wrmpi* fWrmpi;
};
#endif //G4MPINTUPLEMERGER_HH
#endif // G4MPINTUPLEMERGER_HH
@@ -30,14 +30,15 @@
#include "G4VMPIseedGenerator.hh"
class G4MPIrandomSeedGenerator : public G4VMPIseedGenerator {
public:
G4MPIrandomSeedGenerator();
~G4MPIrandomSeedGenerator();
class G4MPIrandomSeedGenerator : public G4VMPIseedGenerator
{
public:
G4MPIrandomSeedGenerator();
~G4MPIrandomSeedGenerator();
protected:
G4bool CheckDoubleCount();
virtual void GenerateSeeds();
protected:
G4bool CheckDoubleCount();
virtual void GenerateSeeds();
};
#endif
@@ -26,23 +26,23 @@
#ifndef G4MPIRUNMERGER_HH_
#define G4MPIRUNMERGER_HH_
#include "G4VUserMPIrunMerger.hh"
#include "G4Run.hh"
#include "G4VUserMPIrunMerger.hh"
//MPI Merger for default G4Run class
// MPI Merger for default G4Run class
class G4MPIrunMerger : public G4VUserMPIrunMerger {
public:
G4MPIrunMerger() : G4VUserMPIrunMerger() {}
G4MPIrunMerger(const G4Run* ar,
G4int destination = G4MPImanager::kRANK_MASTER,
G4int verboose = 0 ) :
G4VUserMPIrunMerger(ar,destination,verboose) {}
protected:
void Pack() {/*nothing do to*/}
G4Run* UnPack() { return new G4Run; }
class G4MPIrunMerger : public G4VUserMPIrunMerger
{
public:
G4MPIrunMerger() : G4VUserMPIrunMerger() {}
G4MPIrunMerger(const G4Run* ar, G4int destination = G4MPImanager::kRANK_MASTER,
G4int verboose = 0)
: G4VUserMPIrunMerger(ar, destination, verboose)
{}
protected:
void Pack() { /*nothing do to*/ }
G4Run* UnPack() { return new G4Run; }
};
#endif /* G4MPIRUNMERGER_HH_ */
@@ -25,85 +25,86 @@
//
#ifndef G4MPISCORERMERGER_HH
#define G4MPISCORERMERGER_HH
#include "G4ScoringManager.hh"
#include <vector>
#include <memory>
#include <utility>
#include <mpi.h>
#include "G4MPImanager.hh"
#include "G4ScoringManager.hh"
//typedef G4THitsMap<G4double> HitMap;
#include <memory>
#include <mpi.h>
#include <utility>
#include <vector>
// typedef G4THitsMap<G4double> HitMap;
typedef G4THitsMap<G4StatDouble> HitStatDoubleMap;
// This class allows for merging over MPI two command line scorers
// via MPI
class G4MPIscorerMerger {
public:
G4MPIscorerMerger();
G4MPIscorerMerger( G4ScoringManager* mgr,
G4int destination = G4MPImanager::kRANK_MASTER,
G4int verbosity = 0 );
virtual ~G4MPIscorerMerger();
class G4MPIscorerMerger
{
public:
G4MPIscorerMerger();
G4MPIscorerMerger(G4ScoringManager* mgr, G4int destination = G4MPImanager::kRANK_MASTER,
G4int verbosity = 0);
virtual ~G4MPIscorerMerger();
//Get/set methods
void SetDestinationRank( G4int i ) { destinationRank = i; }
void SetScoringManager( G4ScoringManager* mgr ) { scoringManager = mgr; }
void SetVerbosity( G4int ver ) { verbose = ver; }
// Get/set methods
void SetDestinationRank(G4int i) { destinationRank = i; }
void SetScoringManager(G4ScoringManager* mgr) { scoringManager = mgr; }
void SetVerbosity(G4int ver) { verbose = ver; }
//Main Interface: call this method to merge all results to rank0
void Merge();
// Main Interface: call this method to merge all results to rank0
void Merge();
protected:
void SetupOutputBuffer(char* buff, G4int size, G4int position) {
outputBuffer = buff;
outputBufferSize=size;
outputBufferPosition=position;
}
void DestroyBuffer() {
delete[] outputBuffer;
outputBuffer = nullptr;
outputBufferSize=0;
outputBufferPosition=0;
ownsBuffer = false;
}
protected:
void SetupOutputBuffer(char* buff, G4int size, G4int position)
{
outputBuffer = buff;
outputBufferSize = size;
outputBufferPosition = position;
}
void DestroyBuffer()
{
delete[] outputBuffer;
outputBuffer = nullptr;
outputBufferSize = 0;
outputBufferPosition = 0;
ownsBuffer = false;
}
//! Pack all meshes into buffer
void Pack(const G4ScoringManager*);
void UnPackAndMerge(const G4ScoringManager*);
//! Pack all meshes into buffer
void Pack(const G4ScoringManager*);
void UnPackAndMerge(const G4ScoringManager*);
//! Pack a single mesh
void Pack(const G4VScoringMesh*);
void UnPackAndMerge(G4VScoringMesh* );
//! Pack a single mesh
void Pack(const G4VScoringMesh*);
void UnPackAndMerge(G4VScoringMesh*);
//! Pack a single score map
//void Pack(const HitMap*);//Used When hits are <double>
void Pack(const HitStatDoubleMap*);//Used when hits are statdouble
//HitMap* UnPackHitMap(const G4String& detName, const G4String& colName);
HitStatDoubleMap* UnPackHitStatDoubleMap(const G4String& detName, const G4String& colName);
//! Pack a single score map
// void Pack(const HitMap*);//Used When hits are <double>
void Pack(const HitStatDoubleMap*); // Used when hits are statdouble
// HitMap* UnPackHitMap(const G4String& detName, const G4String& colName);
HitStatDoubleMap* UnPackHitStatDoubleMap(const G4String& detName, const G4String& colName);
//Return size (in bytes) of the message needed to send the mesh
G4int CalculatePackSize(const G4ScoringManager*) const;
G4int CalculatePackSize(const G4VScoringMesh*) const;
//G4int CalculatePackSize(const HitMap*) const;
G4int CalculatePackSize(const HitStatDoubleMap* ) const;
// Return size (in bytes) of the message needed to send the mesh
G4int CalculatePackSize(const G4ScoringManager*) const;
G4int CalculatePackSize(const G4VScoringMesh*) const;
// G4int CalculatePackSize(const HitMap*) const;
G4int CalculatePackSize(const HitStatDoubleMap*) const;
protected:
void Send(const unsigned int destination);
void Receive(const unsigned int source);
private:
char* outputBuffer;
G4int outputBufferSize;
G4int outputBufferPosition;
long bytesSent;
G4bool ownsBuffer;
G4ScoringManager* scoringManager;
unsigned int commSize;
unsigned int destinationRank;
MPI::Intracomm comm;
G4int verbose;
protected:
void Send(const unsigned int destination);
void Receive(const unsigned int source);
private:
char* outputBuffer;
G4int outputBufferSize;
G4int outputBufferPosition;
long bytesSent;
G4bool ownsBuffer;
G4ScoringManager* scoringManager;
unsigned int commSize;
unsigned int destinationRank;
MPI::Intracomm comm;
G4int verbose;
};
#endif //G4MPISCORERMERGER_HH
#endif // G4MPISCORERMERGER_HH
@@ -30,23 +30,24 @@
#include "G4VMPIsession.hh"
class G4MPIsession : public G4VMPIsession {
public:
G4MPIsession(G4VUIshell* ashell = 0);
~G4MPIsession();
class G4MPIsession : public G4VMPIsession
{
public:
G4MPIsession(G4VUIshell* ashell = 0);
~G4MPIsession();
void SetPrompt(const G4String& prompt);
void SetShell(G4VUIshell* ashell);
void SetPrompt(const G4String& prompt);
void SetShell(G4VUIshell* ashell);
virtual G4UIsession* SessionStart();
virtual G4UIsession* SessionStart();
private:
G4VUIshell* shell_;
private:
G4VUIshell* shell_;
// get command from user prompt of the master node
G4String GetCommand(const char* msg = 0);
// get command from user prompt of the master node
G4String GetCommand(const char* msg = 0);
G4bool TryForcedTerminate();
G4bool TryForcedTerminate();
};
#endif
@@ -28,51 +28,54 @@
#ifndef G4MPI_STATUS_H
#define G4MPI_STATUS_H
#include "globals.hh"
#include "G4ApplicationState.hh"
#include "G4Timer.hh"
#include "globals.hh"
class G4Timer;
class G4MPIstatus {
public:
G4MPIstatus();
~G4MPIstatus();
class G4MPIstatus
{
public:
G4MPIstatus();
~G4MPIstatus();
// set/get functions
void SetStatus(G4int arank, G4int runid, G4int noe, G4int evtid,
G4ApplicationState state);
// set/get functions
void SetStatus(G4int arank, G4int runid, G4int noe, G4int evtid, G4ApplicationState state);
G4int GetRank() const;
G4int GetRunID() const;
G4int GetNEventToBeProcessed() const;
G4int GetEventID() const;
G4double GetCPUTime() const;
G4ApplicationState GetG4State() const;
G4int GetRank() const;
G4int GetRunID() const;
G4int GetNEventToBeProcessed() const;
G4int GetEventID() const;
G4double GetCPUTime() const;
G4ApplicationState GetG4State() const;
// for pickling
G4int SizeOf() const;
void Pack(G4int* data) const;
void UnPack(G4int* data);
// for pickling
G4int SizeOf() const;
void Pack(G4int* data) const;
void UnPack(G4int* data);
// for timer
void StartTimer();
void StopTimer();
// for timer
void StartTimer();
void StopTimer();
void Print() const;
void Print() const;
enum { kNSIZE = 10 };
enum
{
kNSIZE = 10
};
private:
G4int rank_;
G4int run_id_;
G4int nevent_to_be_processed_;
G4int event_id_;
G4double cputime_;
G4ApplicationState g4state_;
G4Timer* timer_;
private:
G4int rank_;
G4int run_id_;
G4int nevent_to_be_processed_;
G4int event_id_;
G4double cputime_;
G4ApplicationState g4state_;
G4Timer* timer_;
G4String GetStateString(G4ApplicationState astate) const;
G4String GetStateString(G4ApplicationState astate) const;
};
// ====================================================================
@@ -26,71 +26,68 @@
// Utility functions for MPI G4 interface
#ifndef G4MPIUTILS_HH
#define G4MPIUTILS_HH
#include <map>
#include <vector>
#include <functional>
#include <map>
#include <numeric>
#include <vector>
//Namespace with some utility functions for G4 MPI integration.
//Main utilities:
// G4mpi::Merge(...) : Merge results via a semi-optimized communication
// patterns between ranks. Note that this implementation
// is not topology aware. This means that MPI_Reduce and
// MPI_Gather are more performant. However if you cannot
// implement an appropriate MPI reducer or you cannot efford
// the memory overhead of Gather, this can be used instead of
// p2p communications.
namespace G4mpi {
//Simple data type representing a rank
typedef unsigned int rank_t;
//A couple of sending/receiving ranks
typedef std::pair<rank_t,rank_t> couple_t;
//This map represent, for each cycle (key) a set of communications
//pairs
typedef std::map<int,std::vector<couple_t> > commMap_t;
// Namespace with some utility functions for G4 MPI integration.
// Main utilities:
// G4mpi::Merge(...) : Merge results via a semi-optimized communication
// patterns between ranks. Note that this implementation
// is not topology aware. This means that MPI_Reduce and
// MPI_Gather are more performant. However if you cannot
// implement an appropriate MPI reducer or you cannot efford
// the memory overhead of Gather, this can be used instead of
// p2p communications.
namespace G4mpi
{
// Simple data type representing a rank
typedef unsigned int rank_t;
// A couple of sending/receiving ranks
typedef std::pair<rank_t, rank_t> couple_t;
// This map represent, for each cycle (key) a set of communications
// pairs
typedef std::map<int, std::vector<couple_t>> commMap_t;
//This function takes as input a vector of rank_t objects representing
//a communication node identified by an ID (rank:int).
//It returns a map of cycle:int -> vector<pairs<rank_t> >
//Representing a sequence of communciation cycles. At each communication cycle
//one or more p2p communications are established: in the pair the first element
//is the sender and the second element of the pair is the receiver
//At the end of the cycles all communications have been done to rank 0
//For example with 4 nodes: [0,1,2,3] we have:
// Cycle 0: (3->2),(1->0)
// Cycle 1: (2->0)
// With 5 nodes:
// Cycle 0: (4->3),(2->1)
// Cycle 1: (3->1)
// Cycle 2: (1->0)
// The algorithm can be used to implement a communication across mpi ranks
// optimizing the network trafic. Each rank (the nodes) can send/receive to another node.
// Once they have sent out the payload they become empty and non-active anymore.
commMap_t buildCommunicationMap( std::vector<rank_t>& input );
// This function takes as input a vector of rank_t objects representing
// a communication node identified by an ID (rank:int).
// It returns a map of cycle:int -> vector<pairs<rank_t> >
// Representing a sequence of communciation cycles. At each communication cycle
// one or more p2p communications are established: in the pair the first element
// is the sender and the second element of the pair is the receiver
// At the end of the cycles all communications have been done to rank 0
// For example with 4 nodes: [0,1,2,3] we have:
// Cycle 0: (3->2),(1->0)
// Cycle 1: (2->0)
// With 5 nodes:
// Cycle 0: (4->3),(2->1)
// Cycle 1: (3->1)
// Cycle 2: (1->0)
// The algorithm can be used to implement a communication across mpi ranks
// optimizing the network trafic. Each rank (the nodes) can send/receive to another node.
// Once they have sent out the payload they become empty and non-active anymore.
commMap_t buildCommunicationMap(std::vector<rank_t>& input);
//Performs merging to rank 0 using the provided sender, receiver and barrier functions.
//CommSize is the size of the communicator and myrank is the rank of the caller
//For example: assume a class UserMerger has two members Send(uint) and
// Receive(uint) and we are using a MPI::Intracomm object as
// communicator, then to use this function the ranks can:
// using std::placeholers::_1;
// std::function<void(unsigned int)> sender =
// std::bind(&Merger::Send,&mergerInst,_1);
// std::function<void(unsigned int)> receiver =
// std::bind(&Merger::Receiver,&mergerInst,_1);
// std::function<void(void)> barrier =
// std::bind(&MPI::Intracomm::Barrier,&commInst);
// G4mpi::Merge(sender,receiver,barrier,commSize,myrank);
void Merge( std::function<void(unsigned int)> senderF ,
std::function<void(unsigned int)> receiverF ,
std::function<void(void)> barrierF ,
unsigned int commSize , unsigned int myrank);
//Type representing a merging functions
typedef std::function<void(std::function<void(unsigned int)>,
std::function<void(unsigned int)>,
std::function<void(void)>,
unsigned int, unsigned int)>
mergerHandler_t;
}
// Performs merging to rank 0 using the provided sender, receiver and barrier functions.
// CommSize is the size of the communicator and myrank is the rank of the caller
// For example: assume a class UserMerger has two members Send(uint) and
// Receive(uint) and we are using a MPI::Intracomm object as
// communicator, then to use this function the ranks can:
// using std::placeholers::_1;
// std::function<void(unsigned int)> sender =
// std::bind(&Merger::Send,&mergerInst,_1);
// std::function<void(unsigned int)> receiver =
// std::bind(&Merger::Receiver,&mergerInst,_1);
// std::function<void(void)> barrier =
// std::bind(&MPI::Intracomm::Barrier,&commInst);
// G4mpi::Merge(sender,receiver,barrier,commSize,myrank);
void Merge(std::function<void(unsigned int)> senderF, std::function<void(unsigned int)> receiverF,
std::function<void(void)> barrierF, unsigned int commSize, unsigned int myrank);
// Type representing a merging functions
typedef std::function<void(std::function<void(unsigned int)>, std::function<void(unsigned int)>,
std::function<void(void)>, unsigned int, unsigned int)>
mergerHandler_t;
} // namespace G4mpi
#endif //G4MPIUTILS_HH
#endif // G4MPIUTILS_HH
@@ -30,12 +30,13 @@
#include "G4VUIshell.hh"
class G4UImpish : public G4VUIshell {
public:
G4UImpish();
~G4UImpish();
class G4UImpish : public G4VUIshell
{
public:
G4UImpish();
~G4UImpish();
virtual G4String GetCommandLineString(const char* msg = 0);
virtual G4String GetCommandLineString(const char* msg = 0);
};
#endif
@@ -30,13 +30,13 @@
#ifndef G4MVPIEXTRAWORKER_HH
class G4VMPIextraWorker {
public:
G4VMPIextraWorker() {}
virtual ~G4VMPIextraWorker() {}
class G4VMPIextraWorker
{
public:
G4VMPIextraWorker() {}
virtual ~G4VMPIextraWorker() {}
virtual void BeamOn() = 0;
virtual void BeamOn() = 0;
};
#endif //G4MPIVEXTRAWORKER_HH
#endif // G4MPIVEXTRAWORKER_HH
@@ -29,25 +29,27 @@
#define G4VMPI_SEED_GENERATOR_H
#include "globals.hh"
#include <vector>
class G4VMPIseedGenerator {
public:
G4VMPIseedGenerator();
virtual ~G4VMPIseedGenerator();
class G4VMPIseedGenerator
{
public:
G4VMPIseedGenerator();
virtual ~G4VMPIseedGenerator();
// set/get methods
void SetMasterSeed(G4long aseed); // trigger GenerateSeeds()
G4long GetMasterSeed() const;
// set/get methods
void SetMasterSeed(G4long aseed); // trigger GenerateSeeds()
G4long GetMasterSeed() const;
const std::vector<G4long>& GetSeedList() const;
const std::vector<G4long>& GetSeedList() const;
protected:
G4long master_seed_;
std::vector<G4long> seed_list_;
protected:
G4long master_seed_;
std::vector<G4long> seed_list_;
// generate seeds for MPI nodes
virtual void GenerateSeeds() = 0;
// generate seeds for MPI nodes
virtual void GenerateSeeds() = 0;
};
// ====================================================================

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