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
@@ -31,42 +31,44 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4Threading.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "G4PhysListFactory.hh"
#include "G4RunManagerFactory.hh"
#include "G4Threading.hh"
#include "G4UImanager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv) {
int main(int argc, char** argv)
{
auto* runManager = G4RunManagerFactory::CreateRunManager();
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization( pDetectorInstance );
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization(pDetectorInstance);
// Physics list factory: use the PHYSLIST environmental variable.
G4PhysListFactory factory;
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
runManager->SetUserInitialization( thePL );
runManager->SetUserInitialization( new ActionInitialization( pDetectorInstance ) );
runManager->SetUserInitialization(thePL);
runManager->SetUserInitialization(new ActionInitialization(pDetectorInstance));
runManager->Initialize();
G4UImanager* UI = G4UImanager::GetUIpointer();
if ( argc==1 ) { // Define UI session for interactive mode.
} else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
G4UImanager* UI = G4UImanager::GetUIpointer();
if (argc == 1) { // Define UI session for interactive mode.
}
else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command + fileName);
}
// job termination
delete runManager;
return 0;
// job termination
delete runManager;
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -11,7 +11,7 @@ Environment variable "G4FORCE_RUN_MANAGER_TYPE" enabled with value == Serial. Fo
**************************************************************
Geant4 version Name: geant4-11-02-patch-02 (21-June-2024)
Geant4 version Name: geant4-11-02-ref-06 (28-June-2024)
Copyright : Geant4 Collaboration
References : NIM A 506 (2003), 250-303
: IEEE-TNS 53 (2006), 270-278
@@ -201,7 +201,7 @@ eBrem: for e+ XStype:4 SubType=3
eBremSB : Emin= 0 eV Emax= 1 GeV ModifiedTsai
eBremLPM : Emin= 1 GeV Emax= 100 TeV ModifiedTsai
annihil: for e+ XStype:2 SubType=5 BuildTable=0
annihil: for e+ XStype:2 SubType=5 AtRestModel:Simple BuildTable=0
===== EM models for the G4Region DefaultRegionForTheWorld ======
eplus2gg : Emin= 0 eV Emax= 100 TeV
@@ -757,7 +757,7 @@ Min energy per nucleon for multifragmentation 200 GeV
Limit excitation energy for Fermi BreakUp 20 MeV
Level density (1/MeV) 0.075
Use simple level density model 1
Use discrete excitation energy of the residual 1
Use discrete excitation energy of the residual 0
Time limit for long lived isomeres 1 ns
Isomer production flag 1
Internal e- conversion flag 1
@@ -813,7 +813,7 @@ Index : 3 used in the geometry : Yes
Run terminated.
Run Summary
Number of events processed : 100
User=53.750000s Real=55.732532s Sys=0.020000s
User=51.080000s Real=53.726586s Sys=0.030000s
=============== Run::PrintInfo() =============== RunID = 0
@@ -827,143 +827,143 @@ Run Summary
Number of events = 100
Conversion factor: fluence from mm^-2 to cm^-2 = 100
Particle fluence in unit of cm^-2 :
case= 0 downstream all 0.000400327
case= 1 downstream electron 1.61974e-06
case= 2 downstream gamma 0.000105871
case= 3 downstream muon 0
case= 4 downstream neutrino 6.06967e-05
case= 5 downstream pion 2.39828e-06
case= 6 downstream neutron 0.000229169
case= 7 downstream proton 5.7134e-07
case= 0 downstream all 0.00049729
case= 1 downstream electron 6.28804e-07
case= 2 downstream gamma 8.94493e-05
case= 3 downstream muon 5.72179e-07
case= 4 downstream neutrino 0.000103405
case= 5 downstream pion 2.70245e-06
case= 6 downstream neutron 0.000300533
case= 7 downstream proton 0
case= 8 downstream ion 0
case= 9 downstream otherMeson 0
case= 10 downstream otherBaryon 0
case= 11 downstream below 20 MeV all 0.000317628
case= 12 downstream below 20 MeV electron 7.19645e-07
case= 13 downstream below 20 MeV gamma 0.000104368
case= 11 downstream below 20 MeV all 0.000372263
case= 12 downstream below 20 MeV electron 6.28804e-07
case= 13 downstream below 20 MeV gamma 8.94493e-05
case= 14 downstream below 20 MeV muon 0
case= 15 downstream below 20 MeV neutrino 4.98397e-06
case= 16 downstream below 20 MeV pion 0
case= 17 downstream below 20 MeV neutron 0.000207557
case= 15 downstream below 20 MeV neutrino 9.32666e-06
case= 16 downstream below 20 MeV pion 8.20331e-07
case= 17 downstream below 20 MeV neutron 0.000272038
case= 18 downstream below 20 MeV proton 0
case= 19 downstream below 20 MeV ion 0
case= 20 downstream below 20 MeV otherMeson 0
case= 21 downstream below 20 MeV otherBaryon 0
case= 22 downstream above 20 MeV all 8.26981e-05
case= 23 downstream above 20 MeV electron 9.00099e-07
case= 24 downstream above 20 MeV gamma 1.50333e-06
case= 25 downstream above 20 MeV muon 0
case= 26 downstream above 20 MeV neutrino 5.57127e-05
case= 27 downstream above 20 MeV pion 2.39828e-06
case= 28 downstream above 20 MeV neutron 2.16124e-05
case= 29 downstream above 20 MeV proton 5.7134e-07
case= 22 downstream above 20 MeV all 0.000125027
case= 23 downstream above 20 MeV electron 0
case= 24 downstream above 20 MeV gamma 0
case= 25 downstream above 20 MeV muon 5.72179e-07
case= 26 downstream above 20 MeV neutrino 9.40781e-05
case= 27 downstream above 20 MeV pion 1.88212e-06
case= 28 downstream above 20 MeV neutron 2.84943e-05
case= 29 downstream above 20 MeV proton 0
case= 30 downstream above 20 MeV ion 0
case= 31 downstream above 20 MeV otherMeson 0
case= 32 downstream above 20 MeV otherBaryon 0
case= 33 side all 0.000678759
case= 34 side electron 1.47359e-06
case= 35 side gamma 0.000129418
case= 33 side all 0.000676203
case= 34 side electron 8.08103e-07
case= 35 side gamma 0.000109726
case= 36 side muon 0
case= 37 side neutrino 0.000123799
case= 37 side neutrino 0.000164799
case= 38 side pion 0
case= 39 side neutron 0.000423817
case= 40 side proton 1.45012e-07
case= 39 side neutron 0.000400462
case= 40 side proton 1.44228e-07
case= 41 side ion 0
case= 42 side otherMeson 1.06938e-07
case= 42 side otherMeson 2.63913e-07
case= 43 side otherBaryon 0
case= 44 side below 20 MeV all 0.000531645
case= 45 side below 20 MeV electron 1.47359e-06
case= 46 side below 20 MeV gamma 0.000129418
case= 44 side below 20 MeV all 0.000500353
case= 45 side below 20 MeV electron 8.08103e-07
case= 46 side below 20 MeV gamma 0.000109621
case= 47 side below 20 MeV muon 0
case= 48 side below 20 MeV neutrino 1.23079e-05
case= 48 side below 20 MeV neutrino 1.26961e-05
case= 49 side below 20 MeV pion 0
case= 50 side below 20 MeV neutron 0.000388446
case= 50 side below 20 MeV neutron 0.000377227
case= 51 side below 20 MeV proton 0
case= 52 side below 20 MeV ion 0
case= 53 side below 20 MeV otherMeson 0
case= 54 side below 20 MeV otherBaryon 0
case= 55 side above 20 MeV all 0.000147114
case= 55 side above 20 MeV all 0.00017585
case= 56 side above 20 MeV electron 0
case= 57 side above 20 MeV gamma 0
case= 57 side above 20 MeV gamma 1.0451e-07
case= 58 side above 20 MeV muon 0
case= 59 side above 20 MeV neutrino 0.000111491
case= 59 side above 20 MeV neutrino 0.000152103
case= 60 side above 20 MeV pion 0
case= 61 side above 20 MeV neutron 3.53709e-05
case= 62 side above 20 MeV proton 1.45012e-07
case= 61 side above 20 MeV neutron 2.32343e-05
case= 62 side above 20 MeV proton 1.44228e-07
case= 63 side above 20 MeV ion 0
case= 64 side above 20 MeV otherMeson 1.06938e-07
case= 64 side above 20 MeV otherMeson 2.63913e-07
case= 65 side above 20 MeV otherBaryon 0
case= 66 upstream all 0.00526068
case= 67 upstream electron 2.33163e-05
case= 68 upstream gamma 0.00131229
case= 66 upstream all 0.00571877
case= 67 upstream electron 4.20574e-05
case= 68 upstream gamma 0.00160983
case= 69 upstream muon 0
case= 70 upstream neutrino 0.000265139
case= 71 upstream pion 5.30172e-06
case= 72 upstream neutron 0.00365215
case= 73 upstream proton 2.48272e-06
case= 74 upstream ion 0
case= 70 upstream neutrino 0.00037909
case= 71 upstream pion 8.83523e-06
case= 72 upstream neutron 0.00367594
case= 73 upstream proton 2.33017e-06
case= 74 upstream ion 6.8213e-07
case= 75 upstream otherMeson 0
case= 76 upstream otherBaryon 0
case= 77 upstream below 20 MeV all 0.00480468
case= 78 upstream below 20 MeV electron 2.2125e-05
case= 79 upstream below 20 MeV gamma 0.00130451
case= 77 upstream below 20 MeV all 0.00514525
case= 78 upstream below 20 MeV electron 3.23201e-05
case= 79 upstream below 20 MeV gamma 0.00159218
case= 80 upstream below 20 MeV muon 0
case= 81 upstream below 20 MeV neutrino 2.09278e-05
case= 81 upstream below 20 MeV neutrino 2.24726e-05
case= 82 upstream below 20 MeV pion 0
case= 83 upstream below 20 MeV neutron 0.00345712
case= 83 upstream below 20 MeV neutron 0.00349827
case= 84 upstream below 20 MeV proton 0
case= 85 upstream below 20 MeV ion 0
case= 86 upstream below 20 MeV otherMeson 0
case= 87 upstream below 20 MeV otherBaryon 0
case= 88 upstream above 20 MeV all 0.000456002
case= 89 upstream above 20 MeV electron 1.1913e-06
case= 90 upstream above 20 MeV gamma 7.77779e-06
case= 88 upstream above 20 MeV all 0.000573519
case= 89 upstream above 20 MeV electron 9.73724e-06
case= 90 upstream above 20 MeV gamma 1.76437e-05
case= 91 upstream above 20 MeV muon 0
case= 92 upstream above 20 MeV neutrino 0.000244211
case= 93 upstream above 20 MeV pion 5.30172e-06
case= 94 upstream above 20 MeV neutron 0.000195037
case= 95 upstream above 20 MeV proton 2.48272e-06
case= 96 upstream above 20 MeV ion 0
case= 92 upstream above 20 MeV neutrino 0.000356618
case= 93 upstream above 20 MeV pion 8.83523e-06
case= 94 upstream above 20 MeV neutron 0.000177673
case= 95 upstream above 20 MeV proton 2.33017e-06
case= 96 upstream above 20 MeV ion 6.8213e-07
case= 97 upstream above 20 MeV otherMeson 0
case= 98 upstream above 20 MeV otherBaryon 0
-------------------------------------------------------------
Extra information: particle production <N> <E_kin> <Sum_Ekin> [MeV]
case= 0 calorimeter all 65852.8 4.06954 267990
case= 1 calorimeter electron 48766.8 1.58539 77314.5
case= 2 calorimeter gamma 14288.1 5.29283 75624.4
case= 3 calorimeter muon 4.68 25.5183 119.426
case= 4 calorimeter neutrino 13.94 38.3338 534.373
case= 5 calorimeter pion 50.87 1218.05 61962.3
case= 6 calorimeter neutron 1057.33 19.6397 20765.6
case= 7 calorimeter proton 240.99 62.738 15119.2
case= 8 calorimeter ion 1424.29 0.932492 1328.14
case= 9 calorimeter otherMeson 4.53 2918.82 13222.3
case= 10 calorimeter otherBaryon 1.32 1515.32 2000.23
case= 11 calorimeter below 20 MeV all 64738.9 0.662399 42883
case= 12 calorimeter below 20 MeV electron 48344.7 0.44789 21653.1
case= 13 calorimeter below 20 MeV gamma 13907.7 1.21332 16874.5
case= 14 calorimeter below 20 MeV muon 4.19 4.14722 17.3768
case= 15 calorimeter below 20 MeV neutrino 1.25 14.3861 17.9826
case= 16 calorimeter below 20 MeV pion 0.84 11.3984 9.57466
case= 17 calorimeter below 20 MeV neutron 913.69 2.65531 2426.13
case= 18 calorimeter below 20 MeV proton 154.86 8.12345 1258
case= 19 calorimeter below 20 MeV ion 1411.37 0.441769 623.5
case= 20 calorimeter below 20 MeV otherMeson 0.22 6.88811 1.51538
case= 21 calorimeter below 20 MeV otherBaryon 0.09 14.3896 1.29506
case= 22 calorimeter above 20 MeV all 1113.95 202.08 225107
case= 23 calorimeter above 20 MeV electron 422.11 131.865 55661.4
case= 24 calorimeter above 20 MeV gamma 380.4 154.442 58749.9
case= 25 calorimeter above 20 MeV muon 0.49 208.263 102.049
case= 26 calorimeter above 20 MeV neutrino 12.69 40.6927 516.391
case= 27 calorimeter above 20 MeV pion 50.03 1238.31 61952.7
case= 28 calorimeter above 20 MeV neutron 143.64 127.677 18339.5
case= 29 calorimeter above 20 MeV proton 86.13 160.934 13861.2
case= 30 calorimeter above 20 MeV ion 12.92 54.5386 704.639
case= 31 calorimeter above 20 MeV otherMeson 4.31 3067.46 13220.8
case= 32 calorimeter above 20 MeV otherBaryon 1.23 1625.15 1998.93
case= 0 calorimeter all 66015 4.1131 271526
case= 1 calorimeter electron 48963.5 1.63513 80061.6
case= 2 calorimeter gamma 14389 5.44851 78398.4
case= 3 calorimeter muon 6.45 18.7028 120.633
case= 4 calorimeter neutrino 19.22 36.9023 709.262
case= 5 calorimeter pion 58.29 1086.23 63316.6
case= 6 calorimeter neutron 997.11 18.5749 18521.2
case= 7 calorimeter proton 228.79 61.7313 14123.5
case= 8 calorimeter ion 1346.71 0.899364 1211.18
case= 9 calorimeter otherMeson 4.83 2877.64 13899
case= 10 calorimeter otherBaryon 1.07 1088.9 1165.13
case= 11 calorimeter below 20 MeV all 64885.4 0.663806 43071.3
case= 12 calorimeter below 20 MeV electron 48526.7 0.450875 21879.5
case= 13 calorimeter below 20 MeV gamma 13997.5 1.21494 17006
case= 14 calorimeter below 20 MeV muon 5.96 4.17254 24.8684
case= 15 calorimeter below 20 MeV neutrino 1.51 14.6329 22.0957
case= 16 calorimeter below 20 MeV pion 1.17 12.1547 14.221
case= 17 calorimeter below 20 MeV neutron 866.33 2.6441 2290.67
case= 18 calorimeter below 20 MeV proton 150.76 8.05407 1214.23
case= 19 calorimeter below 20 MeV ion 1335.32 0.462032 616.961
case= 20 calorimeter below 20 MeV otherMeson 0.23 9.02507 2.07577
case= 21 calorimeter below 20 MeV otherBaryon 0.05 13.688 0.684401
case= 22 calorimeter above 20 MeV all 1129.53 202.257 228455
case= 23 calorimeter above 20 MeV electron 436.87 133.18 58182.2
case= 24 calorimeter above 20 MeV gamma 391.52 156.805 61392.3
case= 25 calorimeter above 20 MeV muon 0.49 195.438 95.7648
case= 26 calorimeter above 20 MeV neutrino 17.71 38.801 687.166
case= 27 calorimeter above 20 MeV pion 57.12 1108.23 63302.3
case= 28 calorimeter above 20 MeV neutron 130.78 124.106 16230.5
case= 29 calorimeter above 20 MeV proton 78.03 165.44 12909.3
case= 30 calorimeter above 20 MeV ion 11.39 52.1704 594.221
case= 31 calorimeter above 20 MeV otherMeson 4.6 3021.07 13896.9
case= 32 calorimeter above 20 MeV otherBaryon 1.02 1141.61 1164.44
=============================================================
================== Deleting memory pools ===================
Number of memory pools allocated: 13 of which, static: 0
Dynamic pools deleted: 13 / Total memory freed: 0.25 MB
Number of memory pools allocated: 11 of which, static: 0
Dynamic pools deleted: 11 / Total memory freed: 0.23 MB
============================================================
@@ -26,7 +26,7 @@
/// \file ActionInitialization.hh
/// \brief Definition of the ActionInitialization class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -40,12 +40,14 @@ class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class ActionInitialization : public G4VUserActionInitialization {
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization( const DetectorConstruction* inputDetectorConstruction = nullptr );
ActionInitialization(const DetectorConstruction* inputDetectorConstruction = nullptr);
~ActionInitialization() override = default;
void BuildForMaster() const override;
void Build() const override;
private:
const DetectorConstruction* fPtrDetectorConstruction = nullptr;
};
@@ -26,7 +26,7 @@
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -35,7 +35,7 @@
#define DetectorConstruction_H 1
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "globals.hh"
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -46,50 +46,50 @@ class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
G4VPhysicalVolume* Construct();
void ConstructSDandField();
void SetMagField( const G4double fieldValue );
void SetAbsorberMaterial( const G4String name );
void SetActiveMaterial( const G4String name );
void SetMagField(const G4double fieldValue);
void SetAbsorberMaterial(const G4String name);
void SetActiveMaterial(const G4String name);
// Use by the messenger.
inline G4Material* GetAbsorberMaterial() const;
inline G4Material* GetActiveMaterial() const;
inline void SetIsCalHomogeneous( const G4bool choice );
inline void SetIsUnitInLambda( const G4bool choice );
inline void SetAbsorberTotalLength( const G4double value );
inline void SetCalorimeterRadius( const G4double value );
inline void SetActiveLayerNumber( const G4int value );
inline void SetActiveLayerSize( const G4double value );
inline void SetIsCalHomogeneous(const G4bool choice);
inline void SetIsUnitInLambda(const G4bool choice);
inline void SetAbsorberTotalLength(const G4double value);
inline void SetCalorimeterRadius(const G4double value);
inline void SetActiveLayerNumber(const G4int value);
inline void SetActiveLayerSize(const G4double value);
// To define the calorimeter geometry.
inline void SetIsRadiusUnitInLambda( const G4bool choice );
inline void SetIsRadiusUnitInLambda(const G4bool choice);
void UpdateGeometry();
inline G4double GetCaloLength() const;
private:
void DefineMaterials();
// Define all the materials.
G4VPhysicalVolume* ConstructCalorimeter();
G4VPhysicalVolume* ConstructCalorimeter();
// To be invoked each time the geometry needs to be updated.
G4bool AreParametersOK();
// Return true if all the parameters are sensible, false otherwise.
void PrintParameters();
// Print the various parameters which define the calorimeter.
G4Material* fVacuum;
G4Material* fIron;
G4Material* fCopper;
@@ -106,58 +106,58 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
G4Material* fGraphite;
G4Material* fAbsorberMaterial;
G4Material* fActiveMaterial;
G4LogicalVolume* fExperimentalHall_log;
G4VPhysicalVolume* fExperimentalHall_phys;
// World envelope.
G4LogicalVolume* fLogicCalo;
// World envelope.
G4LogicalVolume* fLogicCalo;
G4VPhysicalVolume* fPhysiCalo;
// "Calorimeter".
G4LogicalVolume* fLogicModule;
G4LogicalVolume* fLogicModule;
G4VPhysicalVolume* fPhysiModule;
// Module of the "calorimeter".
G4LogicalVolume* fLogicAbsorber;
G4LogicalVolume* fLogicAbsorber;
G4VPhysicalVolume* fPhysiAbsorber;
// Absorber layer of the "calorimeter".
G4LogicalVolume* fLogicActive;
G4LogicalVolume* fLogicActive;
G4VPhysicalVolume* fPhysiActive;
// Active layer of the "calorimeter".
G4FieldManager* fFieldMgr;
// Pointer to the field manager.
G4UniformMagField* fUniformMagField;
G4UniformMagField* fUniformMagField;
// Pointer to the uniform magnetic field.
DetectorMessenger* fDetectorMessenger;
// Pointer to the Messenger.
G4bool fIsCalHomogeneous;
G4bool fIsCalHomogeneous;
// If false then Sampling calorimeter;
// If true then Homogeneous calorimeter.
G4bool fIsUnitInLambda;
// If false then normal unit of length to express the absorber total length.
// If true then lambda (interaction length) to express the absorber total length.
G4double fAbsorberTotalLength;
// This is the total length of the absorber material, expressed
// in unit of length (e.g. m, cm, mm) if theIsUnitInLambda is false,
// This is the total length of the absorber material, expressed
// in unit of length (e.g. m, cm, mm) if theIsUnitInLambda is false,
// otherwise in number of lambdas (interaction lengths).
// Notice that in the case of a sampling calorimeter (i.e.
// Notice that in the case of a sampling calorimeter (i.e.
// theIsCalHomogeneous is false), the active layers are not counted;
// in the case of an homogenous calorimeter, this length account
// for the overall dimension of the calorimeter.
G4double fCalorimeterRadius;
// This is the radius of the calorimeter which is a cylinder, expressed
// in unit of length (e.g. m, cm, mm) if theIsUnitInLambda is false,
// This is the radius of the calorimeter which is a cylinder, expressed
// in unit of length (e.g. m, cm, mm) if theIsUnitInLambda is false,
// otherwise in number of lambdas (interaction lengths) of the absorber.
G4int fActiveLayerNumber;
G4double fActiveLayerSize;
// Number of active layers and length of each of them (in normal unit
@@ -167,60 +167,70 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
// only a fictitious way to sample the longitudinal energy deposits,
// but they are actually made of the same absorber material, and their
// thickness is taken into account in theAbsorberTotalLength.
G4bool fIsRadiusUnitInLambda;
// If false then normal unit of length to express the radius bin size.
// If true then lambda (interaction length of the absorber) to express
// If true then lambda (interaction length of the absorber) to express
// the radius bin size.
G4double fCaloLength; // total length of the calorimeter along its (z) axis
// Scoring part
G4LogicalVolume* fLogicScoringUpDown;
G4LogicalVolume* fLogicScoringUpDown;
G4VPhysicalVolume* fPhysiScoringUpstream;
G4VPhysicalVolume* fPhysiScoringDownstream;
G4LogicalVolume* fLogicScoringSide;
G4LogicalVolume* fLogicScoringSide;
G4VPhysicalVolume* fPhysiScoringSide;
const G4double fScoringThickness = 10.0;
};
inline G4Material* DetectorConstruction::GetAbsorberMaterial() const {
inline G4Material* DetectorConstruction::GetAbsorberMaterial() const
{
return fAbsorberMaterial;
}
inline G4Material* DetectorConstruction::GetActiveMaterial() const {
inline G4Material* DetectorConstruction::GetActiveMaterial() const
{
return fActiveMaterial;
}
inline void DetectorConstruction::SetIsCalHomogeneous( const G4bool choice ) {
inline void DetectorConstruction::SetIsCalHomogeneous(const G4bool choice)
{
fIsCalHomogeneous = choice;
}
inline void DetectorConstruction::SetIsUnitInLambda( const G4bool choice ) {
inline void DetectorConstruction::SetIsUnitInLambda(const G4bool choice)
{
fIsUnitInLambda = choice;
}
inline void DetectorConstruction::SetAbsorberTotalLength( const G4double value ) {
inline void DetectorConstruction::SetAbsorberTotalLength(const G4double value)
{
fAbsorberTotalLength = value;
}
inline void DetectorConstruction::SetCalorimeterRadius( const G4double value ) {
inline void DetectorConstruction::SetCalorimeterRadius(const G4double value)
{
fCalorimeterRadius = value;
}
inline void DetectorConstruction::SetActiveLayerNumber( const G4int value ) {
inline void DetectorConstruction::SetActiveLayerNumber(const G4int value)
{
fActiveLayerNumber = value;
}
inline void DetectorConstruction::SetActiveLayerSize( const G4double value ) {
inline void DetectorConstruction::SetActiveLayerSize(const G4double value)
{
fActiveLayerSize = value;
}
inline void DetectorConstruction::SetIsRadiusUnitInLambda( const G4bool choice ) {
inline void DetectorConstruction::SetIsRadiusUnitInLambda(const G4bool choice)
{
fIsRadiusUnitInLambda = choice;
}
inline G4double DetectorConstruction::GetCaloLength() const {
inline G4double DetectorConstruction::GetCaloLength() const
{
return fCaloLength;
}
@@ -26,7 +26,7 @@
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,8 +34,8 @@
#ifndef DetectorMessenger_h
#define DetectorMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
#include "globals.hh"
class DetectorConstruction;
class G4UIdirectory;
@@ -49,19 +49,20 @@ class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorMessenger: public G4UImessenger {
class DetectorMessenger : public G4UImessenger
{
public:
DetectorMessenger( DetectorConstruction* );
DetectorMessenger(DetectorConstruction*);
~DetectorMessenger();
void SetNewValue( G4UIcommand*, G4String ) override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
G4UIcmdWithADoubleAndUnit* fFieldCommand;
G4UIcmdWithAString* fAbsorberMaterial;
G4UIcmdWithAString* fActiveMaterial;
G4UIcmdWithABool* fIsCalHomogeneous;
G4UIcmdWithABool* fIsCalHomogeneous;
G4UIcmdWithABool* fIsUnitInLambda;
G4UIcmdWithADouble* fAbsorberTotalLength;
G4UIcmdWithADouble* fCalorimeterRadius;
@@ -26,7 +26,7 @@
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,12 +42,14 @@ class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction( const DetectorConstruction* );
PrimaryGeneratorAction(const DetectorConstruction*);
~PrimaryGeneratorAction();
void GeneratePrimaries( G4Event* anEvent ) override;
void GeneratePrimaries(G4Event* anEvent) override;
void SetGunPosition() const;
private:
G4ParticleGun* fParticleGun;
const DetectorConstruction* fPointerDetectorConstruction = nullptr;
@@ -26,7 +26,7 @@
/// \file Run.hh
/// \brief Definition of the Run class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,57 +34,67 @@
#ifndef Run_h
#define Run_h 1
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include <array>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class Run : public G4Run {
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
class Run : public G4Run
{
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
public:
Run();
~Run() override = default;
void RecordEvent( const G4Event* anEvent ) override;
void RecordEvent(const G4Event* anEvent) override;
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event. In the case of multithreaded mode, it is called only for the working thread
// that handled that event.
void Merge( const G4Run* aRun ) override;
void Merge(const G4Run* aRun) override;
// This method is called automatically by the Geant4 kernel (not by the user!) only in the
// case of multithreaded mode and only for working threads.
void PrintInfo() const;
// This method is called by RunAction::EndOfRunAction : in the case of multithreaded mode,
// only the master thread calls it.
void SetPrimaryParticleId( const G4int inputValue ) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy( const G4double inputValue )
{ fPrimaryParticleEnergy = inputValue; }
void SetPrimaryParticleDirection( const G4ThreeVector &inputValue )
{ fPrimaryParticleDirection = inputValue; }
void SetAbsorberMaterialName( const G4String &inputValue )
{ fAbsorberMaterialName = inputValue; }
void SetActiveMaterialName( const G4String &inputValue ) { fActiveMaterialName = inputValue; }
void SetCubicVolumeScoringUpDown( const G4double inputValue )
{ fCubicVolumeScoringUpDown = inputValue; }
void SetCubicVolumeScoringSide( const G4double inputValue )
{ fCubicVolumeScoringSide = inputValue; }
void SetPrimaryParticleId(const G4int inputValue) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy(const G4double inputValue)
{
fPrimaryParticleEnergy = inputValue;
}
void SetPrimaryParticleDirection(const G4ThreeVector& inputValue)
{
fPrimaryParticleDirection = inputValue;
}
void SetAbsorberMaterialName(const G4String& inputValue) { fAbsorberMaterialName = inputValue; }
void SetActiveMaterialName(const G4String& inputValue) { fActiveMaterialName = inputValue; }
void SetCubicVolumeScoringUpDown(const G4double inputValue)
{
fCubicVolumeScoringUpDown = inputValue;
}
void SetCubicVolumeScoringSide(const G4double inputValue)
{
fCubicVolumeScoringSide = inputValue;
}
G4int GetPrimaryParticleId() const { return fPrimaryParticleId; }
G4double GetPrimaryParticleEnergy() const { return fPrimaryParticleEnergy; }
G4ThreeVector GetPrimaryParticleDirection() const { return fPrimaryParticleDirection; }
@@ -93,25 +103,31 @@ class Run : public G4Run {
G4double GetCubicVolumeScoringUpDown() const { return fCubicVolumeScoringUpDown; }
G4double GetCubicVolumeScoringSide() const { return fCubicVolumeScoringSide; }
void SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray );
std::array< G4double, SteppingAction::fkNumberCombinations > GetSteppingArray() const
{ return fSteppingArray; }
void
SetSteppingArray(const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray);
std::array<G4double, SteppingAction::fkNumberCombinations> GetSteppingArray() const
{
return fSteppingArray;
}
// Accessor methods useful to transfer information collected by the stepping-action
// into this Run class
void SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4long, TrackingAction::fkNumberCombinations > GetTrackingArray1() const
{ return fTrackingArray1; }
void SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4double, TrackingAction::fkNumberCombinations > GetTrackingArray2() const
{ return fTrackingArray2; }
void
SetTrackingArray1(const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4long, TrackingAction::fkNumberCombinations> GetTrackingArray1() const
{
return fTrackingArray1;
}
void
SetTrackingArray2(const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4double, TrackingAction::fkNumberCombinations> GetTrackingArray2() const
{
return fTrackingArray2;
}
// Accessor methods useful to transfer information collected by the tracking-action
// into this Run class
private:
private:
G4int fNumEvents;
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -120,9 +136,9 @@ class Run : public G4Run {
G4String fActiveMaterialName;
G4double fCubicVolumeScoringUpDown;
G4double fCubicVolumeScoringSide;
std::array< G4double, SteppingAction::fkNumberCombinations > fSteppingArray;
std::array< G4long, TrackingAction::fkNumberCombinations > fTrackingArray1;
std::array< G4double, TrackingAction::fkNumberCombinations > fTrackingArray2;
std::array<G4double, SteppingAction::fkNumberCombinations> fSteppingArray;
std::array<G4long, TrackingAction::fkNumberCombinations> fTrackingArray1;
std::array<G4double, TrackingAction::fkNumberCombinations> fTrackingArray2;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file RunAction.hh
/// \brief Definition of the RunAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,17 +42,18 @@ class TrackingAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class RunAction: public G4UserRunAction {
class RunAction : public G4UserRunAction
{
public:
RunAction( SteppingAction* steppingAction = nullptr,
TrackingAction* trackingAction = nullptr );
RunAction(SteppingAction* steppingAction = nullptr, TrackingAction* trackingAction = nullptr);
~RunAction() override = default;
void BeginOfRunAction( const G4Run* aRun ) override;
void EndOfRunAction( const G4Run* aRun ) override;
void BeginOfRunAction(const G4Run* aRun) override;
void EndOfRunAction(const G4Run* aRun) override;
G4Run* GenerateRun() override;
private:
SteppingAction* fSteppingAction;
TrackingAction* fTrackingAction;
TrackingAction* fTrackingAction;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,21 +34,23 @@
#ifndef SteppingAction_H
#define SteppingAction_H 1
#include "globals.hh"
#include "G4UserSteppingAction.hh"
#include "G4ThreeVector.hh"
#include "G4UserSteppingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class SteppingAction : public G4UserSteppingAction {
public:
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction();
~SteppingAction() override = default;
void UserSteppingAction( const G4Step* ) override;
void UserSteppingAction(const G4Step*) override;
// This is the main method where the step lengths of particles inside
// the scoring volumes are collected, and then the corresponding fluences
// are filled up in the Run object where they are stored (and then
@@ -62,7 +64,7 @@ class SteppingAction : public G4UserSteppingAction {
// This is necessary because different runs can have different primary particle
// types, kinetic energies, and detector configurations.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// stepping-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the stepping-action
@@ -74,20 +76,20 @@ class SteppingAction : public G4UserSteppingAction {
// the sum of step lengths in those scoring volumes.
// Notice that two of the three scoring volumes - upstream and downstream -
// have the same cubic-volume, that we call "fCubicVolumeScoringUpDown".
static const G4int fkNumberScoringVolumes = 3; // downstream, side, upstream
static const G4int fkNumberScoringVolumes = 3; // downstream, side, upstream
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
private:
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -101,8 +103,8 @@ class SteppingAction : public G4UserSteppingAction {
G4bool fIsFirstStepInScoringSide;
G4double fCubicVolumeScoringUpDown;
G4double fCubicVolumeScoringSide;
std::array< G4double, fkNumberCombinations > fArraySumStepLengths;
std::array<G4double, fkNumberCombinations> fArraySumStepLengths;
// Array to collect the sum of step lengths in the scoring volumes for the whole run,
// according to the various cases (kinematical region and particle type).
// Note that the fluence in a scoring volume is defined as sum of step lengths
@@ -26,63 +26,65 @@
/// \file TrackingAction.hh
/// \brief Definition of the TrackingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef TrackingAction_h
#ifndef TrackingAction_h
#define TrackingAction_h 1
#include "globals.hh"
#include "G4UserTrackingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class TrackingAction : public G4UserTrackingAction {
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the calorimeter.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
class TrackingAction : public G4UserTrackingAction
{
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the calorimeter.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
public:
TrackingAction();
~TrackingAction() override = default;
void PreUserTrackingAction( const G4Track* ) override;
void PostUserTrackingAction( const G4Track* ) override;
void PreUserTrackingAction(const G4Track*) override;
void PostUserTrackingAction(const G4Track*) override;
void Initialize();
// This method is called by RunAction::BeginOfRunAction for the
// initialization of the tracking-action at the beginning of each Run.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// tracking-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the tracking-action
// to the run object.
static const G4int fkNumberScoringVolumes = 1; // calorimeter
static const G4int fkNumberScoringVolumes = 1; // calorimeter
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
std::array< G4long, fkNumberCombinations > fArrayMultiplicities;
std::array< G4double, fkNumberCombinations > fArraySumKineticEnergies;
std::array<G4long, fkNumberCombinations> fArrayMultiplicities;
std::array<G4double, fkNumberCombinations> fArraySumKineticEnergies;
// Keep record of the fkNumber of particles and their kinetic energy at production,
// according to the particle type and their kinetic energy range (below/above 20 MeV).
};
@@ -32,35 +32,38 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "ActionInitialization.hh"
#include "PrimaryGeneratorAction.hh"
#include "Run.hh"
#include "RunAction.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::
ActionInitialization( const DetectorConstruction* inputDetectorConstruction ) :
G4VUserActionInitialization(), fPtrDetectorConstruction( inputDetectorConstruction ) {}
ActionInitialization::ActionInitialization(const DetectorConstruction* inputDetectorConstruction)
: G4VUserActionInitialization(), fPtrDetectorConstruction(inputDetectorConstruction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
void ActionInitialization::BuildForMaster() const
{
// This is NOT called in SEQ-mode, while in the MT-mode is called only for the Master thread.
SetUserAction( new RunAction );
SetUserAction(new RunAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
void ActionInitialization::Build() const
{
// This is called in the SEQ-mode and in the MT-mode only for Worker threads.
SetUserAction( new PrimaryGeneratorAction( fPtrDetectorConstruction ) );
SetUserAction(new PrimaryGeneratorAction(fPtrDetectorConstruction));
SteppingAction* steppingAction = new SteppingAction;
SetUserAction( steppingAction );
SetUserAction(steppingAction);
TrackingAction* trackingAction = new TrackingAction;
SetUserAction( trackingAction );
SetUserAction( new RunAction( steppingAction, trackingAction ) );
SetUserAction(trackingAction);
SetUserAction(new RunAction(steppingAction, trackingAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
File diff suppressed because it is too large Load Diff
@@ -32,106 +32,110 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorMessenger.hh"
#include "DetectorConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIdirectory.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* myDet ) : fDetector( myDet ) {
fDetectorDir = new G4UIdirectory( "/mydet/" );
fDetectorDir->SetGuidance( "Detector control." );
fFieldCommand = new G4UIcmdWithADoubleAndUnit( "/mydet/setField", this );
fFieldCommand->SetGuidance( "Define uniform magnetic field along Y." );
fFieldCommand->SetGuidance( " -> in unit of [Tesla]" );
fFieldCommand->SetParameterName( "By", false );
fFieldCommand->SetDefaultValue( 0.0 );
fFieldCommand->SetUnitCategory( "Magnetic flux density" );
fFieldCommand->AvailableForStates( G4State_PreInit, G4State_Idle );
DetectorMessenger::DetectorMessenger(DetectorConstruction* myDet) : fDetector(myDet)
{
fDetectorDir = new G4UIdirectory("/mydet/");
fDetectorDir->SetGuidance("Detector control.");
fAbsorberMaterial = new G4UIcmdWithAString( "/mydet/absorberMaterial", this );
fAbsorberMaterial->SetGuidance( "Choice of the absorber material:" );
fAbsorberMaterial->SetGuidance( " iron / copper / tungsten / lead / PbWO4 / uranium " );
fAbsorberMaterial->SetParameterName( "choiceAbsorberMaterial", true );
fAbsorberMaterial->SetDefaultValue( "iron" );
fAbsorberMaterial->AvailableForStates( G4State_PreInit, G4State_Idle );
fFieldCommand = new G4UIcmdWithADoubleAndUnit("/mydet/setField", this);
fFieldCommand->SetGuidance("Define uniform magnetic field along Y.");
fFieldCommand->SetGuidance(" -> in unit of [Tesla]");
fFieldCommand->SetParameterName("By", false);
fFieldCommand->SetDefaultValue(0.0);
fFieldCommand->SetUnitCategory("Magnetic flux density");
fFieldCommand->AvailableForStates(G4State_PreInit, G4State_Idle);
fActiveMaterial = new G4UIcmdWithAString( "/mydet/activeMaterial", this );
fActiveMaterial->SetGuidance( "Choice of the active material:" );
fActiveMaterial->SetGuidance( " scintillator / liquidArgon / PbWO4 / silicon / quartz " );
fActiveMaterial->SetParameterName( "choiceActiveMaterial", true );
fActiveMaterial->SetDefaultValue( "scintillator" );
fActiveMaterial->AvailableForStates( G4State_PreInit, G4State_Idle );
fAbsorberMaterial = new G4UIcmdWithAString("/mydet/absorberMaterial", this);
fAbsorberMaterial->SetGuidance("Choice of the absorber material:");
fAbsorberMaterial->SetGuidance(" iron / copper / tungsten / lead / PbWO4 / uranium ");
fAbsorberMaterial->SetParameterName("choiceAbsorberMaterial", true);
fAbsorberMaterial->SetDefaultValue("iron");
fAbsorberMaterial->AvailableForStates(G4State_PreInit, G4State_Idle);
fIsCalHomogeneous = new G4UIcmdWithABool( "/mydet/isCalHomogeneous", this );
fIsCalHomogeneous->SetParameterName( "choiceIsCalHomogeneous", true );
fIsCalHomogeneous->SetGuidance( "Is the calorimeter homogeneous?" );
fIsCalHomogeneous->SetGuidance( " -> yes|y|true|t|1 : Homogeneous calorimeter" );
fIsCalHomogeneous->SetGuidance( " -> no|n|false|f|0 : Sampling calorimeter" );
fIsCalHomogeneous->SetDefaultValue( false ); // default: sampling calorimeter
fIsCalHomogeneous->AvailableForStates( G4State_PreInit, G4State_Idle );
fIsUnitInLambda = new G4UIcmdWithABool( "/mydet/isUnitInLambda", this );
fIsUnitInLambda->SetParameterName( "choiceIsUnitInLambda", true );
fIsUnitInLambda->SetGuidance( "Is unit for absorber length in lambda?" );
fIsUnitInLambda->SetGuidance( " -> yes|y|true|t|1 : unit in lambda" );
fIsUnitInLambda->SetGuidance( " -> no|n|false|f|0 : unit in [mm]" );
fIsUnitInLambda->SetDefaultValue( false ); // default: unit in [mm].
fIsUnitInLambda->AvailableForStates( G4State_PreInit, G4State_Idle );
fAbsorberTotalLength = new G4UIcmdWithADouble( "/mydet/absorberTotalLength", this );
fAbsorberTotalLength->SetParameterName( "choiceAbsorberTotalLength", true );
fAbsorberTotalLength->SetGuidance( "Absorber total length" );
fAbsorberTotalLength->SetGuidance( " -> in unit of lambda or [mm]" );
fAbsorberTotalLength->SetGuidance( " -> depending on value of choiceIsUnitInLambda" );
fAbsorberTotalLength->SetDefaultValue( 2000.0 ); // default: 2 meters.
fAbsorberTotalLength->AvailableForStates( G4State_PreInit, G4State_Idle );
fActiveMaterial = new G4UIcmdWithAString("/mydet/activeMaterial", this);
fActiveMaterial->SetGuidance("Choice of the active material:");
fActiveMaterial->SetGuidance(" scintillator / liquidArgon / PbWO4 / silicon / quartz ");
fActiveMaterial->SetParameterName("choiceActiveMaterial", true);
fActiveMaterial->SetDefaultValue("scintillator");
fActiveMaterial->AvailableForStates(G4State_PreInit, G4State_Idle);
fCalorimeterRadius = new G4UIcmdWithADouble( "/mydet/calorimeterRadius", this );
fCalorimeterRadius->SetParameterName( "choiceCalorimeterRadius", true );
fCalorimeterRadius->SetGuidance( "Calorimeter Radius" );
fCalorimeterRadius->SetGuidance( " -> in unit of lambda or [mm]" );
fCalorimeterRadius->SetGuidance( " -> depending on value of choiceIsUnitInLambda" );
fCalorimeterRadius->SetDefaultValue( 1000.0 ); // default: 1 meter.
fCalorimeterRadius->AvailableForStates( G4State_PreInit, G4State_Idle );
fIsCalHomogeneous = new G4UIcmdWithABool("/mydet/isCalHomogeneous", this);
fIsCalHomogeneous->SetParameterName("choiceIsCalHomogeneous", true);
fIsCalHomogeneous->SetGuidance("Is the calorimeter homogeneous?");
fIsCalHomogeneous->SetGuidance(" -> yes|y|true|t|1 : Homogeneous calorimeter");
fIsCalHomogeneous->SetGuidance(" -> no|n|false|f|0 : Sampling calorimeter");
fIsCalHomogeneous->SetDefaultValue(false); // default: sampling calorimeter
fIsCalHomogeneous->AvailableForStates(G4State_PreInit, G4State_Idle);
fActiveLayerNumber = new G4UIcmdWithAnInteger( "/mydet/activeLayerNumber", this );
fActiveLayerNumber->SetParameterName( "choiceActiveLayerNumber", true );
fActiveLayerNumber->SetGuidance( "Number of active layers" );
fActiveLayerNumber->SetDefaultValue( 50 );
fActiveLayerNumber->AvailableForStates( G4State_PreInit, G4State_Idle );
fIsUnitInLambda = new G4UIcmdWithABool("/mydet/isUnitInLambda", this);
fIsUnitInLambda->SetParameterName("choiceIsUnitInLambda", true);
fIsUnitInLambda->SetGuidance("Is unit for absorber length in lambda?");
fIsUnitInLambda->SetGuidance(" -> yes|y|true|t|1 : unit in lambda");
fIsUnitInLambda->SetGuidance(" -> no|n|false|f|0 : unit in [mm]");
fIsUnitInLambda->SetDefaultValue(false); // default: unit in [mm].
fIsUnitInLambda->AvailableForStates(G4State_PreInit, G4State_Idle);
fActiveLayerSize = new G4UIcmdWithADouble( "/mydet/activeLayerSize", this );
fActiveLayerSize->SetParameterName( "choiceActiveLayerSize", true );
fActiveLayerSize->SetGuidance( "Size (thickness) of the active layer, in [mm]" );
fActiveLayerSize->SetDefaultValue( 4.0 ); // default: 4 millimeters.
fActiveLayerSize->AvailableForStates( G4State_PreInit, G4State_Idle );
fAbsorberTotalLength = new G4UIcmdWithADouble("/mydet/absorberTotalLength", this);
fAbsorberTotalLength->SetParameterName("choiceAbsorberTotalLength", true);
fAbsorberTotalLength->SetGuidance("Absorber total length");
fAbsorberTotalLength->SetGuidance(" -> in unit of lambda or [mm]");
fAbsorberTotalLength->SetGuidance(" -> depending on value of choiceIsUnitInLambda");
fAbsorberTotalLength->SetDefaultValue(2000.0); // default: 2 meters.
fAbsorberTotalLength->AvailableForStates(G4State_PreInit, G4State_Idle);
fIsRadiusUnitInLambda = new G4UIcmdWithABool( "/mydet/isRadiusUnitInLambda", this );
fIsRadiusUnitInLambda->SetParameterName( "choiceIsRadiusUnitInLambda", true );
fIsRadiusUnitInLambda->SetGuidance( "Is unit of radius in lambda?" );
fIsRadiusUnitInLambda->SetGuidance( " -> yes|y|true|t|1 : unit in lambda" );
fIsRadiusUnitInLambda->SetGuidance( " -> no|n|false|f|0 : unit in [mm]" );
fIsRadiusUnitInLambda->SetDefaultValue( false ); // default: unit in [mm].
fIsRadiusUnitInLambda->AvailableForStates( G4State_PreInit, G4State_Idle );
fUpdateCommand = new G4UIcmdWithoutParameter( "/mydet/update", this);
fUpdateCommand->SetGuidance( "Update calorimeter geometry." );
fUpdateCommand->SetGuidance( "This command MUST be applied before \"beamOn\" " );
fUpdateCommand->SetGuidance( "if you changed geometrical value(s)." );
fUpdateCommand->AvailableForStates( G4State_Idle );
fCalorimeterRadius = new G4UIcmdWithADouble("/mydet/calorimeterRadius", this);
fCalorimeterRadius->SetParameterName("choiceCalorimeterRadius", true);
fCalorimeterRadius->SetGuidance("Calorimeter Radius");
fCalorimeterRadius->SetGuidance(" -> in unit of lambda or [mm]");
fCalorimeterRadius->SetGuidance(" -> depending on value of choiceIsUnitInLambda");
fCalorimeterRadius->SetDefaultValue(1000.0); // default: 1 meter.
fCalorimeterRadius->AvailableForStates(G4State_PreInit, G4State_Idle);
fActiveLayerNumber = new G4UIcmdWithAnInteger("/mydet/activeLayerNumber", this);
fActiveLayerNumber->SetParameterName("choiceActiveLayerNumber", true);
fActiveLayerNumber->SetGuidance("Number of active layers");
fActiveLayerNumber->SetDefaultValue(50);
fActiveLayerNumber->AvailableForStates(G4State_PreInit, G4State_Idle);
fActiveLayerSize = new G4UIcmdWithADouble("/mydet/activeLayerSize", this);
fActiveLayerSize->SetParameterName("choiceActiveLayerSize", true);
fActiveLayerSize->SetGuidance("Size (thickness) of the active layer, in [mm]");
fActiveLayerSize->SetDefaultValue(4.0); // default: 4 millimeters.
fActiveLayerSize->AvailableForStates(G4State_PreInit, G4State_Idle);
fIsRadiusUnitInLambda = new G4UIcmdWithABool("/mydet/isRadiusUnitInLambda", this);
fIsRadiusUnitInLambda->SetParameterName("choiceIsRadiusUnitInLambda", true);
fIsRadiusUnitInLambda->SetGuidance("Is unit of radius in lambda?");
fIsRadiusUnitInLambda->SetGuidance(" -> yes|y|true|t|1 : unit in lambda");
fIsRadiusUnitInLambda->SetGuidance(" -> no|n|false|f|0 : unit in [mm]");
fIsRadiusUnitInLambda->SetDefaultValue(false); // default: unit in [mm].
fIsRadiusUnitInLambda->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter("/mydet/update", this);
fUpdateCommand->SetGuidance("Update calorimeter geometry.");
fUpdateCommand->SetGuidance("This command MUST be applied before \"beamOn\" ");
fUpdateCommand->SetGuidance("if you changed geometrical value(s).");
fUpdateCommand->AvailableForStates(G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::~DetectorMessenger() {
DetectorMessenger::~DetectorMessenger()
{
delete fFieldCommand;
delete fDetectorDir;
delete fAbsorberMaterial;
@@ -148,38 +152,39 @@ DetectorMessenger::~DetectorMessenger() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue( G4UIcommand* command, G4String newValue ) {
if ( command == fFieldCommand ) {
fDetector->SetMagField( fFieldCommand->GetNewDoubleValue( newValue ) );
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fFieldCommand) {
fDetector->SetMagField(fFieldCommand->GetNewDoubleValue(newValue));
}
if ( command == fAbsorberMaterial ) {
fDetector->SetAbsorberMaterial( newValue );
if (command == fAbsorberMaterial) {
fDetector->SetAbsorberMaterial(newValue);
}
if ( command == fActiveMaterial ) {
fDetector->SetActiveMaterial( newValue );
if (command == fActiveMaterial) {
fDetector->SetActiveMaterial(newValue);
}
if ( command == fIsCalHomogeneous ) {
fDetector->SetIsCalHomogeneous( fIsCalHomogeneous->GetNewBoolValue( newValue ) );
if (command == fIsCalHomogeneous) {
fDetector->SetIsCalHomogeneous(fIsCalHomogeneous->GetNewBoolValue(newValue));
}
if ( command == fIsUnitInLambda ) {
fDetector->SetIsUnitInLambda( fIsUnitInLambda->GetNewBoolValue( newValue ) );
if (command == fIsUnitInLambda) {
fDetector->SetIsUnitInLambda(fIsUnitInLambda->GetNewBoolValue(newValue));
}
if ( command == fAbsorberTotalLength ) {
fDetector->SetAbsorberTotalLength( fAbsorberTotalLength->GetNewDoubleValue( newValue ) );
if (command == fAbsorberTotalLength) {
fDetector->SetAbsorberTotalLength(fAbsorberTotalLength->GetNewDoubleValue(newValue));
}
if ( command == fCalorimeterRadius ) {
fDetector->SetCalorimeterRadius( fCalorimeterRadius->GetNewDoubleValue(newValue) );
if (command == fCalorimeterRadius) {
fDetector->SetCalorimeterRadius(fCalorimeterRadius->GetNewDoubleValue(newValue));
}
if ( command == fActiveLayerNumber ) {
fDetector->SetActiveLayerNumber( fActiveLayerNumber->GetNewIntValue( newValue ) );
if (command == fActiveLayerNumber) {
fDetector->SetActiveLayerNumber(fActiveLayerNumber->GetNewIntValue(newValue));
}
if ( command == fActiveLayerSize ) {
fDetector->SetActiveLayerSize( fActiveLayerSize->GetNewDoubleValue( newValue ) );
if (command == fActiveLayerSize) {
fDetector->SetActiveLayerSize(fActiveLayerSize->GetNewDoubleValue(newValue));
}
if ( command == fIsRadiusUnitInLambda ) {
fDetector->SetIsRadiusUnitInLambda( fIsRadiusUnitInLambda->GetNewBoolValue( newValue ) );
if (command == fIsRadiusUnitInLambda) {
fDetector->SetIsRadiusUnitInLambda(fIsRadiusUnitInLambda->GetNewBoolValue(newValue));
}
if ( command == fUpdateCommand ) {
if (command == fUpdateCommand) {
fDetector->UpdateGeometry();
}
}
@@ -32,52 +32,58 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "PrimaryGeneratorAction.hh"
#include "DetectorConstruction.hh"
#include "G4Event.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction( const DetectorConstruction* pDetector ) :
fPointerDetectorConstruction( pDetector )
PrimaryGeneratorAction::PrimaryGeneratorAction(const DetectorConstruction* pDetector)
: fPointerDetectorConstruction(pDetector)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun( n_particle );
fParticleGun = new G4ParticleGun(n_particle);
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition( particleTable->FindParticle( "geantino" ) );
fParticleGun->SetParticleEnergy( 10.0*GeV );
fParticleGun->SetParticleDefinition(particleTable->FindParticle("geantino"));
fParticleGun->SetParticleEnergy(10.0 * GeV);
SetGunPosition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete fParticleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::SetGunPosition() const {
void PrimaryGeneratorAction::SetGunPosition() const
{
// Shoot the particle in the middle between the world and the calorimeter
G4double caloLength =
( fPointerDetectorConstruction ? fPointerDetectorConstruction->GetCaloLength() : 0.0 );
G4double gunPosition = -0.55*caloLength; //***LOOKHERE*** default gun position along the z-axis
G4cout << G4endl << "PrimaryGenerationAction::SetGunPosition() : gun position along z = "
<< gunPosition << " mm " << G4endl << G4endl;
fParticleGun->SetParticlePosition( G4ThreeVector( 0.0, 0.0, gunPosition ) );
(fPointerDetectorConstruction ? fPointerDetectorConstruction->GetCaloLength() : 0.0);
G4double gunPosition = -0.55 * caloLength; //***LOOKHERE*** default gun position along the z-axis
G4cout << G4endl
<< "PrimaryGenerationAction::SetGunPosition() : gun position along z = " << gunPosition
<< " mm " << G4endl << G4endl;
fParticleGun->SetParticlePosition(G4ThreeVector(0.0, 0.0, gunPosition));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries( G4Event* anEvent ) {
G4ThreeVector v( 0.0, 0.0, 1.0 ); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection( v );
fParticleGun->GeneratePrimaryVertex( anEvent );
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
G4ThreeVector v(0.0, 0.0, 1.0); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection(v);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,39 +32,47 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "Run.hh"
#include "G4SystemOfUnits.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() : G4Run(), fNumEvents( 0 ),
fPrimaryParticleId( 0 ), fPrimaryParticleEnergy( 0.0 ),
fPrimaryParticleDirection( G4ThreeVector( 0.0, 0.0, 0.0 ) ),
fAbsorberMaterialName( "" ), fActiveMaterialName( "" ),
fCubicVolumeScoringUpDown( 1.0 ), fCubicVolumeScoringSide( 1.0 )
Run::Run()
: G4Run(),
fNumEvents(0),
fPrimaryParticleId(0),
fPrimaryParticleEnergy(0.0),
fPrimaryParticleDirection(G4ThreeVector(0.0, 0.0, 0.0)),
fAbsorberMaterialName(""),
fActiveMaterialName(""),
fCubicVolumeScoringUpDown(1.0),
fCubicVolumeScoringSide(1.0)
{
fSteppingArray.fill( 0.0 );
fTrackingArray1.fill( 0 );
fTrackingArray2.fill( 0.0 );
fSteppingArray.fill(0.0);
fTrackingArray1.fill(0);
fTrackingArray2.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::RecordEvent( const G4Event* anEvent ) {
void Run::RecordEvent(const G4Event* anEvent)
{
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event : in MT-mode, it is called only for the working thread that handled the event.
G4int nEvt = anEvent->GetEventID();
if ( nEvt % 10 == 0 ) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent( anEvent );
if (nEvt % 10 == 0) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge( const G4Run* aRun ) {
void Run::Merge(const G4Run* aRun)
{
// This method is called automatically by the Geant4 kernel (not by the user!) only in the case
// of multithreaded mode and only for working threads.
const Run* localRun = static_cast< const Run* >( aRun );
const Run* localRun = static_cast<const Run*>(aRun);
fPrimaryParticleId = localRun->GetPrimaryParticleId();
fPrimaryParticleEnergy = localRun->GetPrimaryParticleEnergy();
fPrimaryParticleDirection = localRun->GetPrimaryParticleDirection();
@@ -73,55 +81,53 @@ void Run::Merge( const G4Run* aRun ) {
fCubicVolumeScoringUpDown = localRun->GetCubicVolumeScoringUpDown();
fCubicVolumeScoringSide = localRun->GetCubicVolumeScoringSide();
fNumEvents += localRun->GetNumberOfEvent();
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] += localRun->GetSteppingArray()[i];
}
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] += localRun->GetTrackingArray1()[i];
fTrackingArray2[i] += localRun->GetTrackingArray2()[i];
}
G4Run::Merge( aRun );
G4Run::Merge(aRun);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::PrintInfo() const {
void Run::PrintInfo() const
{
// This method is called by RunAction::EndOfRunAction. In MT-mode, only the master thread
// calls it.
const G4double floatingNumberOfEvents =
std::max( 1.0, fNumEvents > 0 ? fNumEvents*1.0 : GetNumberOfEvent()*1.0 );
std::max(1.0, fNumEvents > 0 ? fNumEvents * 1.0 : GetNumberOfEvent() * 1.0);
// The fluence in the scoring volume is defined as sum of step lengths in that volume
// divided by the volume of that scoring volume.
const G4double conversionFactor = CLHEP::cm * CLHEP::cm; // From mm^-2 to cm^-2
const G4double factorUpDown =
conversionFactor / ( fCubicVolumeScoringUpDown*floatingNumberOfEvents );
const G4double factorSide =
conversionFactor / ( fCubicVolumeScoringSide*floatingNumberOfEvents );
conversionFactor / (fCubicVolumeScoringUpDown * floatingNumberOfEvents);
const G4double factorSide = conversionFactor / (fCubicVolumeScoringSide * floatingNumberOfEvents);
G4cout << std::setprecision(6) << G4endl << G4endl
<< " =============== Run::PrintInfo() =============== \t RunID = " << GetRunID()
<< G4endl
<< " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV
<< " GeV" << G4endl
<< " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< G4endl << " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV << " GeV"
<< G4endl << " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< " Absorber material = " << fAbsorberMaterialName << G4endl
<< " Active material = " << fActiveMaterialName << G4endl
<< " Cubic-volume scoring up-down = " << fCubicVolumeScoringUpDown << " mm^3" << G4endl
<< " Cubic-volume scoring side = " << fCubicVolumeScoringSide << " mm^3" << G4endl
<< " Cubic-volume scoring side = " << fCubicVolumeScoringSide << " mm^3" << G4endl
<< " Number of events = " << floatingNumberOfEvents << G4endl
<< " Conversion factor: fluence from mm^-2 to cm^-2 = " << conversionFactor << G4endl
<< " Particle fluence in unit of cm^-2 :" << G4endl;
for ( G4int i = 0; i < SteppingAction::fkNumberScoringVolumes; ++i ) {
G4double factor = ( i == 1 ? factorSide : factorUpDown );
for ( G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k ) {
G4int index = SteppingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << SteppingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << SteppingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << SteppingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << factor*fSteppingArray[index] << G4endl;
for (G4int i = 0; i < SteppingAction::fkNumberScoringVolumes; ++i) {
G4double factor = (i == 1 ? factorSide : factorUpDown);
for (G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k) {
G4int index = SteppingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< SteppingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< SteppingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< SteppingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< factor * fSteppingArray[index] << G4endl;
}
}
}
@@ -129,50 +135,51 @@ void Run::PrintInfo() const {
<< " Extra information: particle production \t \t <N> <E_kin> <Sum_Ekin> [MeV]"
<< G4endl;
const G4double normalization = 1.0 / floatingNumberOfEvents;
for ( G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i ) {
for ( G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k ) {
G4int index = TrackingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << TrackingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << TrackingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << TrackingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << normalization * fTrackingArray1[index]
<< " " << std::setw( 8) << ( fTrackingArray1[index] > 0 ?
fTrackingArray2[index] / fTrackingArray1[index] :
0.0 )
<< " " << std::setw( 8) << normalization * fTrackingArray2[index]
<< G4endl;
for (G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i) {
for (G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k) {
G4int index = TrackingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< TrackingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< TrackingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< TrackingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< normalization * fTrackingArray1[index] << " " << std::setw(8)
<< (fTrackingArray1[index] > 0 ? fTrackingArray2[index] / fTrackingArray1[index]
: 0.0)
<< " " << std::setw(8) << normalization * fTrackingArray2[index] << G4endl;
}
}
}
}
G4cout << " ============================================================= " << G4endl << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
void Run::SetSteppingArray(
const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray1(
const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray2(
const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray2[i] = inputArray[i];
}
}
@@ -32,46 +32,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "RunAction.hh"
#include "globals.hh"
#include "G4Run.hh"
#include "Run.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction( SteppingAction* steppingAction, TrackingAction* trackingAction ) :
G4UserRunAction(), fSteppingAction( steppingAction ), fTrackingAction( trackingAction ) {}
RunAction::RunAction(SteppingAction* steppingAction, TrackingAction* trackingAction)
: G4UserRunAction(), fSteppingAction(steppingAction), fTrackingAction(trackingAction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun() {
G4Run* RunAction::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction( const G4Run* aRun ) {
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
G4cout << "### Run " << aRun->GetRunID() << " starts." << G4endl;
Run* run = const_cast< Run* >( static_cast< const Run* >( aRun ) );
if ( run == nullptr ) return;
if ( fSteppingAction != nullptr ) {
Run* run = const_cast<Run*>(static_cast<const Run*>(aRun));
if (run == nullptr) return;
if (fSteppingAction != nullptr) {
fSteppingAction->Initialize();
fSteppingAction->SetRunPointer( run );
fSteppingAction->SetRunPointer(run);
}
if ( fTrackingAction != nullptr ) {
if (fTrackingAction != nullptr) {
fTrackingAction->Initialize();
fTrackingAction->SetRunPointer( run );
fTrackingAction->SetRunPointer(run);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction( const G4Run* aRun ) {
const Run* run = static_cast< const Run* >( aRun );
if ( run == nullptr || run->GetNumberOfEvent() == 0 ) return;
if ( IsMaster() ) run->PrintInfo();
void RunAction::EndOfRunAction(const G4Run* aRun)
{
const Run* run = static_cast<const Run*>(aRun);
if (run == nullptr || run->GetNumberOfEvent() == 0) return;
if (IsMaster()) run->PrintInfo();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,44 +32,47 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "SteppingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include "G4VSolid.hh"
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, SteppingAction::fkNumberScoringVolumes >
SteppingAction::fkArrayScoringVolumeNames = { "downstream", "side", "upstream" };
#include "G4IonTable.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VSolid.hh"
#include "G4VTouchable.hh"
const std::array< G4String, SteppingAction::fkNumberKinematicRegions >
SteppingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, SteppingAction::fkNumberScoringVolumes>
SteppingAction::fkArrayScoringVolumeNames = {"downstream", "side", "upstream"};
const std::array< G4String, SteppingAction::fkNumberParticleTypes >
SteppingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, SteppingAction::fkNumberKinematicRegions>
SteppingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, SteppingAction::fkNumberParticleTypes>
SteppingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int SteppingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int SteppingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
if ( index < 0 || index >= fkNumberCombinations ) {
if (index < 0 || index >= fkNumberCombinations) {
G4cerr << "SteppingAction::GetIndex : WRONG index=" << index << " set it to 0 !" << G4endl;
index = 0;
}
@@ -78,27 +81,29 @@ G4int SteppingAction::GetIndex( const G4int iScoringVolume, const G4int iKinemat
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction() :G4UserSteppingAction() {
SteppingAction::SteppingAction() : G4UserSteppingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::Initialize() {
// Initialization needed at the beginning of each Run
void SteppingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fPrimaryParticleId = 0;
fPrimaryParticleEnergy = 0.0;
fPrimaryParticleDirection = G4ThreeVector( 0.0, 0.0, 1.0 );
fPrimaryParticleDirection = G4ThreeVector(0.0, 0.0, 1.0);
fAbsorberMaterialName = "";
fActiveMaterialName = "";
fIsFirstStepOfTheEvent = true;
fIsFirstStepInAbsorberLayer = true;
fIsFirstStepInActiveLayer = true;
fIsFirstStepInScoringUpDown = true;
fIsFirstStepInScoringSide = true;
fIsFirstStepInScoringUpDown = true;
fIsFirstStepInScoringSide = true;
fCubicVolumeScoringUpDown = 1.0;
fCubicVolumeScoringSide = 1.0;
for ( G4int i = 0; i < fkNumberCombinations; ++i ) {
for (G4int i = 0; i < fkNumberCombinations; ++i) {
fArraySumStepLengths[i] = 0.0;
}
/*
@@ -123,72 +128,77 @@ void SteppingAction::Initialize() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
void SteppingAction::UserSteppingAction(const G4Step* theStep)
{
// Get information on the primary particle
if ( fIsFirstStepOfTheEvent ) {
if ( theStep->GetTrack()->GetParentID() == 0 ) {
if (fIsFirstStepOfTheEvent) {
if (theStep->GetTrack()->GetParentID() == 0) {
fPrimaryParticleId = theStep->GetTrack()->GetDefinition()->GetPDGEncoding();
fPrimaryParticleEnergy = theStep->GetPreStepPoint()->GetKineticEnergy();
fPrimaryParticleDirection = theStep->GetPreStepPoint()->GetMomentumDirection();
if ( fRunPtr ) {
fRunPtr->SetPrimaryParticleId( fPrimaryParticleId );
fRunPtr->SetPrimaryParticleEnergy( fPrimaryParticleEnergy );
fRunPtr->SetPrimaryParticleDirection( fPrimaryParticleDirection );
if (fRunPtr) {
fRunPtr->SetPrimaryParticleId(fPrimaryParticleId);
fRunPtr->SetPrimaryParticleEnergy(fPrimaryParticleEnergy);
fRunPtr->SetPrimaryParticleDirection(fPrimaryParticleDirection);
}
fIsFirstStepOfTheEvent = false;
}
}
// Get information on the materials of the calorimeter
if ( fIsFirstStepInAbsorberLayer &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiAbsorber" ) {
if (fIsFirstStepInAbsorberLayer
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiAbsorber")
{
fAbsorberMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetAbsorberMaterialName( fAbsorberMaterialName );
if (fRunPtr) fRunPtr->SetAbsorberMaterialName(fAbsorberMaterialName);
fIsFirstStepInAbsorberLayer = false;
}
if ( fIsFirstStepInActiveLayer &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiActive" ) {
if (fIsFirstStepInActiveLayer
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiActive")
{
fActiveMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetActiveMaterialName( fActiveMaterialName );
if (fRunPtr) fRunPtr->SetActiveMaterialName(fActiveMaterialName);
fIsFirstStepInActiveLayer = false;
}
// Get information on step lengths in the scoring volumes
G4int iScoringVolume = -1;
if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringDownstream" ) {
if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringDownstream") {
iScoringVolume = 0;
if ( fIsFirstStepInScoringUpDown ) {
if (fIsFirstStepInScoringUpDown) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringUpDown( fCubicVolumeScoringUpDown );
fIsFirstStepInScoringUpDown = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringSide" ) {
iScoringVolume = 1;
if ( fIsFirstStepInScoringSide ) {
fCubicVolumeScoringSide =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringSide( fCubicVolumeScoringSide );
fIsFirstStepInScoringSide = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() ==
"physiScoringUpstream" ) {
iScoringVolume = 2;
if ( fIsFirstStepInScoringUpDown ) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringUpDown( fCubicVolumeScoringUpDown );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringUpDown(fCubicVolumeScoringUpDown);
fIsFirstStepInScoringUpDown = false;
}
}
if ( iScoringVolume >= 0 ) {
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringSide") {
iScoringVolume = 1;
if (fIsFirstStepInScoringSide) {
fCubicVolumeScoringSide =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if (fRunPtr) fRunPtr->SetCubicVolumeScoringSide(fCubicVolumeScoringSide);
fIsFirstStepInScoringSide = false;
}
}
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringUpstream") {
iScoringVolume = 2;
if (fIsFirstStepInScoringUpDown) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if (fRunPtr) fRunPtr->SetCubicVolumeScoringUpDown(fCubicVolumeScoringUpDown);
fIsFirstStepInScoringUpDown = false;
}
}
if (iScoringVolume >= 0) {
// In the case of the upstream scoring volume, consider only particles whose direction
// is opposite with respect to the primary particle (this is needed, in particular,
// for avoiding to account the incoming, primary beam particle in the "upstream" fluence).
if ( iScoringVolume == 2 &&
fPrimaryParticleDirection.dot(
theStep->GetPreStepPoint()->GetMomentumDirection() ) > 0.0 ) return;
if (iScoringVolume == 2
&& fPrimaryParticleDirection.dot(theStep->GetPreStepPoint()->GetMomentumDirection()) > 0.0)
return;
G4double stepLength = theStep->GetTrack()->GetStepLength() * theStep->GetTrack()->GetWeight();
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr ? 0 :
std::abs( theStep->GetTrack()->GetDefinition()->GetPDGEncoding() );
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr
? 0
: std::abs(theStep->GetTrack()->GetDefinition()->GetPDGEncoding());
/*
G4cout << std::setprecision(6)
<< theStep->GetTrack()->GetDefinition()->GetParticleName() << " absPdg=" << absPdg
@@ -197,42 +207,52 @@ void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
<< "," << theStep->GetTrack()->GetPosition().z() << ")"
<< " " << theStep->GetTrack()->GetVolume()->GetName()
<< " " << theStep->GetTrack()->GetMaterial()->GetName()
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot(
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot(
theStep->GetPreStepPoint()->GetMomentumDirection() ) > 0.0
? "forward" : "backward" )
? "forward" : "backward" )
<< G4endl;
*/
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = theStep->GetPreStepPoint()->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4; // neutrinos
// (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( theStep->GetTrack()->GetDefinition() ) || // ions (and anti-ions)
G4IonTable::IsAntiIon( theStep->GetTrack()->GetDefinition() ) ) iParticleType = 8;
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4; // neutrinos
// (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(theStep->GetTrack()->GetDefinition()) || // ions (and anti-ions)
G4IonTable::IsAntiIon(theStep->GetTrack()->GetDefinition()))
iParticleType = 8;
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex(iScoringVolume, 0, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
fArraySumStepLengths[index] += stepLength;
if ( fRunPtr ) fRunPtr->SetSteppingArray( fArraySumStepLengths );
if (fRunPtr) fRunPtr->SetSteppingArray(fArraySumStepLengths);
}
}
@@ -32,115 +32,130 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "TrackingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, TrackingAction::fkNumberScoringVolumes >
TrackingAction::fkArrayScoringVolumeNames = { "calorimeter" };
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4Track.hh"
const std::array< G4String, TrackingAction::fkNumberKinematicRegions >
TrackingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, TrackingAction::fkNumberScoringVolumes>
TrackingAction::fkArrayScoringVolumeNames = {"calorimeter"};
const std::array< G4String, TrackingAction::fkNumberParticleTypes >
TrackingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, TrackingAction::fkNumberKinematicRegions>
TrackingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, TrackingAction::fkNumberParticleTypes>
TrackingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int TrackingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int TrackingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
return index;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TrackingAction::TrackingAction() : G4UserTrackingAction() {
TrackingAction::TrackingAction() : G4UserTrackingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::Initialize() {
void TrackingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill( 0 );
fArraySumKineticEnergies.fill( 0.0 );
fArrayMultiplicities.fill(0);
fArraySumKineticEnergies.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PreUserTrackingAction( const G4Track* aTrack ) {
// This method is called not only once when a particle is created,
void TrackingAction::PreUserTrackingAction(const G4Track* aTrack)
{
// This method is called not only once when a particle is created,
// but also each time it is resumed, in the case the track gets suspended,
// as it happens in the case of neutrons with _HP Physics Lists.
// To be sure that we collect information about a track one and only once,
// we require that the current step be the first one.
if ( aTrack == nullptr ||
aTrack->GetCurrentStepNumber() != 0 ||
aTrack->GetDefinition() == nullptr ||
aTrack->GetLogicalVolumeAtVertex() == nullptr ||
( aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicAbsorber" &&
aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicActive" ) ) {
if (aTrack == nullptr || aTrack->GetCurrentStepNumber() != 0 || aTrack->GetDefinition() == nullptr
|| aTrack->GetLogicalVolumeAtVertex() == nullptr
|| (aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicAbsorber"
&& aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicActive"))
{
return;
}
G4int iScoringVolume = 0;
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = aTrack->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int absPdg = std::abs( aTrack->GetDefinition()->GetPDGEncoding() );
G4int absPdg = std::abs(aTrack->GetDefinition()->GetPDGEncoding());
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( aTrack->GetDefinition() ) ||
G4IonTable::IsAntiIon( aTrack->GetDefinition() ) ) iParticleType = 8;
// ions (and anti-ions)
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(aTrack->GetDefinition())
|| G4IonTable::IsAntiIon(aTrack->GetDefinition()))
iParticleType = 8;
// ions (and anti-ions)
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex(iScoringVolume, 0, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
if ( fRunPtr ) {
fRunPtr->SetTrackingArray1( fArrayMultiplicities );
fRunPtr->SetTrackingArray2( fArraySumKineticEnergies );
if (fRunPtr) {
fRunPtr->SetTrackingArray1(fArrayMultiplicities);
fRunPtr->SetTrackingArray2(fArraySumKineticEnergies);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PostUserTrackingAction( const G4Track* /* aTrack */ ) {}
void TrackingAction::PostUserTrackingAction(const G4Track* /* aTrack */) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -31,40 +31,42 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4Threading.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "G4PhysListFactory.hh"
#include "G4RunManagerFactory.hh"
#include "G4Threading.hh"
#include "G4UImanager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv) {
int main(int argc, char** argv)
{
auto* runManager = G4RunManagerFactory::CreateRunManager();
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization( pDetectorInstance );
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization(pDetectorInstance);
// Physics list factory: use the PHYSLIST environmental variable.
G4PhysListFactory factory;
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
runManager->SetUserInitialization( thePL );
runManager->SetUserInitialization( new ActionInitialization );
runManager->SetUserInitialization(thePL);
runManager->SetUserInitialization(new ActionInitialization);
G4UImanager* UI = G4UImanager::GetUIpointer();
if ( argc==1 ) { // Define UI session for interactive mode.
} else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
G4UImanager* UI = G4UImanager::GetUIpointer();
if (argc == 1) { // Define UI session for interactive mode.
}
else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command + fileName);
}
// job termination
delete runManager;
return 0;
// job termination
delete runManager;
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,7 @@
/// \file ActionInitialization.hh
/// \brief Definition of the ActionInitialization class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -38,7 +38,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class ActionInitialization : public G4VUserActionInitialization {
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
~ActionInitialization() override = default;
@@ -26,7 +26,7 @@
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -35,7 +35,7 @@
#define DetectorConstruction_H 1
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "globals.hh"
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -44,36 +44,37 @@ class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction {
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
G4VPhysicalVolume* Construct();
void SetMaterialTracker( const G4String name );
void SetMaterialTracker(const G4String name);
inline G4Material* GetMaterialTracker() const;
void SetMaterialEmCalo( const G4String name );
void SetMaterialEmCalo(const G4String name);
inline G4Material* GetMaterialEmCalo() const;
void SetMaterialHadCalo( const G4String name );
void SetMaterialHadCalo(const G4String name);
inline G4Material* GetMaterialHadCalo() const;
inline void SetInnerRadiusTracker( const G4double value );
inline void SetInnerRadiusTracker(const G4double value);
inline G4double GetInnerRadiusTracker() const;
inline void SetOuterRadiusTracker( const G4double value );
inline void SetOuterRadiusTracker(const G4double value);
inline G4double GetOuterRadiusTracker() const;
inline void SetInnerRadiusEmCalo( const G4double value );
inline void SetInnerRadiusEmCalo(const G4double value);
inline G4double GetInnerRadiusEmCalo() const;
inline void SetOuterRadiusEmCalo( const G4double value );
inline void SetOuterRadiusEmCalo(const G4double value);
inline G4double GetOuterRadiusEmCalo() const;
inline void SetInnerRadiusHadCalo( const G4double value );
inline void SetInnerRadiusHadCalo(const G4double value);
inline G4double GetInnerRadiusHadCalo() const;
inline void SetOuterRadiusHadCalo( const G4double value );
inline void SetOuterRadiusHadCalo(const G4double value);
inline G4double GetOuterRadiusHadCalo() const;
inline G4double GetScoringThickness() const;
void UpdateGeometry();
private:
G4VPhysicalVolume* ConstructDetector(); // To be invoked each time the geometry needs
// to be updated.
@@ -81,21 +82,21 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
G4Material* fMaterialTracker;
G4Material* fMaterialEmCalo;
G4Material* fMaterialHadCalo;
G4LogicalVolume* fExperimentalHall_log;
G4LogicalVolume* fExperimentalHall_log;
G4VPhysicalVolume* fExperimentalHall_phys;
G4LogicalVolume* fLogicTrackerShell;
G4LogicalVolume* fLogicTrackerShell;
G4VPhysicalVolume* fPhysiTrackerShell;
G4LogicalVolume* fLogicEmCaloShell;
G4LogicalVolume* fLogicEmCaloShell;
G4VPhysicalVolume* fPhysiEmCaloShell;
G4LogicalVolume* fLogicHadCaloShell;
G4LogicalVolume* fLogicHadCaloShell;
G4VPhysicalVolume* fPhysiHadCaloShell;
G4LogicalVolume* fLogicScoringTrackerShell;
G4LogicalVolume* fLogicScoringTrackerShell;
G4VPhysicalVolume* fPhysiScoringTrackerShell;
G4LogicalVolume* fLogicScoringEmCaloShell;
G4LogicalVolume* fLogicScoringEmCaloShell;
G4VPhysicalVolume* fPhysiScoringEmCaloShell;
G4LogicalVolume* fLogicScoringHadCaloShell;
G4LogicalVolume* fLogicScoringHadCaloShell;
G4VPhysicalVolume* fPhysiScoringHadCaloShell;
DetectorMessenger* fDetectorMessenger;
DetectorMessenger* fDetectorMessenger;
G4double fInnerRadiusTracker;
G4double fOuterRadiusTracker;
G4double fInnerRadiusEmCalo;
@@ -105,67 +106,83 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
const G4double fScoringThickness = 10.0; //***LOOKHERE*** thickness of the scoring shell
};
inline G4Material* DetectorConstruction::GetMaterialTracker() const {
inline G4Material* DetectorConstruction::GetMaterialTracker() const
{
return fMaterialTracker;
}
inline G4Material* DetectorConstruction::GetMaterialEmCalo() const {
inline G4Material* DetectorConstruction::GetMaterialEmCalo() const
{
return fMaterialEmCalo;
}
inline G4Material* DetectorConstruction::GetMaterialHadCalo() const {
inline G4Material* DetectorConstruction::GetMaterialHadCalo() const
{
return fMaterialHadCalo;
}
inline G4double DetectorConstruction::GetInnerRadiusTracker() const {
inline G4double DetectorConstruction::GetInnerRadiusTracker() const
{
return fInnerRadiusTracker;
}
inline void DetectorConstruction::SetInnerRadiusTracker( const G4double value ) {
inline void DetectorConstruction::SetInnerRadiusTracker(const G4double value)
{
fInnerRadiusTracker = value;
}
inline G4double DetectorConstruction::GetOuterRadiusTracker() const {
inline G4double DetectorConstruction::GetOuterRadiusTracker() const
{
return fOuterRadiusTracker;
}
inline void DetectorConstruction::SetOuterRadiusTracker( const G4double value ) {
inline void DetectorConstruction::SetOuterRadiusTracker(const G4double value)
{
fOuterRadiusTracker = value;
}
inline G4double DetectorConstruction::GetInnerRadiusEmCalo() const {
inline G4double DetectorConstruction::GetInnerRadiusEmCalo() const
{
return fInnerRadiusEmCalo;
}
inline void DetectorConstruction::SetInnerRadiusEmCalo( const G4double value ) {
inline void DetectorConstruction::SetInnerRadiusEmCalo(const G4double value)
{
fInnerRadiusEmCalo = value;
}
inline G4double DetectorConstruction::GetOuterRadiusEmCalo() const {
inline G4double DetectorConstruction::GetOuterRadiusEmCalo() const
{
return fOuterRadiusEmCalo;
}
inline void DetectorConstruction::SetOuterRadiusEmCalo( const G4double value ) {
inline void DetectorConstruction::SetOuterRadiusEmCalo(const G4double value)
{
fOuterRadiusEmCalo = value;
}
inline G4double DetectorConstruction::GetInnerRadiusHadCalo() const {
inline G4double DetectorConstruction::GetInnerRadiusHadCalo() const
{
return fInnerRadiusHadCalo;
}
inline void DetectorConstruction::SetInnerRadiusHadCalo( const G4double value ) {
inline void DetectorConstruction::SetInnerRadiusHadCalo(const G4double value)
{
fInnerRadiusHadCalo = value;
}
inline G4double DetectorConstruction::GetOuterRadiusHadCalo() const {
inline G4double DetectorConstruction::GetOuterRadiusHadCalo() const
{
return fOuterRadiusHadCalo;
}
inline void DetectorConstruction::SetOuterRadiusHadCalo( const G4double value ) {
inline void DetectorConstruction::SetOuterRadiusHadCalo(const G4double value)
{
fOuterRadiusHadCalo = value;
}
inline G4double DetectorConstruction::GetScoringThickness() const {
inline G4double DetectorConstruction::GetScoringThickness() const
{
return fScoringThickness;
}
@@ -26,7 +26,7 @@
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,8 +34,8 @@
#ifndef DetectorMessenger_h
#define DetectorMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
#include "globals.hh"
class DetectorConstruction;
class G4UIdirectory;
@@ -45,11 +45,13 @@ class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorMessenger: public G4UImessenger {
class DetectorMessenger : public G4UImessenger
{
public:
DetectorMessenger( DetectorConstruction* );
DetectorMessenger(DetectorConstruction*);
~DetectorMessenger();
void SetNewValue( G4UIcommand*, G4String ) override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
@@ -26,7 +26,7 @@
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,12 +41,14 @@ class G4Event;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction();
~PrimaryGeneratorAction();
void GeneratePrimaries( G4Event* anEvent ) override;
void GeneratePrimaries(G4Event* anEvent) override;
void SetGunPosition() const;
private:
G4ParticleGun* fParticleGun;
};
@@ -26,7 +26,7 @@
/// \file Run.hh
/// \brief Definition of the Run class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,62 +34,72 @@
#ifndef Run_h
#define Run_h 1
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include <array>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class Run : public G4Run {
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
class Run : public G4Run
{
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
public:
Run();
~Run() override = default;
void RecordEvent( const G4Event* anEvent ) override;
void RecordEvent(const G4Event* anEvent) override;
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event. In the case of multithreaded mode, it is called only for the working thread
// that handled that event.
void Merge( const G4Run* aRun ) override;
void Merge(const G4Run* aRun) override;
// This method is called automatically by the Geant4 kernel (not by the user!) only in the
// case of multithreaded mode and only for working threads.
void PrintInfo() const;
// This method is called by RunAction::EndOfRunAction : in the case of multithreaded mode,
// only the master thread calls it.
void SetPrimaryParticleId( const G4int inputValue ) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy( const G4double inputValue )
{ fPrimaryParticleEnergy = inputValue; }
void SetPrimaryParticleDirection( const G4ThreeVector &inputValue )
{ fPrimaryParticleDirection = inputValue; }
void SetTrackerMaterialName( const G4String &inputValue )
{ fTrackerMaterialName = inputValue; }
void SetEmCaloMaterialName( const G4String &inputValue )
{ fEmCaloMaterialName = inputValue; }
void SetHadCaloMaterialName( const G4String &inputValue )
{ fHadCaloMaterialName = inputValue; }
void SetCubicVolumeScoringTrackerShell( const G4double inputValue )
{ fCubicVolumeScoringTrackerShell = inputValue; }
void SetCubicVolumeScoringEmCaloShell( const G4double inputValue )
{ fCubicVolumeScoringEmCaloShell = inputValue; }
void SetCubicVolumeScoringHadCaloShell( const G4double inputValue )
{ fCubicVolumeScoringHadCaloShell = inputValue; }
void SetPrimaryParticleId(const G4int inputValue) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy(const G4double inputValue)
{
fPrimaryParticleEnergy = inputValue;
}
void SetPrimaryParticleDirection(const G4ThreeVector& inputValue)
{
fPrimaryParticleDirection = inputValue;
}
void SetTrackerMaterialName(const G4String& inputValue) { fTrackerMaterialName = inputValue; }
void SetEmCaloMaterialName(const G4String& inputValue) { fEmCaloMaterialName = inputValue; }
void SetHadCaloMaterialName(const G4String& inputValue) { fHadCaloMaterialName = inputValue; }
void SetCubicVolumeScoringTrackerShell(const G4double inputValue)
{
fCubicVolumeScoringTrackerShell = inputValue;
}
void SetCubicVolumeScoringEmCaloShell(const G4double inputValue)
{
fCubicVolumeScoringEmCaloShell = inputValue;
}
void SetCubicVolumeScoringHadCaloShell(const G4double inputValue)
{
fCubicVolumeScoringHadCaloShell = inputValue;
}
G4int GetPrimaryParticleId() const { return fPrimaryParticleId; }
G4double GetPrimaryParticleEnergy() const { return fPrimaryParticleEnergy; }
G4ThreeVector GetPrimaryParticleDirection() const { return fPrimaryParticleDirection; }
@@ -100,25 +110,31 @@ class Run : public G4Run {
G4double GetCubicVolumeScoringEmCaloShell() const { return fCubicVolumeScoringEmCaloShell; }
G4double GetCubicVolumeScoringHadCaloShell() const { return fCubicVolumeScoringHadCaloShell; }
void SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray );
std::array< G4double, SteppingAction::fkNumberCombinations > GetSteppingArray() const
{ return fSteppingArray; }
void
SetSteppingArray(const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray);
std::array<G4double, SteppingAction::fkNumberCombinations> GetSteppingArray() const
{
return fSteppingArray;
}
// Accessor methods useful to transfer information collected by the stepping-action
// into this Run class
void SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4long, TrackingAction::fkNumberCombinations > GetTrackingArray1() const
{ return fTrackingArray1; }
void SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4double, TrackingAction::fkNumberCombinations > GetTrackingArray2() const
{ return fTrackingArray2; }
void
SetTrackingArray1(const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4long, TrackingAction::fkNumberCombinations> GetTrackingArray1() const
{
return fTrackingArray1;
}
void
SetTrackingArray2(const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4double, TrackingAction::fkNumberCombinations> GetTrackingArray2() const
{
return fTrackingArray2;
}
// Accessor methods useful to transfer information collected by the tracking-action
// into this Run class
private:
private:
G4int fNumEvents;
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -129,9 +145,9 @@ class Run : public G4Run {
G4double fCubicVolumeScoringTrackerShell;
G4double fCubicVolumeScoringEmCaloShell;
G4double fCubicVolumeScoringHadCaloShell;
std::array< G4double, SteppingAction::fkNumberCombinations > fSteppingArray;
std::array< G4long, TrackingAction::fkNumberCombinations > fTrackingArray1;
std::array< G4double, TrackingAction::fkNumberCombinations > fTrackingArray2;
std::array<G4double, SteppingAction::fkNumberCombinations> fSteppingArray;
std::array<G4long, TrackingAction::fkNumberCombinations> fTrackingArray1;
std::array<G4double, TrackingAction::fkNumberCombinations> fTrackingArray2;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file RunAction.hh
/// \brief Definition of the RunAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,13 +42,14 @@ class TrackingAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class RunAction: public G4UserRunAction {
class RunAction : public G4UserRunAction
{
public:
RunAction( SteppingAction* steppingAction = nullptr,
TrackingAction* trackingAction = nullptr );
void BeginOfRunAction( const G4Run* aRun ) override;
void EndOfRunAction( const G4Run* aRun ) override;
RunAction(SteppingAction* steppingAction = nullptr, TrackingAction* trackingAction = nullptr);
void BeginOfRunAction(const G4Run* aRun) override;
void EndOfRunAction(const G4Run* aRun) override;
G4Run* GenerateRun() override;
private:
SteppingAction* fSteppingAction;
TrackingAction* fTrackingAction;
@@ -26,7 +26,7 @@
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,21 +34,23 @@
#ifndef SteppingAction_H
#define SteppingAction_H 1
#include "globals.hh"
#include "G4UserSteppingAction.hh"
#include "G4ThreeVector.hh"
#include "G4UserSteppingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class SteppingAction : public G4UserSteppingAction {
public:
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction();
~SteppingAction() override = default;
void UserSteppingAction( const G4Step* ) override;
void UserSteppingAction(const G4Step*) override;
// This is the main method where the step lengths of particles inside
// the scoring shell are collected, and then the corresponding fluences
// are filled up in the Run object where they are stored (and then
@@ -62,33 +64,33 @@ class SteppingAction : public G4UserSteppingAction {
// This is necessary because different runs can have different primary particle
// types, kinetic energies, and detector configurations.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// stepping-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the stepping-action
// to the run object.
G4double GetCubicVolumeScoringTrackerShell() const { return fCubicVolumeScoringTrackerShell; }
G4double GetCubicVolumeScoringEmCaloShell() const { return fCubicVolumeScoringEmCaloShell; }
G4double GetCubicVolumeScoringEmCaloShell() const { return fCubicVolumeScoringEmCaloShell; }
G4double GetCubicVolumeScoringHadCaloShell() const { return fCubicVolumeScoringHadCaloShell; }
// Needed to get the fluence from the sum of step lengths
static const G4int fkNumberScoringShells = 3; // tracker, emCalo, hadCalo
static const G4int fkNumberScoringShells = 3; // tracker, emCalo, hadCalo
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberScoringPositions = 2; // forward, backward (hemisphere, w.r.t.
// the primary particle direction)
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations = fkNumberScoringShells *
fkNumberKinematicRegions * fkNumberScoringPositions * fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringShells > fkArrayScoringShellNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberScoringPositions > fkArrayScoringPositionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringShell, const G4int iKinematicRegion,
const G4int iScoringPosition, const G4int iParticleType );
private:
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations = fkNumberScoringShells * fkNumberKinematicRegions
* fkNumberScoringPositions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringShells> fkArrayScoringShellNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberScoringPositions> fkArrayScoringPositionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringShell, const G4int iKinematicRegion,
const G4int iScoringPosition, const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -106,8 +108,8 @@ class SteppingAction : public G4UserSteppingAction {
G4bool fIsFirstStepInHadCalo;
G4bool fIsFirstStepInScoringHadCaloShell;
G4double fCubicVolumeScoringHadCaloShell;
std::array< G4double, fkNumberCombinations > fArraySumStepLengths;
std::array<G4double, fkNumberCombinations> fArraySumStepLengths;
// Array to collect the sum of step lengths in the scoring shells for the whole run,
// according to the various cases (scoring shell, kinematical region, scoring position
// and particle type).
@@ -26,64 +26,66 @@
/// \file TrackingAction.hh
/// \brief Definition of the TrackingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef TrackingAction_h
#ifndef TrackingAction_h
#define TrackingAction_h 1
#include "globals.hh"
#include "G4UserTrackingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class TrackingAction : public G4UserTrackingAction {
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the inner sphere (tracker), the middle spherical shell (EM calo),
// and the outmost spherical shell (HAD calo).
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
class TrackingAction : public G4UserTrackingAction
{
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the inner sphere (tracker), the middle spherical shell (EM calo),
// and the outmost spherical shell (HAD calo).
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
public:
TrackingAction();
~TrackingAction() override = default;
void PreUserTrackingAction( const G4Track* ) override;
void PostUserTrackingAction( const G4Track* ) override;
void PreUserTrackingAction(const G4Track*) override;
void PostUserTrackingAction(const G4Track*) override;
void Initialize();
// This method is called by RunAction::BeginOfRunAction for the
// initialization of the tracking-action at the beginning of each Run.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// tracking-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the tracking-action
// to the run object.
static const G4int fkNumberScoringVolumes = 3; // tracker, emCalo, hadCalo
static const G4int fkNumberScoringVolumes = 3; // tracker, emCalo, hadCalo
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
std::array< G4long, fkNumberCombinations > fArrayMultiplicities;
std::array< G4double, fkNumberCombinations > fArraySumKineticEnergies;
std::array<G4long, fkNumberCombinations> fArrayMultiplicities;
std::array<G4double, fkNumberCombinations> fArraySumKineticEnergies;
// Keep record of the number of particles and their kinetic energy at production,
// according to the particle type and their kinetic energy range (below/above 20 MeV).
};
@@ -32,11 +32,12 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "ActionInitialization.hh"
#include "PrimaryGeneratorAction.hh"
#include "Run.hh"
#include "RunAction.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,21 +45,23 @@ ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
void ActionInitialization::BuildForMaster() const
{
// This is NOT called in SEQ-mode, while in the MT-mode is called only for the Master thread.
SetUserAction( new RunAction );
SetUserAction(new RunAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
void ActionInitialization::Build() const
{
// This is called in the SEQ-mode and in the MT-mode only for Worker threads.
SetUserAction( new PrimaryGeneratorAction );
SetUserAction(new PrimaryGeneratorAction);
SteppingAction* steppingAction = new SteppingAction;
SetUserAction( steppingAction );
SetUserAction(steppingAction);
TrackingAction* trackingAction = new TrackingAction;
SetUserAction( trackingAction );
SetUserAction( new RunAction( steppingAction, trackingAction ) );
SetUserAction(trackingAction);
SetUserAction(new RunAction(steppingAction, trackingAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,66 +32,83 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
#include "G4Box.hh"
#include "G4GeometryManager.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Box.hh"
#include "G4Sphere.hh"
#include "G4LogicalVolume.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "globals.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4RunManager.hh"
#include "G4SolidStore.hh"
#include "G4Sphere.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction() :
fMaterialTracker( nullptr ), fMaterialEmCalo( nullptr ), fMaterialHadCalo( nullptr ),
fExperimentalHall_log( nullptr ), fExperimentalHall_phys( nullptr ),
fLogicTrackerShell( nullptr), fPhysiTrackerShell( nullptr ),
fLogicEmCaloShell( nullptr), fPhysiEmCaloShell( nullptr),
fLogicHadCaloShell( nullptr), fPhysiHadCaloShell( nullptr),
fLogicScoringTrackerShell( nullptr), fPhysiScoringTrackerShell( nullptr ),
fLogicScoringEmCaloShell( nullptr), fPhysiScoringEmCaloShell( nullptr),
fLogicScoringHadCaloShell( nullptr), fPhysiScoringHadCaloShell( nullptr),
fDetectorMessenger( nullptr ),
fInnerRadiusTracker( 10.0*cm ), fOuterRadiusTracker( 20.0*cm ), //***LOOKHERE*** Default radii
fInnerRadiusEmCalo( 30.0*cm ), fOuterRadiusEmCalo( 60.0*cm ),
fInnerRadiusHadCalo( 70.0*cm ), fOuterRadiusHadCalo( 170.0*cm )
DetectorConstruction::DetectorConstruction()
: fMaterialTracker(nullptr),
fMaterialEmCalo(nullptr),
fMaterialHadCalo(nullptr),
fExperimentalHall_log(nullptr),
fExperimentalHall_phys(nullptr),
fLogicTrackerShell(nullptr),
fPhysiTrackerShell(nullptr),
fLogicEmCaloShell(nullptr),
fPhysiEmCaloShell(nullptr),
fLogicHadCaloShell(nullptr),
fPhysiHadCaloShell(nullptr),
fLogicScoringTrackerShell(nullptr),
fPhysiScoringTrackerShell(nullptr),
fLogicScoringEmCaloShell(nullptr),
fPhysiScoringEmCaloShell(nullptr),
fLogicScoringHadCaloShell(nullptr),
fPhysiScoringHadCaloShell(nullptr),
fDetectorMessenger(nullptr),
fInnerRadiusTracker(10.0 * cm),
fOuterRadiusTracker(20.0 * cm), //***LOOKHERE*** Default radii
fInnerRadiusEmCalo(30.0 * cm),
fOuterRadiusEmCalo(60.0 * cm),
fInnerRadiusHadCalo(70.0 * cm),
fOuterRadiusHadCalo(170.0 * cm)
{
//G4cout << " BEGIN DetectorConstruction::DetectorConstruction()" << G4endl;
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Si" ); //***LOOKHERE***
// Default material
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial( "G4_PbWO4" );
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" );
fDetectorMessenger = new DetectorMessenger( this );
//G4cout << " END DetectorConstruction::DetectorConstruction()" << G4endl;
// G4cout << " BEGIN DetectorConstruction::DetectorConstruction()" << G4endl;
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si"); //***LOOKHERE***
// Default material
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial("G4_PbWO4");
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe");
fDetectorMessenger = new DetectorMessenger(this);
// G4cout << " END DetectorConstruction::DetectorConstruction()" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction() {
DetectorConstruction::~DetectorConstruction()
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct() {
//G4cout << " BEGIN DetectorConstruction::Construct()" << G4endl;
G4VPhysicalVolume* DetectorConstruction::Construct()
{
// G4cout << " BEGIN DetectorConstruction::Construct()" << G4endl;
return ConstructDetector();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructDetector() {
//G4cout << " BEGIN DetectorConstruction::ConstructDetector()" << G4endl;
G4VPhysicalVolume* DetectorConstruction::ConstructDetector()
{
// G4cout << " BEGIN DetectorConstruction::ConstructDetector()" << G4endl;
// Clean old geometry, if any.
G4GeometryManager::GetInstance()->OpenGeometry();
@@ -102,308 +119,301 @@ G4VPhysicalVolume* DetectorConstruction::ConstructDetector() {
// Check that the radii are resonable
G4bool isOK = true;
if ( fInnerRadiusTracker < 0.0 ||
fOuterRadiusTracker < fInnerRadiusTracker ||
fInnerRadiusEmCalo < fOuterRadiusTracker + fScoringThickness ||
fOuterRadiusEmCalo < fInnerRadiusEmCalo ||
fInnerRadiusHadCalo < fOuterRadiusEmCalo + fScoringThickness ||
fOuterRadiusHadCalo < fInnerRadiusHadCalo ) {
if (fInnerRadiusTracker < 0.0 || fOuterRadiusTracker < fInnerRadiusTracker
|| fInnerRadiusEmCalo < fOuterRadiusTracker + fScoringThickness
|| fOuterRadiusEmCalo < fInnerRadiusEmCalo
|| fInnerRadiusHadCalo < fOuterRadiusEmCalo + fScoringThickness
|| fOuterRadiusHadCalo < fInnerRadiusHadCalo)
{
isOK = false;
}
if ( ! isOK ) {
if (!isOK) {
G4cerr << G4endl << "ERROR: the radii are inconsistent !" << G4endl
<< " InnerRadiusTracker = " << fInnerRadiusTracker << " mm" << G4endl
<< " OuterRadiusTracker = " << fOuterRadiusTracker << " mm" << G4endl
<< " InnerRadiusEmCalo = " << fInnerRadiusEmCalo << " mm" << G4endl
<< " OuterRadiusEmCalo = " << fOuterRadiusEmCalo << " mm" << G4endl
<< " InnerRadiusEmCalo = " << fInnerRadiusEmCalo << " mm" << G4endl
<< " OuterRadiusEmCalo = " << fOuterRadiusEmCalo << " mm" << G4endl
<< " InnerRadiusHadCalo = " << fInnerRadiusHadCalo << " mm" << G4endl
<< " OuterRadiusHadCalo = " << fOuterRadiusHadCalo << " mm" << G4endl
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< G4endl;
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl << G4endl;
return nullptr;
}
// The detector consists of 3 concentric full spherical shells (G4Sphere),
// positioned at the center, (0.0, 0.0, 0.0).
// The world volume (experimental hall) is a box 10% bigger than the outmost
// spherical shell.
// and it is filled of "G4_Galactic" material.
G4double expHall_x = 1.1*fOuterRadiusHadCalo; // half dimension along x
G4double expHall_y = 1.1*fOuterRadiusHadCalo; // half dimension along y
G4double expHall_z = 1.1*fOuterRadiusHadCalo; // half dimension along z
G4double expHall_x = 1.1 * fOuterRadiusHadCalo; // half dimension along x
G4double expHall_y = 1.1 * fOuterRadiusHadCalo; // half dimension along y
G4double expHall_z = 1.1 * fOuterRadiusHadCalo; // half dimension along z
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Galactic" );
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box* experimentalHall_box = new G4Box( "expHall_box", expHall_x, expHall_y, expHall_z );
G4Box* experimentalHall_box = new G4Box("expHall_box", expHall_x, expHall_y, expHall_z);
fExperimentalHall_log = new G4LogicalVolume( experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fExperimentalHall_log = new G4LogicalVolume(experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0); // user limits
fExperimentalHall_phys = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0 ); // copy number
fExperimentalHall_phys = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0); // copy number
// 1st (innermost) spherical shell: Tracker
G4Sphere* solidTrackerShell = new G4Sphere( "solidTrackerShell", // name
fInnerRadiusTracker, // Inner radius
fOuterRadiusTracker, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0*CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi ); // Delta Theta angle of the
// segment in radians
fLogicTrackerShell = new G4LogicalVolume( solidTrackerShell, // solid
fMaterialTracker, // material
"logicTrackerShell", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiTrackerShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiTrackerShell", // name
fLogicTrackerShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
// 1st (innermost) spherical shell: Tracker
G4Sphere* solidTrackerShell = new G4Sphere("solidTrackerShell", // name
fInnerRadiusTracker, // Inner radius
fOuterRadiusTracker, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0 * CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi); // Delta Theta angle of the
// segment in radians
fLogicTrackerShell = new G4LogicalVolume(solidTrackerShell, // solid
fMaterialTracker, // material
"logicTrackerShell", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiTrackerShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiTrackerShell", // name
fLogicTrackerShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
// Scoring tracker shell (a thin vacuum layer, immediately outside the Tracker shell)
G4Sphere* solidScoringTrackerShell =
new G4Sphere( "solidScoringTrackerShell", // name
fOuterRadiusTracker, // Inner radius
fOuterRadiusTracker + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the segment
// in radians
2.0*CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the segment
// in radians
CLHEP::pi ); // Delta Theta angle of the segment
// in radians
fLogicScoringTrackerShell = new G4LogicalVolume( solidScoringTrackerShell, // solid
vacuum, // material
"logicScoringTrackerShell", // name
0, // field manager
0, // sensitive
// detector
0 ); // user limits
fPhysiScoringTrackerShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiScoringTrackerShell", // name
fLogicScoringTrackerShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean
// operation
0 ); // copy number
// 2nd (middle) spherical shell: EM Calo
G4Sphere* solidEmCaloShell = new G4Sphere( "solidEmCaloShell", // name
fInnerRadiusEmCalo, // Inner radius
fOuterRadiusEmCalo, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0*CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi ); // Delta Theta angle of the
// segment in radians
fLogicEmCaloShell = new G4LogicalVolume( solidEmCaloShell, // solid
fMaterialEmCalo, // material
"logicEmCaloShell", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiEmCaloShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiEmCaloShell", // name
fLogicEmCaloShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
new G4Sphere("solidScoringTrackerShell", // name
fOuterRadiusTracker, // Inner radius
fOuterRadiusTracker + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the segment
// in radians
2.0 * CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the segment
// in radians
CLHEP::pi); // Delta Theta angle of the segment
// in radians
fLogicScoringTrackerShell = new G4LogicalVolume(solidScoringTrackerShell, // solid
vacuum, // material
"logicScoringTrackerShell", // name
0, // field manager
0, // sensitive
// detector
0); // user limits
fPhysiScoringTrackerShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiScoringTrackerShell", // name
fLogicScoringTrackerShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean
// operation
0); // copy number
// 2nd (middle) spherical shell: EM Calo
G4Sphere* solidEmCaloShell = new G4Sphere("solidEmCaloShell", // name
fInnerRadiusEmCalo, // Inner radius
fOuterRadiusEmCalo, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0 * CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi); // Delta Theta angle of the
// segment in radians
fLogicEmCaloShell = new G4LogicalVolume(solidEmCaloShell, // solid
fMaterialEmCalo, // material
"logicEmCaloShell", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiEmCaloShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiEmCaloShell", // name
fLogicEmCaloShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
// Scoring EmCalo shell (a thin vacuum layer, immediately outside the EmCalo shell)
G4Sphere* solidScoringEmCaloShell =
new G4Sphere( "solidScoringEmCaloShell", // name
fOuterRadiusEmCalo, // Inner radius
fOuterRadiusEmCalo + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the segment
// in radians
2.0*CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi ); // Delta Theta angle of the segment
// in radians
fLogicScoringEmCaloShell = new G4LogicalVolume( solidScoringEmCaloShell, // solid
vacuum, // material
"logicScoringEmCaloShell", // name
0, // field manager
0, // sensitive
// detector
0 ); // user limits
fPhysiScoringEmCaloShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiScoringEmCaloShell", // name
fLogicScoringEmCaloShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean operation
0 ); // copy number
// 3rd (outmost) spherical shell: HAD Calo
G4Sphere* solidHadCaloShell = new G4Sphere( "solidHadCaloShell", // name
fInnerRadiusHadCalo, // Inner radius
fOuterRadiusHadCalo, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0*CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi ); // Delta Theta angle of the
// segment in radians
fLogicHadCaloShell = new G4LogicalVolume( solidHadCaloShell, // solid
fMaterialHadCalo, // material
"logicHadCaloShell", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiHadCaloShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiHadCaloShell", // name
fLogicHadCaloShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
new G4Sphere("solidScoringEmCaloShell", // name
fOuterRadiusEmCalo, // Inner radius
fOuterRadiusEmCalo + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the segment
// in radians
2.0 * CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi); // Delta Theta angle of the segment
// in radians
fLogicScoringEmCaloShell = new G4LogicalVolume(solidScoringEmCaloShell, // solid
vacuum, // material
"logicScoringEmCaloShell", // name
0, // field manager
0, // sensitive
// detector
0); // user limits
fPhysiScoringEmCaloShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiScoringEmCaloShell", // name
fLogicScoringEmCaloShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean operation
0); // copy number
// 3rd (outmost) spherical shell: HAD Calo
G4Sphere* solidHadCaloShell = new G4Sphere("solidHadCaloShell", // name
fInnerRadiusHadCalo, // Inner radius
fOuterRadiusHadCalo, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0 * CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi); // Delta Theta angle of the
// segment in radians
fLogicHadCaloShell = new G4LogicalVolume(solidHadCaloShell, // solid
fMaterialHadCalo, // material
"logicHadCaloShell", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiHadCaloShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiHadCaloShell", // name
fLogicHadCaloShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
// Scoring HadCalo shell (a thin vacuum layer, immediately outside the HadCalo shell)
G4Sphere* solidScoringHadCaloShell =
new G4Sphere( "solidScoringHadCaloShell", // name
fOuterRadiusHadCalo, // Inner radius
fOuterRadiusHadCalo + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0*CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi ); // Delta Theta angle of the segment
// in radians
fLogicScoringHadCaloShell = new G4LogicalVolume( solidScoringHadCaloShell, // solid
vacuum, // material
"logicScoringHadCaloShell", // name
0, // field manager
0, // sensitive
// detector
0 ); // user limits
fPhysiScoringHadCaloShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiScoringHadCaloShell", // name
fLogicScoringHadCaloShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean
// operation
0 ); // copy number
new G4Sphere("solidScoringHadCaloShell", // name
fOuterRadiusHadCalo, // Inner radius
fOuterRadiusHadCalo + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0 * CLHEP::pi, // Delta Phi angle of the segment
// in radians
0.0, // Starting Theta angle of the
// segment in radians
CLHEP::pi); // Delta Theta angle of the segment
// in radians
fLogicScoringHadCaloShell = new G4LogicalVolume(solidScoringHadCaloShell, // solid
vacuum, // material
"logicScoringHadCaloShell", // name
0, // field manager
0, // sensitive
// detector
0); // user limits
fPhysiScoringHadCaloShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiScoringHadCaloShell", // name
fLogicScoringHadCaloShell, // logical volume
fExperimentalHall_phys, // mother physical
// volume
false, // boolean
// operation
0); // copy number
G4cout << "DetectorConstruction::ConstructSphere() : " << G4endl
<< "\t World (box) size: " << G4endl
<< "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl
<< G4endl;
<< "\t World (box) size: " << G4endl << "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl << G4endl;
PrintParameters();
//G4cout << " END DetectorConstruction::ConstructDetector()
// G4cout << " END DetectorConstruction::ConstructDetector()
return fExperimentalHall_phys;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterialTracker( const G4String name ) {
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial( name );
if ( ! fMaterialTracker ) {
G4cout << G4endl << G4endl
<< "WARNING: the name of the material has not been recognized!" << G4endl
<< " ===> the default * G4_Si * will be used."
<< G4endl << G4endl;
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Si" );
void DetectorConstruction::SetMaterialTracker(const G4String name)
{
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial(name);
if (!fMaterialTracker) {
G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!"
<< G4endl << " ===> the default * G4_Si * will be used." << G4endl << G4endl;
fMaterialTracker = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
}
if ( fLogicTrackerShell ) fLogicTrackerShell->SetMaterial( fMaterialTracker );
if (fLogicTrackerShell) fLogicTrackerShell->SetMaterial(fMaterialTracker);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterialEmCalo( const G4String name ) {
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial( name );
if ( ! fMaterialEmCalo ) {
G4cout << G4endl << G4endl
<< "WARNING: the name of the material has not been recognized!" << G4endl
<< " ===> the default * G4_Pb * will be used."
<< G4endl << G4endl;
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Pb" );
void DetectorConstruction::SetMaterialEmCalo(const G4String name)
{
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial(name);
if (!fMaterialEmCalo) {
G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!"
<< G4endl << " ===> the default * G4_Pb * will be used." << G4endl << G4endl;
fMaterialEmCalo = G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb");
}
if ( fLogicEmCaloShell ) fLogicEmCaloShell->SetMaterial( fMaterialEmCalo );
if (fLogicEmCaloShell) fLogicEmCaloShell->SetMaterial(fMaterialEmCalo);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterialHadCalo( const G4String name ) {
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial( name );
if ( fMaterialHadCalo == nullptr ) {
G4cout << G4endl << G4endl
<< "WARNING: the name of the material has not been recognized!" << G4endl
<< " ===> the default * G4_Fe * will be used."
<< G4endl << G4endl;
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" );
void DetectorConstruction::SetMaterialHadCalo(const G4String name)
{
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial(name);
if (fMaterialHadCalo == nullptr) {
G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!"
<< G4endl << " ===> the default * G4_Fe * will be used." << G4endl << G4endl;
fMaterialHadCalo = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe");
}
if ( fLogicHadCaloShell ) fLogicHadCaloShell->SetMaterial( fMaterialHadCalo );
if (fLogicHadCaloShell) fLogicHadCaloShell->SetMaterial(fMaterialHadCalo);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::UpdateGeometry() {
//G4cout << " BEGIN DetectorConstruction::UpdateGeometry" << G4endl;
void DetectorConstruction::UpdateGeometry()
{
// G4cout << " BEGIN DetectorConstruction::UpdateGeometry" << G4endl;
G4RunManager::GetRunManager()->ReinitializeGeometry();
PrintParameters();
// Update also the position of the gun
const PrimaryGeneratorAction* pPrimaryAction =
dynamic_cast< const PrimaryGeneratorAction* >
( G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction() );
if ( pPrimaryAction ) pPrimaryAction->SetGunPosition();
//G4cout << " END DetectorConstruction::UpdateGeometry" << G4endl;
const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast<const PrimaryGeneratorAction*>(
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
if (pPrimaryAction) pPrimaryAction->SetGunPosition();
// G4cout << " END DetectorConstruction::UpdateGeometry" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::PrintParameters() {
G4cout << G4endl
<< " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
void DetectorConstruction::PrintParameters()
{
G4cout << G4endl << " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
<< " MaterialTracker = " << fMaterialTracker->GetName() << G4endl
<< " MaterialEmCalo = " << fMaterialEmCalo->GetName() << G4endl
<< " MaterialHadCalo = " << fMaterialHadCalo->GetName() << G4endl
<< " InnerRadiusTracker = " << fInnerRadiusTracker << " mm" << G4endl
<< " OuterRadiusTracker = " << fOuterRadiusTracker << " mm" << G4endl
<< " InnerRadiusEmCalo = " << fInnerRadiusEmCalo << " mm" << G4endl
<< " OuterRadiusEmCalo = " << fOuterRadiusEmCalo << " mm" << G4endl
<< " InnerRadiusEmCalo = " << fInnerRadiusEmCalo << " mm" << G4endl
<< " OuterRadiusEmCalo = " << fOuterRadiusEmCalo << " mm" << G4endl
<< " InnerRadiusHadCalo = " << fInnerRadiusHadCalo << " mm" << G4endl
<< " OuterRadiusHadCalo = " << fOuterRadiusHadCalo << " mm" << G4endl
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< " -------------------------------------------------------- " << G4endl
<< G4endl;
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< " -------------------------------------------------------- " << G4endl << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,86 +32,90 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorMessenger.hh"
#include "DetectorConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIdirectory.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* myDet ) : fDetector( myDet ) {
fDetectorDir = new G4UIdirectory( "/mydet/" );
fDetectorDir->SetGuidance( "Detector control." );
DetectorMessenger::DetectorMessenger(DetectorConstruction* myDet) : fDetector(myDet)
{
fDetectorDir = new G4UIdirectory("/mydet/");
fDetectorDir->SetGuidance("Detector control.");
fMaterialTracker = new G4UIcmdWithAString( "/mydet/material_tracker", this );
fMaterialTracker->SetGuidance( "Choice of the material for the Tracker:" );
fMaterialTracker->SetGuidance( " a Geant4 NIST material, e.g. G4_Si " );
fMaterialTracker->SetParameterName( "choiceMaterial", true );
fMaterialTracker->SetDefaultValue( "G4_Si" );
fMaterialTracker->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterialTracker = new G4UIcmdWithAString("/mydet/material_tracker", this);
fMaterialTracker->SetGuidance("Choice of the material for the Tracker:");
fMaterialTracker->SetGuidance(" a Geant4 NIST material, e.g. G4_Si ");
fMaterialTracker->SetParameterName("choiceMaterial", true);
fMaterialTracker->SetDefaultValue("G4_Si");
fMaterialTracker->AvailableForStates(G4State_PreInit, G4State_Idle);
fMaterialEmCalo = new G4UIcmdWithAString( "/mydet/material_emCalo", this );
fMaterialEmCalo->SetGuidance( "Choice of the material for the EM calo:" );
fMaterialEmCalo->SetGuidance( " a Geant4 NIST material, e.g. G4_Pb " );
fMaterialEmCalo->SetParameterName( "choiceMaterial", true );
fMaterialEmCalo->SetDefaultValue( "G4_Pb" );
fMaterialEmCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterialHadCalo = new G4UIcmdWithAString( "/mydet/material_hadCalo", this );
fMaterialHadCalo->SetGuidance( "Choice of the material for the HAD calo:" );
fMaterialHadCalo->SetGuidance( " a Geant4 NIST material, e.g. G4_Fe " );
fMaterialHadCalo->SetParameterName( "choiceMaterial", true );
fMaterialHadCalo->SetDefaultValue( "G4_Fe" );
fMaterialHadCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fInnerRadiusTracker = new G4UIcmdWithADoubleAndUnit( "/mydet/inner_radius_tracker", this );
fInnerRadiusTracker->SetParameterName( "choiceInnerRadiusTracker", true );
fInnerRadiusTracker->SetGuidance( "Inner radius of the Tracker" );
fInnerRadiusTracker->SetDefaultValue( 100.0 ); // default: 10 cm.
fInnerRadiusTracker->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterialEmCalo = new G4UIcmdWithAString("/mydet/material_emCalo", this);
fMaterialEmCalo->SetGuidance("Choice of the material for the EM calo:");
fMaterialEmCalo->SetGuidance(" a Geant4 NIST material, e.g. G4_Pb ");
fMaterialEmCalo->SetParameterName("choiceMaterial", true);
fMaterialEmCalo->SetDefaultValue("G4_Pb");
fMaterialEmCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fOuterRadiusTracker = new G4UIcmdWithADoubleAndUnit( "/mydet/outer_radius_tracker", this );
fOuterRadiusTracker->SetParameterName( "choiceOuterRadiusTracker", true );
fOuterRadiusTracker->SetGuidance( "Outer radius of the Tracker" );
fOuterRadiusTracker->SetDefaultValue( 200.0 ); // default: 20 cm.
fOuterRadiusTracker->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterialHadCalo = new G4UIcmdWithAString("/mydet/material_hadCalo", this);
fMaterialHadCalo->SetGuidance("Choice of the material for the HAD calo:");
fMaterialHadCalo->SetGuidance(" a Geant4 NIST material, e.g. G4_Fe ");
fMaterialHadCalo->SetParameterName("choiceMaterial", true);
fMaterialHadCalo->SetDefaultValue("G4_Fe");
fMaterialHadCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fInnerRadiusEmCalo = new G4UIcmdWithADoubleAndUnit( "/mydet/inner_radius_emCalo", this );
fInnerRadiusEmCalo->SetParameterName( "choiceInnerRadiusEmCalo", true );
fInnerRadiusEmCalo->SetGuidance( "Inner radius of the EM Calo" );
fInnerRadiusEmCalo->SetDefaultValue( 300.0 ); // default: 30 cm.
fInnerRadiusEmCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fInnerRadiusTracker = new G4UIcmdWithADoubleAndUnit("/mydet/inner_radius_tracker", this);
fInnerRadiusTracker->SetParameterName("choiceInnerRadiusTracker", true);
fInnerRadiusTracker->SetGuidance("Inner radius of the Tracker");
fInnerRadiusTracker->SetDefaultValue(100.0); // default: 10 cm.
fInnerRadiusTracker->AvailableForStates(G4State_PreInit, G4State_Idle);
fOuterRadiusEmCalo = new G4UIcmdWithADoubleAndUnit( "/mydet/outer_radius_emCalo", this );
fOuterRadiusEmCalo->SetParameterName( "choiceOuterRadiusEmCalo", true );
fOuterRadiusEmCalo->SetGuidance( "Outer radius of the EM Calo" );
fOuterRadiusEmCalo->SetDefaultValue( 600.0 ); // default: 60 cm.
fOuterRadiusEmCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fInnerRadiusHadCalo = new G4UIcmdWithADoubleAndUnit( "/mydet/inner_radius_hadCalo", this );
fInnerRadiusHadCalo->SetParameterName( "choiceInnerRadiusHadCalo", true );
fInnerRadiusHadCalo->SetGuidance( "Inner radius of the HAD Calo" );
fInnerRadiusHadCalo->SetDefaultValue( 700.0 ); // default: 70 cm.
fInnerRadiusHadCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fOuterRadiusTracker = new G4UIcmdWithADoubleAndUnit("/mydet/outer_radius_tracker", this);
fOuterRadiusTracker->SetParameterName("choiceOuterRadiusTracker", true);
fOuterRadiusTracker->SetGuidance("Outer radius of the Tracker");
fOuterRadiusTracker->SetDefaultValue(200.0); // default: 20 cm.
fOuterRadiusTracker->AvailableForStates(G4State_PreInit, G4State_Idle);
fOuterRadiusHadCalo = new G4UIcmdWithADoubleAndUnit( "/mydet/outer_radius_hadCalo", this );
fOuterRadiusHadCalo->SetParameterName( "choiceOuterRadiusHadCalo", true );
fOuterRadiusHadCalo->SetGuidance( "Outer radius of the HAD Calo" );
fOuterRadiusHadCalo->SetDefaultValue( 1700.0 ); // default: 170 cm.
fOuterRadiusHadCalo->AvailableForStates( G4State_PreInit, G4State_Idle );
fUpdateCommand = new G4UIcmdWithoutParameter( "/mydet/update", this);
fUpdateCommand->SetGuidance( "Update geometry." );
fUpdateCommand->SetGuidance( "This command MUST be applied before \"beamOn\" " );
fUpdateCommand->SetGuidance( "if you changed geometrical value(s)." );
fUpdateCommand->AvailableForStates( G4State_Idle );
fInnerRadiusEmCalo = new G4UIcmdWithADoubleAndUnit("/mydet/inner_radius_emCalo", this);
fInnerRadiusEmCalo->SetParameterName("choiceInnerRadiusEmCalo", true);
fInnerRadiusEmCalo->SetGuidance("Inner radius of the EM Calo");
fInnerRadiusEmCalo->SetDefaultValue(300.0); // default: 30 cm.
fInnerRadiusEmCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fOuterRadiusEmCalo = new G4UIcmdWithADoubleAndUnit("/mydet/outer_radius_emCalo", this);
fOuterRadiusEmCalo->SetParameterName("choiceOuterRadiusEmCalo", true);
fOuterRadiusEmCalo->SetGuidance("Outer radius of the EM Calo");
fOuterRadiusEmCalo->SetDefaultValue(600.0); // default: 60 cm.
fOuterRadiusEmCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fInnerRadiusHadCalo = new G4UIcmdWithADoubleAndUnit("/mydet/inner_radius_hadCalo", this);
fInnerRadiusHadCalo->SetParameterName("choiceInnerRadiusHadCalo", true);
fInnerRadiusHadCalo->SetGuidance("Inner radius of the HAD Calo");
fInnerRadiusHadCalo->SetDefaultValue(700.0); // default: 70 cm.
fInnerRadiusHadCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fOuterRadiusHadCalo = new G4UIcmdWithADoubleAndUnit("/mydet/outer_radius_hadCalo", this);
fOuterRadiusHadCalo->SetParameterName("choiceOuterRadiusHadCalo", true);
fOuterRadiusHadCalo->SetGuidance("Outer radius of the HAD Calo");
fOuterRadiusHadCalo->SetDefaultValue(1700.0); // default: 170 cm.
fOuterRadiusHadCalo->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter("/mydet/update", this);
fUpdateCommand->SetGuidance("Update geometry.");
fUpdateCommand->SetGuidance("This command MUST be applied before \"beamOn\" ");
fUpdateCommand->SetGuidance("if you changed geometrical value(s).");
fUpdateCommand->AvailableForStates(G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::~DetectorMessenger() {
DetectorMessenger::~DetectorMessenger()
{
delete fDetectorDir;
delete fMaterialTracker;
delete fMaterialEmCalo;
@@ -127,35 +131,36 @@ DetectorMessenger::~DetectorMessenger() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue( G4UIcommand* command, G4String newValue ) {
if ( command == fMaterialTracker ) {
fDetector->SetMaterialTracker( newValue );
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fMaterialTracker) {
fDetector->SetMaterialTracker(newValue);
}
if ( command == fMaterialEmCalo ) {
fDetector->SetMaterialEmCalo( newValue );
if (command == fMaterialEmCalo) {
fDetector->SetMaterialEmCalo(newValue);
}
if ( command == fMaterialHadCalo ) {
fDetector->SetMaterialHadCalo( newValue );
}
if ( command == fInnerRadiusTracker ) {
fDetector->SetInnerRadiusTracker( fInnerRadiusTracker->GetNewDoubleValue( newValue ) );
if (command == fMaterialHadCalo) {
fDetector->SetMaterialHadCalo(newValue);
}
if ( command == fOuterRadiusTracker ) {
fDetector->SetOuterRadiusTracker( fOuterRadiusTracker->GetNewDoubleValue( newValue ) );
if (command == fInnerRadiusTracker) {
fDetector->SetInnerRadiusTracker(fInnerRadiusTracker->GetNewDoubleValue(newValue));
}
if ( command == fInnerRadiusEmCalo ) {
fDetector->SetInnerRadiusEmCalo( fInnerRadiusEmCalo->GetNewDoubleValue( newValue ) );
if (command == fOuterRadiusTracker) {
fDetector->SetOuterRadiusTracker(fOuterRadiusTracker->GetNewDoubleValue(newValue));
}
if ( command == fOuterRadiusEmCalo ) {
fDetector->SetOuterRadiusEmCalo( fOuterRadiusEmCalo->GetNewDoubleValue( newValue ) );
if (command == fInnerRadiusEmCalo) {
fDetector->SetInnerRadiusEmCalo(fInnerRadiusEmCalo->GetNewDoubleValue(newValue));
}
if ( command == fInnerRadiusHadCalo ) {
fDetector->SetInnerRadiusHadCalo( fInnerRadiusHadCalo->GetNewDoubleValue( newValue ) );
if (command == fOuterRadiusEmCalo) {
fDetector->SetOuterRadiusEmCalo(fOuterRadiusEmCalo->GetNewDoubleValue(newValue));
}
if ( command == fOuterRadiusHadCalo ) {
fDetector->SetOuterRadiusHadCalo( fOuterRadiusHadCalo->GetNewDoubleValue( newValue ) );
if (command == fInnerRadiusHadCalo) {
fDetector->SetInnerRadiusHadCalo(fInnerRadiusHadCalo->GetNewDoubleValue(newValue));
}
if ( command == fUpdateCommand ) {
if (command == fOuterRadiusHadCalo) {
fDetector->SetOuterRadiusHadCalo(fOuterRadiusHadCalo->GetNewDoubleValue(newValue));
}
if (command == fUpdateCommand) {
fDetector->UpdateGeometry();
}
}
@@ -32,45 +32,50 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "PrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction() : G4VUserPrimaryGeneratorAction(),
fParticleGun( nullptr ) {
PrimaryGeneratorAction::PrimaryGeneratorAction()
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun( n_particle );
fParticleGun = new G4ParticleGun(n_particle);
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition( particleTable->FindParticle( "geantino" ) );
fParticleGun->SetParticleEnergy( 10.0*GeV );
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition(particleTable->FindParticle("geantino"));
fParticleGun->SetParticleEnergy(10.0 * GeV);
SetGunPosition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete fParticleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::SetGunPosition() const {
void PrimaryGeneratorAction::SetGunPosition() const
{
// Shoot the particle from the center of the sphere
fParticleGun->SetParticlePosition( G4ThreeVector( 0.0, 0.0, 0.0 ) );
fParticleGun->SetParticlePosition(G4ThreeVector(0.0, 0.0, 0.0));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries( G4Event* anEvent ) {
G4ThreeVector v( 0.0, 0.0, 1.0 ); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection( v );
fParticleGun->GeneratePrimaryVertex( anEvent );
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
G4ThreeVector v(0.0, 0.0, 1.0); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection(v);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,40 +32,49 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "Run.hh"
#include "G4SystemOfUnits.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() : G4Run(), fNumEvents( 0 ),
fPrimaryParticleId( 0 ), fPrimaryParticleEnergy( 0.0 ),
fPrimaryParticleDirection( G4ThreeVector( 0.0, 0.0, 0.0 ) ),
fTrackerMaterialName( "" ), fEmCaloMaterialName( "" ), fHadCaloMaterialName( "" ),
fCubicVolumeScoringTrackerShell( 1.0 ), fCubicVolumeScoringEmCaloShell( 1.0 ),
fCubicVolumeScoringHadCaloShell( 1.0 )
Run::Run()
: G4Run(),
fNumEvents(0),
fPrimaryParticleId(0),
fPrimaryParticleEnergy(0.0),
fPrimaryParticleDirection(G4ThreeVector(0.0, 0.0, 0.0)),
fTrackerMaterialName(""),
fEmCaloMaterialName(""),
fHadCaloMaterialName(""),
fCubicVolumeScoringTrackerShell(1.0),
fCubicVolumeScoringEmCaloShell(1.0),
fCubicVolumeScoringHadCaloShell(1.0)
{
fSteppingArray.fill( 0.0 );
fTrackingArray1.fill( 0 );
fTrackingArray2.fill( 0.0 );
fSteppingArray.fill(0.0);
fTrackingArray1.fill(0);
fTrackingArray2.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::RecordEvent( const G4Event* anEvent ) {
void Run::RecordEvent(const G4Event* anEvent)
{
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event : in MT-mode, it is called only for the working thread that handled the event.
G4int nEvt = anEvent->GetEventID();
if ( nEvt % 10 == 0 ) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent( anEvent );
if (nEvt % 10 == 0) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge( const G4Run* aRun ) {
void Run::Merge(const G4Run* aRun)
{
// This method is called automatically by the Geant4 kernel (not by the user!) only in the case
// of multithreaded mode and only for working threads.
const Run* localRun = static_cast< const Run* >( aRun );
const Run* localRun = static_cast<const Run*>(aRun);
fPrimaryParticleId = localRun->GetPrimaryParticleId();
fPrimaryParticleEnergy = localRun->GetPrimaryParticleEnergy();
fPrimaryParticleDirection = localRun->GetPrimaryParticleDirection();
@@ -76,67 +85,66 @@ void Run::Merge( const G4Run* aRun ) {
fCubicVolumeScoringEmCaloShell = localRun->GetCubicVolumeScoringEmCaloShell();
fCubicVolumeScoringHadCaloShell = localRun->GetCubicVolumeScoringHadCaloShell();
fNumEvents += localRun->GetNumberOfEvent();
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] += localRun->GetSteppingArray()[i];
}
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] += localRun->GetTrackingArray1()[i];
fTrackingArray2[i] += localRun->GetTrackingArray2()[i];
}
G4Run::Merge( aRun );
G4Run::Merge(aRun);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::PrintInfo() const {
void Run::PrintInfo() const
{
// This method is called by RunAction::EndOfRunAction.
// In MT-mode, only the master thread calls it.
const G4double floatingNumberOfEvents =
std::max( 1.0, fNumEvents > 0 ? fNumEvents*1.0 : GetNumberOfEvent()*1.0 );
std::max(1.0, fNumEvents > 0 ? fNumEvents * 1.0 : GetNumberOfEvent() * 1.0);
// The fluence in a scoring shell is defined as sum of step lengths in that shell
// divided by the cubic-volume of the scoring shell.
const G4double conversionFactor = CLHEP::cm * CLHEP::cm; // From mm^-2 to cm^-2
const G4double factorTracker =
conversionFactor / ( 0.5*fCubicVolumeScoringTrackerShell*floatingNumberOfEvents );
const G4double factorEmCalo =
conversionFactor / ( 0.5*fCubicVolumeScoringEmCaloShell*floatingNumberOfEvents );
conversionFactor / (0.5 * fCubicVolumeScoringTrackerShell * floatingNumberOfEvents);
const G4double factorEmCalo =
conversionFactor / (0.5 * fCubicVolumeScoringEmCaloShell * floatingNumberOfEvents);
const G4double factorHadCalo =
conversionFactor / ( 0.5*fCubicVolumeScoringHadCaloShell*floatingNumberOfEvents );
conversionFactor / (0.5 * fCubicVolumeScoringHadCaloShell * floatingNumberOfEvents);
G4cout << std::setprecision(6) << G4endl << G4endl
<< " =============== Run::PrintInfo() =============== \t RunID = " << GetRunID()
<< G4endl
<< " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV
<< " GeV" << G4endl
<< " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< G4endl << " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV << " GeV"
<< G4endl << " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< " Tracker material = " << fTrackerMaterialName << G4endl
<< " EmCalo material = " << fEmCaloMaterialName << G4endl
<< " HadCalo material = " << fHadCaloMaterialName << G4endl
<< " Cubic-volume scoring tracker shell = " << fCubicVolumeScoringTrackerShell
<< " Cubic-volume scoring tracker shell = " << fCubicVolumeScoringTrackerShell << " mm^3"
<< G4endl << " Cubic-volume scoring emCalo shell = " << fCubicVolumeScoringEmCaloShell
<< " mm^3" << G4endl
<< " Cubic-volume scoring emCalo shell = " << fCubicVolumeScoringEmCaloShell
<< " mm^3" << G4endl
<< " Cubic-volume scoring hadCalo shell = " << fCubicVolumeScoringHadCaloShell
<< " mm^3" << G4endl
<< " Number of events = " << floatingNumberOfEvents << G4endl
<< " Cubic-volume scoring hadCalo shell = " << fCubicVolumeScoringHadCaloShell << " mm^3"
<< G4endl << " Number of events = " << floatingNumberOfEvents << G4endl
<< " Conversion factor: fluence from mm^-2 to cm^-2 = " << conversionFactor << G4endl
<< " Particle fluence in unit of cm^-2 :" << G4endl;
for ( G4int i = 0; i < SteppingAction::fkNumberScoringShells; ++i ) {
for (G4int i = 0; i < SteppingAction::fkNumberScoringShells; ++i) {
G4double factor = factorTracker;
if ( i == 1 ) factor = factorEmCalo;
else if ( i == 2 ) factor = factorHadCalo;
for ( G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < SteppingAction::fkNumberScoringPositions; ++k ) {
for ( G4int ll = 0; ll < SteppingAction::fkNumberParticleTypes; ++ll ) {
G4int index = SteppingAction::GetIndex( i, j, k, ll );
//G4cout << "(i, j, k, ll)=(" << i << ", " << j << ", " << k << ", "
// << ll << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << SteppingAction::fkArrayScoringShellNames[i]
<< " " << std::setw(12) << SteppingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << SteppingAction::fkArrayScoringPositionNames[k]
<< " " << std::setw(12) << SteppingAction::fkArrayParticleTypeNames[ll]
<< " " << std::setw( 8) << factor*fSteppingArray[index] << G4endl;
if (i == 1)
factor = factorEmCalo;
else if (i == 2)
factor = factorHadCalo;
for (G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < SteppingAction::fkNumberScoringPositions; ++k) {
for (G4int ll = 0; ll < SteppingAction::fkNumberParticleTypes; ++ll) {
G4int index = SteppingAction::GetIndex(i, j, k, ll);
// G4cout << "(i, j, k, ll)=(" << i << ", " << j << ", " << k << ", "
// << ll << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< SteppingAction::fkArrayScoringShellNames[i] << " " << std::setw(12)
<< SteppingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< SteppingAction::fkArrayScoringPositionNames[k] << " " << std::setw(12)
<< SteppingAction::fkArrayParticleTypeNames[ll] << " " << std::setw(8)
<< factor * fSteppingArray[index] << G4endl;
}
}
}
@@ -145,21 +153,19 @@ void Run::PrintInfo() const {
<< " Extra information: particle production \t \t <N> <E_kin> <Sum_Ekin> [MeV]"
<< G4endl;
const G4double normalization = 1.0 / floatingNumberOfEvents;
for ( G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i ) {
for ( G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k ) {
G4int index = TrackingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << TrackingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << TrackingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << TrackingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << normalization * fTrackingArray1[index]
<< " " << std::setw( 8) << ( fTrackingArray1[index] > 0 ?
fTrackingArray2[index] / fTrackingArray1[index] :
0.0 )
<< " " << std::setw( 8) << normalization * fTrackingArray2[index]
<< G4endl;
for (G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i) {
for (G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k) {
G4int index = TrackingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< TrackingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< TrackingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< TrackingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< normalization * fTrackingArray1[index] << " " << std::setw(8)
<< (fTrackingArray1[index] > 0 ? fTrackingArray2[index] / fTrackingArray1[index]
: 0.0)
<< " " << std::setw(8) << normalization * fTrackingArray2[index] << G4endl;
}
}
}
@@ -168,27 +174,30 @@ void Run::PrintInfo() const {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
void Run::SetSteppingArray(
const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray1(
const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray2(
const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray2[i] = inputArray[i];
}
}
@@ -32,46 +32,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "RunAction.hh"
#include "globals.hh"
#include "G4Run.hh"
#include "Run.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction( SteppingAction* steppingAction, TrackingAction* trackingAction ) :
G4UserRunAction(), fSteppingAction( steppingAction ), fTrackingAction( trackingAction ) {}
RunAction::RunAction(SteppingAction* steppingAction, TrackingAction* trackingAction)
: G4UserRunAction(), fSteppingAction(steppingAction), fTrackingAction(trackingAction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun() {
G4Run* RunAction::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction( const G4Run* aRun ) {
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
G4cout << "### Run " << aRun->GetRunID() << " starts." << G4endl;
Run* run = const_cast< Run* >( static_cast< const Run* >( aRun ) );
if ( run == nullptr ) return;
if ( fSteppingAction != nullptr ) {
Run* run = const_cast<Run*>(static_cast<const Run*>(aRun));
if (run == nullptr) return;
if (fSteppingAction != nullptr) {
fSteppingAction->Initialize();
fSteppingAction->SetRunPointer( run );
fSteppingAction->SetRunPointer(run);
}
if ( fTrackingAction != nullptr ) {
if (fTrackingAction != nullptr) {
fTrackingAction->Initialize();
fTrackingAction->SetRunPointer( run );
fTrackingAction->SetRunPointer(run);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction( const G4Run* aRun ) {
const Run* run = static_cast< const Run* >( aRun );
if ( run == nullptr || run->GetNumberOfEvent() == 0 ) return;
if ( IsMaster() ) run->PrintInfo();
void RunAction::EndOfRunAction(const G4Run* aRun)
{
const Run* run = static_cast<const Run*>(aRun);
if (run == nullptr || run->GetNumberOfEvent() == 0) return;
if (IsMaster()) run->PrintInfo();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,48 +32,53 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "SteppingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include "G4VSolid.hh"
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, SteppingAction::fkNumberScoringShells >
SteppingAction::fkArrayScoringShellNames = { "tracker", "emCalo", "hadCalo" };
#include "G4IonTable.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VSolid.hh"
#include "G4VTouchable.hh"
const std::array< G4String, SteppingAction::fkNumberKinematicRegions >
SteppingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, SteppingAction::fkNumberScoringShells>
SteppingAction::fkArrayScoringShellNames = {"tracker", "emCalo", "hadCalo"};
const std::array< G4String, SteppingAction::fkNumberScoringPositions >
SteppingAction::fkArrayScoringPositionNames = { "forward", "backward" };
const std::array<G4String, SteppingAction::fkNumberKinematicRegions>
SteppingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array< G4String, SteppingAction::fkNumberParticleTypes >
SteppingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, SteppingAction::fkNumberScoringPositions>
SteppingAction::fkArrayScoringPositionNames = {"forward", "backward"};
const std::array<G4String, SteppingAction::fkNumberParticleTypes>
SteppingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int SteppingAction::GetIndex( const G4int iScoringShell, const G4int iKinematicRegion,
const G4int iScoringPosition, const G4int iParticleType ) {
G4int SteppingAction::GetIndex(const G4int iScoringShell, const G4int iKinematicRegion,
const G4int iScoringPosition, const G4int iParticleType)
{
G4int index = -1;
if ( iScoringShell >= 0 && iScoringShell < fkNumberScoringShells &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iScoringPosition >= 0 && iScoringPosition < fkNumberScoringPositions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringShell * fkNumberKinematicRegions * fkNumberScoringPositions *
fkNumberParticleTypes + iKinematicRegion * fkNumberScoringPositions * fkNumberParticleTypes
if (iScoringShell >= 0 && iScoringShell < fkNumberScoringShells && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iScoringPosition >= 0
&& iScoringPosition < fkNumberScoringPositions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index =
iScoringShell * fkNumberKinematicRegions * fkNumberScoringPositions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberScoringPositions * fkNumberParticleTypes
+ iScoringPosition * fkNumberParticleTypes + iParticleType;
}
if ( index < 0 || index >= fkNumberCombinations ) {
if (index < 0 || index >= fkNumberCombinations) {
G4cerr << "SteppingAction::GetIndex : WRONG index=" << index << " set it to 0 !" << G4endl;
index = 0;
}
@@ -82,25 +87,27 @@ G4int SteppingAction::GetIndex( const G4int iScoringShell, const G4int iKinemati
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction() :G4UserSteppingAction() {
SteppingAction::SteppingAction() : G4UserSteppingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::Initialize() {
void SteppingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fPrimaryParticleId = 0;
fPrimaryParticleEnergy = 0.0;
fPrimaryParticleDirection = G4ThreeVector( 0.0, 0.0, 1.0 );
fPrimaryParticleDirection = G4ThreeVector(0.0, 0.0, 1.0);
fTrackerMaterialName = fEmCaloMaterialName = fHadCaloMaterialName = "";
fIsFirstStepOfTheEvent = true;
fIsFirstStepInTracker = fIsFirstStepInEmCalo = fIsFirstStepInHadCalo = true;
fIsFirstStepInScoringTrackerShell = fIsFirstStepInScoringEmCaloShell =
fIsFirstStepInScoringHadCaloShell = true;
fIsFirstStepInScoringHadCaloShell = true;
fCubicVolumeScoringTrackerShell = fCubicVolumeScoringEmCaloShell =
fCubicVolumeScoringHadCaloShell = 1.0;
for ( G4int i = 0; i < fkNumberCombinations; ++i ) {
for (G4int i = 0; i < fkNumberCombinations; ++i) {
fArraySumStepLengths[i] = 0.0;
}
/*
@@ -128,74 +135,80 @@ void SteppingAction::Initialize() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
void SteppingAction::UserSteppingAction(const G4Step* theStep)
{
// Get information on the primary particle
if ( fIsFirstStepOfTheEvent ) {
if ( theStep->GetTrack()->GetParentID() == 0 ) {
if (fIsFirstStepOfTheEvent) {
if (theStep->GetTrack()->GetParentID() == 0) {
fPrimaryParticleId = theStep->GetTrack()->GetDefinition()->GetPDGEncoding();
fPrimaryParticleEnergy = theStep->GetPreStepPoint()->GetKineticEnergy();
fPrimaryParticleDirection = theStep->GetPreStepPoint()->GetMomentumDirection();
if ( fRunPtr ) {
fRunPtr->SetPrimaryParticleId( fPrimaryParticleId );
fRunPtr->SetPrimaryParticleEnergy( fPrimaryParticleEnergy );
fRunPtr->SetPrimaryParticleDirection( fPrimaryParticleDirection );
if (fRunPtr) {
fRunPtr->SetPrimaryParticleId(fPrimaryParticleId);
fRunPtr->SetPrimaryParticleEnergy(fPrimaryParticleEnergy);
fRunPtr->SetPrimaryParticleDirection(fPrimaryParticleDirection);
}
fIsFirstStepOfTheEvent = false;
}
}
// Get information on the materials
if ( fIsFirstStepInTracker &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiTrackerShell" ) {
if (fIsFirstStepInTracker
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiTrackerShell")
{
fTrackerMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetTrackerMaterialName( fTrackerMaterialName );
if (fRunPtr) fRunPtr->SetTrackerMaterialName(fTrackerMaterialName);
fIsFirstStepInTracker = false;
}
if ( fIsFirstStepInEmCalo &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiEmCaloShell" ) {
if (fIsFirstStepInEmCalo
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiEmCaloShell")
{
fEmCaloMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetEmCaloMaterialName( fEmCaloMaterialName );
if (fRunPtr) fRunPtr->SetEmCaloMaterialName(fEmCaloMaterialName);
fIsFirstStepInEmCalo = false;
}
if ( fIsFirstStepInHadCalo &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiHadCaloShell" ) {
if (fIsFirstStepInHadCalo
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiHadCaloShell")
{
fHadCaloMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetHadCaloMaterialName( fHadCaloMaterialName );
if (fRunPtr) fRunPtr->SetHadCaloMaterialName(fHadCaloMaterialName);
fIsFirstStepInHadCalo = false;
}
// Get information on step lengths in the scoring shells
G4int iScoringShell = -1;
if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() ==
"physiScoringTrackerShell" ) {
if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringTrackerShell") {
iScoringShell = 0;
if ( fIsFirstStepInScoringTrackerShell ) {
if (fIsFirstStepInScoringTrackerShell) {
fCubicVolumeScoringTrackerShell =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringTrackerShell( fCubicVolumeScoringTrackerShell );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringTrackerShell(fCubicVolumeScoringTrackerShell);
fIsFirstStepInScoringTrackerShell = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() ==
"physiScoringEmCaloShell" ) {
}
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringEmCaloShell")
{
iScoringShell = 1;
if ( fIsFirstStepInScoringEmCaloShell ) {
if (fIsFirstStepInScoringEmCaloShell) {
fCubicVolumeScoringEmCaloShell =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringEmCaloShell( fCubicVolumeScoringEmCaloShell );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringEmCaloShell(fCubicVolumeScoringEmCaloShell);
fIsFirstStepInScoringEmCaloShell = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() ==
"physiScoringHadCaloShell" ) {
}
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringHadCaloShell")
{
iScoringShell = 2;
if ( fIsFirstStepInScoringHadCaloShell ) {
if (fIsFirstStepInScoringHadCaloShell) {
fCubicVolumeScoringHadCaloShell =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringHadCaloShell( fCubicVolumeScoringHadCaloShell );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringHadCaloShell(fCubicVolumeScoringHadCaloShell);
fIsFirstStepInScoringHadCaloShell = false;
}
}
if ( iScoringShell >= 0 ) {
if (iScoringShell >= 0) {
G4double stepLength = theStep->GetTrack()->GetStepLength() * theStep->GetTrack()->GetWeight();
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr ? 0 :
std::abs( theStep->GetTrack()->GetDefinition()->GetPDGEncoding() );
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr
? 0
: std::abs(theStep->GetTrack()->GetDefinition()->GetPDGEncoding());
/*
G4cout << theStep->GetTrack()->GetDefinition()->GetParticleName() << " absPdg=" << absPdg
<< " Ekin[MeV]=" << theStep->GetPreStepPoint()->GetKineticEnergy()
@@ -203,7 +216,7 @@ void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
<< " z[mm]=" << theStep->GetTrack()->GetPosition().z()
<< " " << theStep->GetTrack()->GetVolume()->GetName()
<< " " << theStep->GetTrack()->GetMaterial()->GetName()
<< " L[mm]=" << stepLength << " "
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot( theStep->GetTrack()->GetPosition().unit() ) > 0.0
? "forward" : "backward" ) << G4endl;
*/
@@ -212,39 +225,49 @@ void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
// Two scoring positions: [0] : forward hemisphere ; [1] : backward hemisphere
// (with respect to the primary particle initial direction)
G4int iScoringPosition =
fPrimaryParticleDirection.dot( theStep->GetTrack()->GetPosition().unit() ) > 0.0 ? 0 : 1;
fPrimaryParticleDirection.dot(theStep->GetTrack()->GetPosition().unit()) > 0.0 ? 0 : 1;
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4; // neutrinos
// (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( theStep->GetTrack()->GetDefinition() ) || // ions (and anti-ions)
G4IonTable::IsAntiIon( theStep->GetTrack()->GetDefinition() ) ) iParticleType = 8;
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4; // neutrinos
// (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(theStep->GetTrack()->GetDefinition()) || // ions (and anti-ions)
G4IonTable::IsAntiIon(theStep->GetTrack()->GetDefinition()))
iParticleType = 8;
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
// Consider the specific case : scoring shell, kinematic region, scoring position, and
// particle type
G4int index = GetIndex( iScoringShell, iKinematicRegion, iScoringPosition, iParticleType );
G4int index = GetIndex(iScoringShell, iKinematicRegion, iScoringPosition, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "all" particle case, with the same scoring shell, kinematic region and
// scoring position
index = GetIndex( iScoringShell, iKinematicRegion, iScoringPosition, 0 );
index = GetIndex(iScoringShell, iKinematicRegion, iScoringPosition, 0);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region case, with the same scoring shell, scoring position
// and particle type
index = GetIndex( iScoringShell, 0, iScoringPosition, iParticleType );
// and particle type
index = GetIndex(iScoringShell, 0, iScoringPosition, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region and "all" particle, with the same scoring shell and
// scoring position
index = GetIndex( iScoringShell, 0, iScoringPosition, 0 );
// scoring position
index = GetIndex(iScoringShell, 0, iScoringPosition, 0);
fArraySumStepLengths[index] += stepLength;
if ( fRunPtr ) fRunPtr->SetSteppingArray( fArraySumStepLengths );
if (fRunPtr) fRunPtr->SetSteppingArray(fArraySumStepLengths);
}
}
@@ -32,119 +32,136 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "TrackingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, TrackingAction::fkNumberScoringVolumes >
TrackingAction::fkArrayScoringVolumeNames = { "tracker", "emCalo", "hadCalo" };
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4Track.hh"
const std::array< G4String, TrackingAction::fkNumberKinematicRegions >
TrackingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, TrackingAction::fkNumberScoringVolumes>
TrackingAction::fkArrayScoringVolumeNames = {"tracker", "emCalo", "hadCalo"};
const std::array< G4String, TrackingAction::fkNumberParticleTypes >
TrackingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, TrackingAction::fkNumberKinematicRegions>
TrackingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, TrackingAction::fkNumberParticleTypes>
TrackingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int TrackingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int TrackingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
return index;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TrackingAction::TrackingAction() : G4UserTrackingAction() {
TrackingAction::TrackingAction() : G4UserTrackingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::Initialize() {
void TrackingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill( 0 );
fArraySumKineticEnergies.fill( 0.0 );
fArrayMultiplicities.fill(0);
fArraySumKineticEnergies.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PreUserTrackingAction( const G4Track* aTrack ) {
// This method is called not only once when a particle is created,
void TrackingAction::PreUserTrackingAction(const G4Track* aTrack)
{
// This method is called not only once when a particle is created,
// but also each time it is resumed, in the case the track gets suspended,
// as it happens in the case of neutrons with _HP Physics Lists.
// To be sure that we collect information about a track one and only once,
// we require that the current step be the first one.
if ( aTrack == nullptr ||
aTrack->GetCurrentStepNumber() != 0 ||
aTrack->GetDefinition() == nullptr ||
aTrack->GetLogicalVolumeAtVertex() == nullptr ) return;
if (aTrack == nullptr || aTrack->GetCurrentStepNumber() != 0 || aTrack->GetDefinition() == nullptr
|| aTrack->GetLogicalVolumeAtVertex() == nullptr)
return;
G4int iScoringVolume = -1;
if ( aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicTrackerShell" ) {
if (aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicTrackerShell") {
iScoringVolume = 0;
} else if ( aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicEmCaloShell" ) {
}
else if (aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicEmCaloShell") {
iScoringVolume = 1;
} else if ( aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicHadCaloShell" ) {
}
else if (aTrack->GetLogicalVolumeAtVertex()->GetName() == "logicHadCaloShell") {
iScoringVolume = 2;
}
if ( iScoringVolume < 0 ) return;
if (iScoringVolume < 0) return;
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = aTrack->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int absPdg = std::abs( aTrack->GetDefinition()->GetPDGEncoding() );
G4int absPdg = std::abs(aTrack->GetDefinition()->GetPDGEncoding());
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( aTrack->GetDefinition() ) ||
G4IonTable::IsAntiIon( aTrack->GetDefinition() ) ) iParticleType = 8;
// ions (and anti-ions)
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(aTrack->GetDefinition())
|| G4IonTable::IsAntiIon(aTrack->GetDefinition()))
iParticleType = 8;
// ions (and anti-ions)
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
index = GetIndex(iScoringVolume, 0, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
if ( fRunPtr ) {
fRunPtr->SetTrackingArray1( fArrayMultiplicities );
fRunPtr->SetTrackingArray2( fArraySumKineticEnergies );
if (fRunPtr) {
fRunPtr->SetTrackingArray1(fArrayMultiplicities);
fRunPtr->SetTrackingArray2(fArraySumKineticEnergies);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PostUserTrackingAction( const G4Track* /* aTrack */ ) {}
void TrackingAction::PostUserTrackingAction(const G4Track* /* aTrack */) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -31,40 +31,42 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4Threading.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "G4PhysListFactory.hh"
#include "G4RunManagerFactory.hh"
#include "G4Threading.hh"
#include "G4UImanager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv) {
int main(int argc, char** argv)
{
auto* runManager = G4RunManagerFactory::CreateRunManager();
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization( pDetectorInstance );
runManager->SetUserInitialization(pDetectorInstance);
// Physics list factory: use the PHYSLIST environmental variable.
G4PhysListFactory factory;
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
runManager->SetUserInitialization( thePL );
runManager->SetUserInitialization( new ActionInitialization( pDetectorInstance ) );
runManager->SetUserInitialization(thePL);
runManager->SetUserInitialization(new ActionInitialization(pDetectorInstance));
G4UImanager* UI = G4UImanager::GetUIpointer();
if ( argc==1 ) { // Define UI session for interactive mode.
} else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
G4UImanager* UI = G4UImanager::GetUIpointer();
if (argc == 1) { // Define UI session for interactive mode.
}
else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command + fileName);
}
// job termination
delete runManager;
return 0;
// job termination
delete runManager;
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,7 @@
/// \file ActionInitialization.hh
/// \brief Definition of the ActionInitialization class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -40,12 +40,14 @@ class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class ActionInitialization : public G4VUserActionInitialization {
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization( const DetectorConstruction* inputDetectorConstruction = nullptr );
ActionInitialization(const DetectorConstruction* inputDetectorConstruction = nullptr);
~ActionInitialization() override = default;
void BuildForMaster() const override;
void Build() const override;
private:
const DetectorConstruction* fPtrDetectorConstruction = nullptr;
};
@@ -26,7 +26,7 @@
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -35,7 +35,7 @@
#define DetectorConstruction_H 1
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "globals.hh"
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -44,20 +44,22 @@ class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction {
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
G4VPhysicalVolume* Construct();
void SetMaterial( const G4String name );
void SetMaterial(const G4String name);
inline G4Material* GetMaterial() const;
inline void SetThickness( const G4double value );
inline void SetThickness(const G4double value);
inline G4double GetThickness() const;
inline void SetDiameter( const G4double value );
inline void SetDiameter(const G4double value);
inline G4double GetDiameter() const;
void UpdateGeometry();
private:
G4VPhysicalVolume* ConstructLayer(); // To be invoked each time the geometry needs to be
// updated.
@@ -65,12 +67,12 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
G4Material* fMaterial;
G4LogicalVolume* fExperimentalHall_log;
G4VPhysicalVolume* fExperimentalHall_phys;
G4LogicalVolume* fLogicLayer;
G4LogicalVolume* fLogicLayer;
G4VPhysicalVolume* fPhysiLayer;
G4LogicalVolume* fLogicScoringUpDown;
G4LogicalVolume* fLogicScoringUpDown;
G4VPhysicalVolume* fPhysiScoringUpstream;
G4VPhysicalVolume* fPhysiScoringDownstream;
G4LogicalVolume* fLogicScoringSide;
G4LogicalVolume* fLogicScoringSide;
G4VPhysicalVolume* fPhysiScoringSide;
DetectorMessenger* fDetectorMessenger;
G4double fThickness;
@@ -78,23 +80,28 @@ class DetectorConstruction : public G4VUserDetectorConstruction {
const G4double fScoringThickness = 10.0; //***LOOKHERE*** thickness of the scoring shell
};
inline G4Material* DetectorConstruction::GetMaterial() const {
inline G4Material* DetectorConstruction::GetMaterial() const
{
return fMaterial;
}
inline void DetectorConstruction::SetThickness( const G4double value ) {
inline void DetectorConstruction::SetThickness(const G4double value)
{
fThickness = value;
}
inline G4double DetectorConstruction::GetThickness() const {
inline G4double DetectorConstruction::GetThickness() const
{
return fThickness;
}
inline void DetectorConstruction::SetDiameter( const G4double value ) {
inline void DetectorConstruction::SetDiameter(const G4double value)
{
fDiameter = value;
}
inline G4double DetectorConstruction::GetDiameter() const {
inline G4double DetectorConstruction::GetDiameter() const
{
return fDiameter;
}
@@ -26,7 +26,7 @@
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,8 +34,8 @@
#ifndef DetectorMessenger_h
#define DetectorMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
#include "globals.hh"
class DetectorConstruction;
class G4UIdirectory;
@@ -45,18 +45,20 @@ class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorMessenger: public G4UImessenger {
class DetectorMessenger : public G4UImessenger
{
public:
DetectorMessenger( DetectorConstruction* );
DetectorMessenger(DetectorConstruction*);
~DetectorMessenger();
void SetNewValue( G4UIcommand*, G4String ) override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
G4UIcmdWithAString* fMaterial;
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
G4UIcmdWithAString* fMaterial;
G4UIcmdWithADoubleAndUnit* fThickness;
G4UIcmdWithADoubleAndUnit* fDiameter;
G4UIcmdWithoutParameter* fUpdateCommand;
G4UIcmdWithoutParameter* fUpdateCommand;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,12 +42,14 @@ class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction( const DetectorConstruction* );
PrimaryGeneratorAction(const DetectorConstruction*);
~PrimaryGeneratorAction();
void GeneratePrimaries( G4Event* anEvent ) override;
void GeneratePrimaries(G4Event* anEvent) override;
void SetGunPosition() const;
private:
G4ParticleGun* fParticleGun;
const DetectorConstruction* fPointerDetectorConstruction = nullptr;
@@ -26,7 +26,7 @@
/// \file Run.hh
/// \brief Definition of the Run class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,77 +34,94 @@
#ifndef Run_h
#define Run_h 1
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include <array>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class Run : public G4Run {
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction . )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
class Run : public G4Run
{
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction . )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
public:
Run();
~Run() override = default;
void RecordEvent( const G4Event* anEvent ) override;
void RecordEvent(const G4Event* anEvent) override;
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event. In the case of multithreaded mode, it is called only for the working thread
// that handled that event.
void Merge( const G4Run* aRun ) override;
void Merge(const G4Run* aRun) override;
// This method is called automatically by the Geant4 kernel (not by the user!) only in the
// case of multithreaded mode and only for working threads.
void PrintInfo() const;
// This method is called by RunAction::EndOfRunAction : in the case of multithreaded mode,
// only the master thread calls it.
void SetPrimaryParticleId( const G4int inputValue ) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy( const G4double inputValue )
{ fPrimaryParticleEnergy = inputValue; }
void SetPrimaryParticleDirection( const G4ThreeVector &inputValue )
{ fPrimaryParticleDirection = inputValue; }
void SetTargetMaterialName( const G4String &inputValue ) { fTargetMaterialName = inputValue; }
void SetCubicVolumeScoringUpDown( const G4double inputValue )
{ fCubicVolumeScoringUpDown = inputValue; }
void SetCubicVolumeScoringSide( const G4double inputValue )
{ fCubicVolumeScoringSide = inputValue; }
void SetPrimaryParticleId(const G4int inputValue) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy(const G4double inputValue)
{
fPrimaryParticleEnergy = inputValue;
}
void SetPrimaryParticleDirection(const G4ThreeVector& inputValue)
{
fPrimaryParticleDirection = inputValue;
}
void SetTargetMaterialName(const G4String& inputValue) { fTargetMaterialName = inputValue; }
void SetCubicVolumeScoringUpDown(const G4double inputValue)
{
fCubicVolumeScoringUpDown = inputValue;
}
void SetCubicVolumeScoringSide(const G4double inputValue)
{
fCubicVolumeScoringSide = inputValue;
}
G4int GetPrimaryParticleId() const { return fPrimaryParticleId; }
G4double GetPrimaryParticleEnergy() const { return fPrimaryParticleEnergy; }
G4ThreeVector GetPrimaryParticleDirection() const { return fPrimaryParticleDirection; }
G4String GetTargetMaterialName() const { return fTargetMaterialName; }
G4double GetCubicVolumeScoringUpDown() const { return fCubicVolumeScoringUpDown; }
G4double GetCubicVolumeScoringSide() const { return fCubicVolumeScoringSide; }
void SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray );
std::array< G4double, SteppingAction::fkNumberCombinations > GetSteppingArray() const
{ return fSteppingArray; }
void
SetSteppingArray(const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray);
std::array<G4double, SteppingAction::fkNumberCombinations> GetSteppingArray() const
{
return fSteppingArray;
}
// Accessor methods useful to transfer information collected by the stepping-action
// into this Run class
void SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4long, TrackingAction::fkNumberCombinations > GetTrackingArray1() const
{ return fTrackingArray1; }
void SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4double, TrackingAction::fkNumberCombinations > GetTrackingArray2() const
{ return fTrackingArray2; }
void
SetTrackingArray1(const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4long, TrackingAction::fkNumberCombinations> GetTrackingArray1() const
{
return fTrackingArray1;
}
void
SetTrackingArray2(const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4double, TrackingAction::fkNumberCombinations> GetTrackingArray2() const
{
return fTrackingArray2;
}
// Accessor methods useful to transfer information collected by the tracking-action
// into this Run class
@@ -116,10 +133,9 @@ class Run : public G4Run {
G4String fTargetMaterialName;
G4double fCubicVolumeScoringUpDown;
G4double fCubicVolumeScoringSide;
std::array< G4double, SteppingAction::fkNumberCombinations > fSteppingArray;
std::array< G4long, TrackingAction::fkNumberCombinations > fTrackingArray1;
std::array< G4double, TrackingAction::fkNumberCombinations > fTrackingArray2;
std::array<G4double, SteppingAction::fkNumberCombinations> fSteppingArray;
std::array<G4long, TrackingAction::fkNumberCombinations> fTrackingArray1;
std::array<G4double, TrackingAction::fkNumberCombinations> fTrackingArray2;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file RunAction.hh
/// \brief Definition of the RunAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,16 +42,18 @@ class TrackingAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class RunAction: public G4UserRunAction {
class RunAction : public G4UserRunAction
{
public:
RunAction( SteppingAction* steppingAction = nullptr, TrackingAction* trackingAction = nullptr );
RunAction(SteppingAction* steppingAction = nullptr, TrackingAction* trackingAction = nullptr);
~RunAction() override = default;
void BeginOfRunAction( const G4Run* aRun ) override;
void EndOfRunAction( const G4Run* aRun ) override;
void BeginOfRunAction(const G4Run* aRun) override;
void EndOfRunAction(const G4Run* aRun) override;
G4Run* GenerateRun() override;
private:
SteppingAction* fSteppingAction;
TrackingAction* fTrackingAction;
TrackingAction* fTrackingAction;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,21 +34,23 @@
#ifndef SteppingAction_H
#define SteppingAction_H 1
#include "globals.hh"
#include "G4UserSteppingAction.hh"
#include "G4ThreeVector.hh"
#include "G4UserSteppingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class SteppingAction : public G4UserSteppingAction {
public:
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction();
~SteppingAction() override = default;
void UserSteppingAction( const G4Step* ) override;
void UserSteppingAction(const G4Step*) override;
// This is the main method where the step lengths of particles inside
// the scoring volumes are collected, and then the corresponding fluences
// are filled up in the Run object where they are stored (and then
@@ -62,7 +64,7 @@ class SteppingAction : public G4UserSteppingAction {
// This is necessary because different runs can have different primary particle
// types, kinetic energies, and detector configurations.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// stepping-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the stepping-action
@@ -74,20 +76,20 @@ class SteppingAction : public G4UserSteppingAction {
// the sum of step lengths in those scoring volumes.
// Notice that two of the three scoring volumes - upstream and downstream -
// have the same cubic-volume, that we call "fCubicVolumeScoringUpDown".
static const G4int fkNumberScoringVolumes = 3; // downstream, side, upstream
static const G4int fkNumberScoringVolumes = 3; // downstream, side, upstream
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
private:
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -99,8 +101,8 @@ class SteppingAction : public G4UserSteppingAction {
G4bool fIsFirstStepInScoringSide;
G4double fCubicVolumeScoringUpDown;
G4double fCubicVolumeScoringSide;
std::array< G4double, fkNumberCombinations > fArraySumStepLengths;
std::array<G4double, fkNumberCombinations> fArraySumStepLengths;
// Array to collect the sum of step lengths in the scoring volumes for the whole run,
// according to the various cases (kinematical region and particle type).
// Note that the fluence in a scoring volume is defined as sum of step lengths
@@ -26,63 +26,65 @@
/// \file TrackingAction.hh
/// \brief Definition of the TrackingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef TrackingAction_h
#ifndef TrackingAction_h
#define TrackingAction_h 1
#include "globals.hh"
#include "G4UserTrackingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class TrackingAction : public G4UserTrackingAction {
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the target layer.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
class TrackingAction : public G4UserTrackingAction
{
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the target layer.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
public:
TrackingAction();
~TrackingAction() override = default;
void PreUserTrackingAction( const G4Track* ) override;
void PostUserTrackingAction( const G4Track* ) override;
void PreUserTrackingAction(const G4Track*) override;
void PostUserTrackingAction(const G4Track*) override;
void Initialize();
// This method is called by RunAction::BeginOfRunAction for the
// initialization of the tracking-action at the beginning of each Run.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// tracking-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the tracking-action
// to the run object.
static const G4int fkNumberScoringVolumes = 1; // only the target layer
static const G4int fkNumberScoringVolumes = 1; // only the target layer
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
std::array< G4long, fkNumberCombinations > fArrayMultiplicities;
std::array< G4double, fkNumberCombinations > fArraySumKineticEnergies;
std::array<G4long, fkNumberCombinations> fArrayMultiplicities;
std::array<G4double, fkNumberCombinations> fArraySumKineticEnergies;
// Keep record of the fkNumber of particles and their kinetic energy at production,
// according to the particle type and their kinetic energy range (below/above 20 MeV).
};
@@ -32,35 +32,38 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "ActionInitialization.hh"
#include "PrimaryGeneratorAction.hh"
#include "Run.hh"
#include "RunAction.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization( const DetectorConstruction*
inputDetectorConstruction ) :
G4VUserActionInitialization(), fPtrDetectorConstruction( inputDetectorConstruction ) {}
ActionInitialization::ActionInitialization(const DetectorConstruction* inputDetectorConstruction)
: G4VUserActionInitialization(), fPtrDetectorConstruction(inputDetectorConstruction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
void ActionInitialization::BuildForMaster() const
{
// This is NOT called in SEQ-mode, while in the MT-mode is called only for the Master thread.
SetUserAction( new RunAction );
SetUserAction(new RunAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
void ActionInitialization::Build() const
{
// This is called in the SEQ-mode and in the MT-mode only for Worker threads.
SetUserAction( new PrimaryGeneratorAction( fPtrDetectorConstruction ) );
SetUserAction(new PrimaryGeneratorAction(fPtrDetectorConstruction));
SteppingAction* steppingAction = new SteppingAction;
SetUserAction( steppingAction );
SetUserAction(steppingAction);
TrackingAction* trackingAction = new TrackingAction;
SetUserAction( trackingAction );
SetUserAction( new RunAction( steppingAction, trackingAction ) );
SetUserAction(trackingAction);
SetUserAction(new RunAction(steppingAction, trackingAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,55 +32,66 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
#include "G4Box.hh"
#include "G4GeometryManager.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4LogicalVolume.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "globals.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4RunManager.hh"
#include "G4SolidStore.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "G4Tubs.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction() :
fMaterial( nullptr ), fExperimentalHall_log( nullptr ), fExperimentalHall_phys( nullptr ),
fLogicLayer( nullptr ), fPhysiLayer( nullptr ),
fLogicScoringUpDown( nullptr ), fPhysiScoringUpstream( nullptr ),
fPhysiScoringDownstream( nullptr ),
fLogicScoringSide( nullptr ), fPhysiScoringSide( nullptr ),
fDetectorMessenger( nullptr ),
fThickness( 2.0*CLHEP::m ), fDiameter( 2.0*CLHEP::m ) //***LOOKHERE*** Default values
DetectorConstruction::DetectorConstruction()
: fMaterial(nullptr),
fExperimentalHall_log(nullptr),
fExperimentalHall_phys(nullptr),
fLogicLayer(nullptr),
fPhysiLayer(nullptr),
fLogicScoringUpDown(nullptr),
fPhysiScoringUpstream(nullptr),
fPhysiScoringDownstream(nullptr),
fLogicScoringSide(nullptr),
fPhysiScoringSide(nullptr),
fDetectorMessenger(nullptr),
fThickness(2.0 * CLHEP::m),
fDiameter(2.0 * CLHEP::m) //***LOOKHERE*** Default values
{
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" ); //***LOOKHERE***
// Default material
fDetectorMessenger = new DetectorMessenger( this );
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe"); //***LOOKHERE***
// Default material
fDetectorMessenger = new DetectorMessenger(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction() {
DetectorConstruction::~DetectorConstruction()
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct() {
G4VPhysicalVolume* DetectorConstruction::Construct()
{
return ConstructLayer();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructLayer() {
G4VPhysicalVolume* DetectorConstruction::ConstructLayer()
{
// Clean old geometry, if any.
G4GeometryManager::GetInstance()->OpenGeometry();
G4PhysicalVolumeStore::GetInstance()->Clean();
@@ -92,156 +103,152 @@ G4VPhysicalVolume* DetectorConstruction::ConstructLayer() {
// The world volume (experimental hall) is a box 20% bigger than the target layer,
// and it is filled of "G4_Galactic" material.
G4double expHall_x = 0.6*fDiameter; // half dimension along x : 20% bigger than the radius
// of the target layer
G4double expHall_y = 0.6*fDiameter; // half dimension along y : 20% bigger than the radius
// of the target layer
G4double expHall_z = 0.6*fThickness; // half dimension along z : 20% bigger than the half
// thickness of the target layer
G4double expHall_x = 0.6 * fDiameter; // half dimension along x : 20% bigger than the radius
// of the target layer
G4double expHall_y = 0.6 * fDiameter; // half dimension along y : 20% bigger than the radius
// of the target layer
G4double expHall_z = 0.6 * fThickness; // half dimension along z : 20% bigger than the half
// thickness of the target layer
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Galactic" );
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
// Experimental hall
G4Box* experimentalHall_box = new G4Box( "expHall_box", expHall_x, expHall_y, expHall_z );
fExperimentalHall_log = new G4LogicalVolume( experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fExperimentalHall_phys = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Box* experimentalHall_box = new G4Box("expHall_box", expHall_x, expHall_y, expHall_z);
fExperimentalHall_log = new G4LogicalVolume(experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0); // user limits
fExperimentalHall_phys = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0); // copy number
// Target
G4Tubs* solidLayer = new G4Tubs( "solidLayer", // name
0.0, // inner radius
0.5*fDiameter, // outer radius
0.5*fThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0*pi ); // final phi angle in rad
fLogicLayer = new G4LogicalVolume( solidLayer, // solid
fMaterial, // material
"logicLayer", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiLayer = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiLayer", // name
fLogicLayer, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Tubs* solidLayer = new G4Tubs("solidLayer", // name
0.0, // inner radius
0.5 * fDiameter, // outer radius
0.5 * fThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0 * pi); // final phi angle in rad
fLogicLayer = new G4LogicalVolume(solidLayer, // solid
fMaterial, // material
"logicLayer", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiLayer = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiLayer", // name
fLogicLayer, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
// Three scoring volumes: one thin layer downstream of the target ("down")
// one thin layer surrounding (lateral) of the target ("side")
// one thin layer upstream of the target ("up")
G4Tubs* solidScoringUpDown = new G4Tubs( "solidScoringUpDown", // name
0.0, // inner radius
0.5*fDiameter, // outer radius
0.5*fScoringThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0*pi ); // final phi angle in rad
fLogicScoringUpDown = new G4LogicalVolume( solidScoringUpDown, // solid
vacuum, // material
"logicScoringUpDown", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
G4double zScoringUpDown = 0.5*(fThickness + fScoringThickness);
fPhysiScoringUpstream = new G4PVPlacement( 0, // rotation
G4ThreeVector( 0.0, 0.0, -zScoringUpDown ),
// translation
"physiScoringUpstream", // name
fLogicScoringUpDown, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
fPhysiScoringDownstream = new G4PVPlacement( 0, // rotation
G4ThreeVector( 0.0, 0.0, zScoringUpDown ),
// translation
"physiScoringDownstream", // name
fLogicScoringUpDown, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Tubs* solidScoringUpDown = new G4Tubs("solidScoringUpDown", // name
0.0, // inner radius
0.5 * fDiameter, // outer radius
0.5 * fScoringThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0 * pi); // final phi angle in rad
fLogicScoringUpDown = new G4LogicalVolume(solidScoringUpDown, // solid
vacuum, // material
"logicScoringUpDown", // name
0, // field manager
0, // sensitive detector
0); // user limits
G4double zScoringUpDown = 0.5 * (fThickness + fScoringThickness);
fPhysiScoringUpstream = new G4PVPlacement(0, // rotation
G4ThreeVector(0.0, 0.0, -zScoringUpDown),
// translation
"physiScoringUpstream", // name
fLogicScoringUpDown, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
fPhysiScoringDownstream = new G4PVPlacement(0, // rotation
G4ThreeVector(0.0, 0.0, zScoringUpDown),
// translation
"physiScoringDownstream", // name
fLogicScoringUpDown, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
G4Tubs* solidScoringSide = new G4Tubs( "solidScoringSide", // name
0.5*fDiameter, // inner radius
0.5*fDiameter + fScoringThickness, // outer radius
0.5*fThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0*pi ); // final phi angle in rad
fLogicScoringSide = new G4LogicalVolume( solidScoringSide, // solid
vacuum, // material
"logicScoringSide", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiScoringSide = new G4PVPlacement( 0, // rotation
G4ThreeVector( 0.0, 0.0, 0.0 ), // translation
"physiScoringSide", // name
fLogicScoringSide, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Tubs* solidScoringSide = new G4Tubs("solidScoringSide", // name
0.5 * fDiameter, // inner radius
0.5 * fDiameter + fScoringThickness, // outer radius
0.5 * fThickness, // half cylinder length in z
0.0, // starting phi angle in rad
2.0 * pi); // final phi angle in rad
fLogicScoringSide = new G4LogicalVolume(solidScoringSide, // solid
vacuum, // material
"logicScoringSide", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiScoringSide = new G4PVPlacement(0, // rotation
G4ThreeVector(0.0, 0.0, 0.0), // translation
"physiScoringSide", // name
fLogicScoringSide, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
G4cout << G4endl
<< "DetectorConstruction::ConstructLayer() : " << G4endl
<< "\t World (box) size: " << G4endl
<< "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl
<< "\t Target layer (cylinder) size: " << G4endl
<< "\t \t x : -/+ " << 0.5*fDiameter << " mm ;"
<< "\t y : -/+ " << 0.5*fDiameter << " mm ;"
<< "\t z : -/+ " << 0.5*fThickness << " mm ;" << G4endl
<< G4endl << G4endl;
G4cout << G4endl << "DetectorConstruction::ConstructLayer() : " << G4endl
<< "\t World (box) size: " << G4endl << "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl
<< "\t Target layer (cylinder) size: " << G4endl << "\t \t x : -/+ " << 0.5 * fDiameter
<< " mm ;"
<< "\t y : -/+ " << 0.5 * fDiameter << " mm ;"
<< "\t z : -/+ " << 0.5 * fThickness << " mm ;" << G4endl << G4endl << G4endl;
return fExperimentalHall_phys;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterial( const G4String name ) {
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( name );
if ( ! fMaterial ) {
G4cout << G4endl << G4endl
<< "WARNING: the name of the material has not been recognized!" << G4endl
<< " ===> the default * G4_Fe * will be used."
<< G4endl << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" );
void DetectorConstruction::SetMaterial(const G4String name)
{
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial(name);
if (!fMaterial) {
G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!"
<< G4endl << " ===> the default * G4_Fe * will be used." << G4endl << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe");
}
if ( fLogicLayer ) fLogicLayer->SetMaterial( fMaterial );
if (fLogicLayer) fLogicLayer->SetMaterial(fMaterial);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::UpdateGeometry() {
void DetectorConstruction::UpdateGeometry()
{
G4RunManager::GetRunManager()->ReinitializeGeometry();
PrintParameters();
// Update also the position of the gun
const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast< const PrimaryGeneratorAction* >(
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction() );
if ( pPrimaryAction ) pPrimaryAction->SetGunPosition();
const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast<const PrimaryGeneratorAction*>(
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
if (pPrimaryAction) pPrimaryAction->SetGunPosition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::PrintParameters() {
G4cout << G4endl << G4endl
<< " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
void DetectorConstruction::PrintParameters()
{
G4cout << G4endl << G4endl << " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
<< " Material = " << fMaterial->GetName() << G4endl
<< " Thickness = " << fThickness << " mm" << G4endl
<< " Diameter = " << fDiameter << " mm" << G4endl
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< " ------------------------------------------------------ "
<< G4endl << G4endl;
<< " Diameter = " << fDiameter << " mm" << G4endl
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< " ------------------------------------------------------ " << G4endl << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,48 +32,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorMessenger.hh"
#include "DetectorConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIdirectory.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* myDet ) : fDetector( myDet ) {
fDetectorDir = new G4UIdirectory( "/mydet/" );
fDetectorDir->SetGuidance( "Detector control." );
DetectorMessenger::DetectorMessenger(DetectorConstruction* myDet) : fDetector(myDet)
{
fDetectorDir = new G4UIdirectory("/mydet/");
fDetectorDir->SetGuidance("Detector control.");
fMaterial = new G4UIcmdWithAString( "/mydet/material", this );
fMaterial->SetGuidance( "Choice of the material:" );
fMaterial->SetGuidance( " a Geant4 NIST material, e.g. G4_Fe " );
fMaterial->SetParameterName( "choiceMaterial", true );
fMaterial->SetDefaultValue( "G4_Fe" );
fMaterial->AvailableForStates( G4State_PreInit, G4State_Idle );
fThickness = new G4UIcmdWithADoubleAndUnit( "/mydet/thickness", this );
fThickness->SetParameterName( "choiceThickness", true );
fThickness->SetGuidance( "Target thickness" );
fThickness->SetDefaultValue( 1000.0 ); // default: 1 meter.
fThickness->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterial = new G4UIcmdWithAString("/mydet/material", this);
fMaterial->SetGuidance("Choice of the material:");
fMaterial->SetGuidance(" a Geant4 NIST material, e.g. G4_Fe ");
fMaterial->SetParameterName("choiceMaterial", true);
fMaterial->SetDefaultValue("G4_Fe");
fMaterial->AvailableForStates(G4State_PreInit, G4State_Idle);
fDiameter = new G4UIcmdWithADoubleAndUnit( "/mydet/diameter", this );
fDiameter->SetParameterName( "choiceDiameter", true );
fDiameter->SetGuidance( "Target diameter" );
fDiameter->SetDefaultValue( 1000.0 ); // default: 1 meter.
fDiameter->AvailableForStates( G4State_PreInit, G4State_Idle );
fThickness = new G4UIcmdWithADoubleAndUnit("/mydet/thickness", this);
fThickness->SetParameterName("choiceThickness", true);
fThickness->SetGuidance("Target thickness");
fThickness->SetDefaultValue(1000.0); // default: 1 meter.
fThickness->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter( "/mydet/update", this);
fUpdateCommand->SetGuidance( "Update calorimeter geometry." );
fUpdateCommand->SetGuidance( "This command MUST be applied before \"beamOn\" " );
fUpdateCommand->SetGuidance( "if you changed geometrical value(s)." );
fUpdateCommand->AvailableForStates( G4State_Idle );
fDiameter = new G4UIcmdWithADoubleAndUnit("/mydet/diameter", this);
fDiameter->SetParameterName("choiceDiameter", true);
fDiameter->SetGuidance("Target diameter");
fDiameter->SetDefaultValue(1000.0); // default: 1 meter.
fDiameter->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter("/mydet/update", this);
fUpdateCommand->SetGuidance("Update calorimeter geometry.");
fUpdateCommand->SetGuidance("This command MUST be applied before \"beamOn\" ");
fUpdateCommand->SetGuidance("if you changed geometrical value(s).");
fUpdateCommand->AvailableForStates(G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::~DetectorMessenger() {
DetectorMessenger::~DetectorMessenger()
{
delete fDetectorDir;
delete fMaterial;
delete fThickness;
@@ -83,17 +87,18 @@ DetectorMessenger::~DetectorMessenger() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue( G4UIcommand* command, G4String newValue ) {
if ( command == fMaterial ) {
fDetector->SetMaterial( newValue );
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fMaterial) {
fDetector->SetMaterial(newValue);
}
if ( command == fThickness ) {
fDetector->SetThickness( fThickness->GetNewDoubleValue( newValue ) );
if (command == fThickness) {
fDetector->SetThickness(fThickness->GetNewDoubleValue(newValue));
}
if ( command == fDiameter ) {
fDetector->SetDiameter( fDiameter->GetNewDoubleValue(newValue) );
if (command == fDiameter) {
fDetector->SetDiameter(fDiameter->GetNewDoubleValue(newValue));
}
if ( command == fUpdateCommand ) {
if (command == fUpdateCommand) {
fDetector->UpdateGeometry();
}
}
@@ -32,54 +32,59 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "PrimaryGeneratorAction.hh"
#include "DetectorConstruction.hh"
#include "G4Event.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::
PrimaryGeneratorAction( const DetectorConstruction* pDetector ) :
fPointerDetectorConstruction( pDetector )
PrimaryGeneratorAction::PrimaryGeneratorAction(const DetectorConstruction* pDetector)
: fPointerDetectorConstruction(pDetector)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun( n_particle );
fParticleGun = new G4ParticleGun(n_particle);
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition( particleTable->FindParticle( "geantino" ) );
fParticleGun->SetParticleEnergy( 10.0*GeV );
fParticleGun->SetParticleDefinition(particleTable->FindParticle("geantino"));
fParticleGun->SetParticleEnergy(10.0 * GeV);
SetGunPosition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete fParticleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::SetGunPosition() const {
void PrimaryGeneratorAction::SetGunPosition() const
{
// Shoot the particle in the middle between the world and the target layer
G4double targetThickness =
( fPointerDetectorConstruction ? fPointerDetectorConstruction->GetThickness() : 0.0 );
G4double gunPosition = -0.55*targetThickness; //***LOOKHERE*** default gun position
// along the z-axis
G4cout << G4endl << "PrimaryGenerationAction::SetGunPosition() : gun position along z = "
<< gunPosition << " mm " << G4endl << G4endl;
fParticleGun->SetParticlePosition( G4ThreeVector( 0.0, 0.0, gunPosition ) );
(fPointerDetectorConstruction ? fPointerDetectorConstruction->GetThickness() : 0.0);
G4double gunPosition = -0.55 * targetThickness; //***LOOKHERE*** default gun position
// along the z-axis
G4cout << G4endl
<< "PrimaryGenerationAction::SetGunPosition() : gun position along z = " << gunPosition
<< " mm " << G4endl << G4endl;
fParticleGun->SetParticlePosition(G4ThreeVector(0.0, 0.0, gunPosition));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries( G4Event* anEvent ) {
G4ThreeVector v( 0.0, 0.0, 1.0 ); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection( v );
fParticleGun->GeneratePrimaryVertex( anEvent );
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
G4ThreeVector v(0.0, 0.0, 1.0); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection(v);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,39 +32,46 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "Run.hh"
#include "G4SystemOfUnits.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() : G4Run(), fNumEvents( 0 ),
fPrimaryParticleId( 0 ), fPrimaryParticleEnergy( 0.0 ),
fPrimaryParticleDirection( G4ThreeVector( 0.0, 0.0, 0.0 ) ),
fTargetMaterialName( "" ),
fCubicVolumeScoringUpDown( 1.0 ), fCubicVolumeScoringSide( 1.0 )
Run::Run()
: G4Run(),
fNumEvents(0),
fPrimaryParticleId(0),
fPrimaryParticleEnergy(0.0),
fPrimaryParticleDirection(G4ThreeVector(0.0, 0.0, 0.0)),
fTargetMaterialName(""),
fCubicVolumeScoringUpDown(1.0),
fCubicVolumeScoringSide(1.0)
{
fSteppingArray.fill( 0.0 );
fTrackingArray1.fill( 0 );
fTrackingArray2.fill( 0.0 );
fSteppingArray.fill(0.0);
fTrackingArray1.fill(0);
fTrackingArray2.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::RecordEvent( const G4Event* anEvent ) {
void Run::RecordEvent(const G4Event* anEvent)
{
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event : in MT-mode, it is called only for the working thread that handled the event.
G4int nEvt = anEvent->GetEventID();
if ( nEvt % 10 == 0 ) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent( anEvent );
if (nEvt % 10 == 0) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge( const G4Run* aRun ) {
void Run::Merge(const G4Run* aRun)
{
// This method is called automatically by the Geant4 kernel (not by the user!) only in the case
// of multithreaded mode and only for working threads.
const Run* localRun = static_cast< const Run* >( aRun );
const Run* localRun = static_cast<const Run*>(aRun);
fPrimaryParticleId = localRun->GetPrimaryParticleId();
fPrimaryParticleEnergy = localRun->GetPrimaryParticleEnergy();
fPrimaryParticleDirection = localRun->GetPrimaryParticleDirection();
@@ -72,54 +79,52 @@ void Run::Merge( const G4Run* aRun ) {
fCubicVolumeScoringUpDown = localRun->GetCubicVolumeScoringUpDown();
fCubicVolumeScoringSide = localRun->GetCubicVolumeScoringSide();
fNumEvents += localRun->GetNumberOfEvent();
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] += localRun->GetSteppingArray()[i];
}
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] += localRun->GetTrackingArray1()[i];
fTrackingArray2[i] += localRun->GetTrackingArray2()[i];
}
G4Run::Merge( aRun );
G4Run::Merge(aRun);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::PrintInfo() const {
void Run::PrintInfo() const
{
// This method is called by RunAction::EndOfRunAction. In MT-mode, only the master thread
// calls it.
const G4double floatingNumberOfEvents =
std::max( 1.0, fNumEvents > 0 ? fNumEvents*1.0 : GetNumberOfEvent()*1.0 );
std::max(1.0, fNumEvents > 0 ? fNumEvents * 1.0 : GetNumberOfEvent() * 1.0);
// The fluence in the scoring volume is defined as sum of step lengths in that volume
// divided by the volume of that scoring volume.
const G4double conversionFactor = CLHEP::cm * CLHEP::cm; // From mm^-2 to cm^-2
const G4double factorUpDown =
conversionFactor / ( fCubicVolumeScoringUpDown*floatingNumberOfEvents );
const G4double factorSide =
conversionFactor / ( fCubicVolumeScoringSide*floatingNumberOfEvents );
conversionFactor / (fCubicVolumeScoringUpDown * floatingNumberOfEvents);
const G4double factorSide = conversionFactor / (fCubicVolumeScoringSide * floatingNumberOfEvents);
G4cout << std::setprecision(6) << G4endl << G4endl
<< " =============== Run::PrintInfo() =============== \t RunID = " << GetRunID()
<< G4endl
<< " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV
<< " GeV" << G4endl
<< " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< G4endl << " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV << " GeV"
<< G4endl << " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< " Target material = " << fTargetMaterialName << G4endl
<< " Cubic-volume scoring up-down = " << fCubicVolumeScoringUpDown << " mm^3" << G4endl
<< " Cubic-volume scoring side = " << fCubicVolumeScoringSide << " mm^3" << G4endl
<< " Cubic-volume scoring side = " << fCubicVolumeScoringSide << " mm^3" << G4endl
<< " Number of events = " << floatingNumberOfEvents << G4endl
<< " Conversion factor: fluence from mm^-2 to cm^-2 = " << conversionFactor << G4endl
<< " Particle fluence in unit of cm^-2 :" << G4endl;
for ( G4int i = 0; i < SteppingAction::fkNumberScoringVolumes; ++i ) {
G4double factor = ( i == 1 ? factorSide : factorUpDown );
for ( G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k ) {
G4int index = SteppingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << SteppingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << SteppingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << SteppingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << factor*fSteppingArray[index] << G4endl;
for (G4int i = 0; i < SteppingAction::fkNumberScoringVolumes; ++i) {
G4double factor = (i == 1 ? factorSide : factorUpDown);
for (G4int j = 0; j < SteppingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k) {
G4int index = SteppingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< SteppingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< SteppingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< SteppingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< factor * fSteppingArray[index] << G4endl;
}
}
}
@@ -127,21 +132,19 @@ void Run::PrintInfo() const {
<< " Extra information: particle production \t \t <N> <E_kin> <Sum_Ekin> [MeV]"
<< G4endl;
const G4double normalization = 1.0 / floatingNumberOfEvents;
for ( G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i ) {
for ( G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k ) {
G4int index = TrackingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << TrackingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << TrackingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << TrackingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << normalization * fTrackingArray1[index]
<< " " << std::setw( 8) << ( fTrackingArray1[index] > 0 ?
fTrackingArray2[index] / fTrackingArray1[index] :
0.0 )
<< " " << std::setw( 8) << normalization * fTrackingArray2[index]
<< G4endl;
for (G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i) {
for (G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k) {
G4int index = TrackingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< TrackingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< TrackingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< TrackingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< normalization * fTrackingArray1[index] << " " << std::setw(8)
<< (fTrackingArray1[index] > 0 ? fTrackingArray2[index] / fTrackingArray1[index]
: 0.0)
<< " " << std::setw(8) << normalization * fTrackingArray2[index] << G4endl;
}
}
}
@@ -150,27 +153,30 @@ void Run::PrintInfo() const {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
void Run::SetSteppingArray(
const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray1(
const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray2(
const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray2[i] = inputArray[i];
}
}
@@ -32,46 +32,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "RunAction.hh"
#include "globals.hh"
#include "G4Run.hh"
#include "Run.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction( SteppingAction* steppingAction, TrackingAction* trackingAction ) :
G4UserRunAction(), fSteppingAction( steppingAction ), fTrackingAction( trackingAction ) {}
RunAction::RunAction(SteppingAction* steppingAction, TrackingAction* trackingAction)
: G4UserRunAction(), fSteppingAction(steppingAction), fTrackingAction(trackingAction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun() {
G4Run* RunAction::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction( const G4Run* aRun ) {
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
G4cout << "### Run " << aRun->GetRunID() << " starts." << G4endl;
Run* run = const_cast< Run* >( static_cast< const Run* >( aRun ) );
if ( run == nullptr ) return;
if ( fSteppingAction != nullptr ) {
Run* run = const_cast<Run*>(static_cast<const Run*>(aRun));
if (run == nullptr) return;
if (fSteppingAction != nullptr) {
fSteppingAction->Initialize();
fSteppingAction->SetRunPointer( run );
fSteppingAction->SetRunPointer(run);
}
if ( fTrackingAction != nullptr ) {
if (fTrackingAction != nullptr) {
fTrackingAction->Initialize();
fTrackingAction->SetRunPointer( run );
fTrackingAction->SetRunPointer(run);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction( const G4Run* aRun ) {
const Run* run = static_cast< const Run* >( aRun );
if ( run == nullptr || run->GetNumberOfEvent() == 0 ) return;
if ( IsMaster() ) run->PrintInfo();
void RunAction::EndOfRunAction(const G4Run* aRun)
{
const Run* run = static_cast<const Run*>(aRun);
if (run == nullptr || run->GetNumberOfEvent() == 0) return;
if (IsMaster()) run->PrintInfo();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,44 +32,47 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "SteppingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include "G4VSolid.hh"
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, SteppingAction::fkNumberScoringVolumes >
SteppingAction::fkArrayScoringVolumeNames = { "downstream", "side", "upstream" };
#include "G4IonTable.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VSolid.hh"
#include "G4VTouchable.hh"
const std::array< G4String, SteppingAction::fkNumberKinematicRegions >
SteppingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, SteppingAction::fkNumberScoringVolumes>
SteppingAction::fkArrayScoringVolumeNames = {"downstream", "side", "upstream"};
const std::array< G4String, SteppingAction::fkNumberParticleTypes >
SteppingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, SteppingAction::fkNumberKinematicRegions>
SteppingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, SteppingAction::fkNumberParticleTypes>
SteppingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int SteppingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int SteppingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
if ( index < 0 || index >= fkNumberCombinations ) {
if (index < 0 || index >= fkNumberCombinations) {
G4cerr << "SteppingAction::GetIndex : WRONG index=" << index << " set it to 0 !" << G4endl;
index = 0;
}
@@ -78,25 +81,27 @@ G4int SteppingAction::GetIndex( const G4int iScoringVolume, const G4int iKinemat
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction() : G4UserSteppingAction() {
SteppingAction::SteppingAction() : G4UserSteppingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::Initialize() {
// Initialization needed at the beginning of each Run
void SteppingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fPrimaryParticleId = 0;
fPrimaryParticleEnergy = 0.0;
fPrimaryParticleDirection = G4ThreeVector( 0.0, 0.0, 1.0 );
fPrimaryParticleDirection = G4ThreeVector(0.0, 0.0, 1.0);
fTargetMaterialName = "";
fIsFirstStepOfTheEvent = true;
fIsFirstStepInTarget = true;
fIsFirstStepInScoringUpDown = true;
fIsFirstStepInScoringSide = true;
fIsFirstStepInScoringUpDown = true;
fIsFirstStepInScoringSide = true;
fCubicVolumeScoringUpDown = 1.0;
fCubicVolumeScoringSide = 1.0;
for ( G4int i = 0; i < fkNumberCombinations; ++i ) {
for (G4int i = 0; i < fkNumberCombinations; ++i) {
fArraySumStepLengths[i] = 0.0;
}
/*
@@ -121,67 +126,72 @@ void SteppingAction::Initialize() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
void SteppingAction::UserSteppingAction(const G4Step* theStep)
{
// Get information on the primary particle
if ( fIsFirstStepOfTheEvent ) {
if ( theStep->GetTrack()->GetParentID() == 0 ) {
if (fIsFirstStepOfTheEvent) {
if (theStep->GetTrack()->GetParentID() == 0) {
fPrimaryParticleId = theStep->GetTrack()->GetDefinition()->GetPDGEncoding();
fPrimaryParticleEnergy = theStep->GetPreStepPoint()->GetKineticEnergy();
fPrimaryParticleDirection = theStep->GetPreStepPoint()->GetMomentumDirection();
if ( fRunPtr ) {
fRunPtr->SetPrimaryParticleId( fPrimaryParticleId );
fRunPtr->SetPrimaryParticleEnergy( fPrimaryParticleEnergy );
fRunPtr->SetPrimaryParticleDirection( fPrimaryParticleDirection );
if (fRunPtr) {
fRunPtr->SetPrimaryParticleId(fPrimaryParticleId);
fRunPtr->SetPrimaryParticleEnergy(fPrimaryParticleEnergy);
fRunPtr->SetPrimaryParticleDirection(fPrimaryParticleDirection);
}
fIsFirstStepOfTheEvent = false;
}
}
// Get information on the target material
if ( fIsFirstStepInTarget &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiLayer" ) {
if (fIsFirstStepInTarget
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiLayer")
{
fTargetMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetTargetMaterialName( fTargetMaterialName );
if (fRunPtr) fRunPtr->SetTargetMaterialName(fTargetMaterialName);
fIsFirstStepInTarget = false;
}
// Get information on step lengths in the scoring volumes
G4int iScoringVolume = -1;
if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringDownstream" ) {
if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringDownstream") {
iScoringVolume = 0;
if ( fIsFirstStepInScoringUpDown ) {
if (fIsFirstStepInScoringUpDown) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringUpDown( fCubicVolumeScoringUpDown );
fIsFirstStepInScoringUpDown = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringSide" ) {
iScoringVolume = 1;
if ( fIsFirstStepInScoringSide ) {
fCubicVolumeScoringSide =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringSide( fCubicVolumeScoringSide );
fIsFirstStepInScoringSide = false;
}
} else if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() ==
"physiScoringUpstream" ) {
iScoringVolume = 2;
if ( fIsFirstStepInScoringUpDown ) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringUpDown( fCubicVolumeScoringUpDown );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringUpDown(fCubicVolumeScoringUpDown);
fIsFirstStepInScoringUpDown = false;
}
}
if ( iScoringVolume >= 0 ) {
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringSide") {
iScoringVolume = 1;
if (fIsFirstStepInScoringSide) {
fCubicVolumeScoringSide =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if (fRunPtr) fRunPtr->SetCubicVolumeScoringSide(fCubicVolumeScoringSide);
fIsFirstStepInScoringSide = false;
}
}
else if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringUpstream") {
iScoringVolume = 2;
if (fIsFirstStepInScoringUpDown) {
fCubicVolumeScoringUpDown =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if (fRunPtr) fRunPtr->SetCubicVolumeScoringUpDown(fCubicVolumeScoringUpDown);
fIsFirstStepInScoringUpDown = false;
}
}
if (iScoringVolume >= 0) {
// In the case of the upstream scoring volume, consider only particles whose direction
// is opposite with respect to the primary particle (this is needed, in particular,
// for avoiding to account the incoming, primary beam particle in the "upstream" fluence).
if ( iScoringVolume == 2 && fPrimaryParticleDirection.dot(
theStep->GetPreStepPoint()->GetMomentumDirection() ) > 0.0 ) {
if (iScoringVolume == 2
&& fPrimaryParticleDirection.dot(theStep->GetPreStepPoint()->GetMomentumDirection()) > 0.0)
{
return;
}
G4double stepLength = theStep->GetTrack()->GetStepLength() * theStep->GetTrack()->GetWeight();
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr ? 0 :
std::abs( theStep->GetTrack()->GetDefinition()->GetPDGEncoding() );
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr
? 0
: std::abs(theStep->GetTrack()->GetDefinition()->GetPDGEncoding());
/*
G4cout << std::setprecision(6)
<< theStep->GetTrack()->GetDefinition()->GetParticleName() << " absPdg=" << absPdg
@@ -190,42 +200,52 @@ void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
<< "," << theStep->GetTrack()->GetPosition().z() << ")"
<< " " << theStep->GetTrack()->GetVolume()->GetName()
<< " " << theStep->GetTrack()->GetMaterial()->GetName()
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot(
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot(
theStep->GetPreStepPoint()->GetMomentumDirection() ) > 0.0
? "forward" : "backward" )
? "forward" : "backward" )
<< G4endl;
*/
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = theStep->GetPreStepPoint()->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4; // neutrinos
//(and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( theStep->GetTrack()->GetDefinition() ) || // ions (and anti-ions)
G4IonTable::IsAntiIon( theStep->GetTrack()->GetDefinition() ) ) iParticleType = 8;
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4; // neutrinos
//(and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(theStep->GetTrack()->GetDefinition()) || // ions (and anti-ions)
G4IonTable::IsAntiIon(theStep->GetTrack()->GetDefinition()))
iParticleType = 8;
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex(iScoringVolume, 0, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
fArraySumStepLengths[index] += stepLength;
if ( fRunPtr ) fRunPtr->SetSteppingArray( fArraySumStepLengths );
if (fRunPtr) fRunPtr->SetSteppingArray(fArraySumStepLengths);
}
}
@@ -32,112 +32,127 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "TrackingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, TrackingAction::fkNumberScoringVolumes >
TrackingAction::fkArrayScoringVolumeNames = { "layer" };
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4Track.hh"
const std::array< G4String, TrackingAction::fkNumberKinematicRegions >
TrackingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, TrackingAction::fkNumberScoringVolumes>
TrackingAction::fkArrayScoringVolumeNames = {"layer"};
const std::array< G4String, TrackingAction::fkNumberParticleTypes >
TrackingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, TrackingAction::fkNumberKinematicRegions>
TrackingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, TrackingAction::fkNumberParticleTypes>
TrackingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int TrackingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int TrackingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
return index;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TrackingAction::TrackingAction() : G4UserTrackingAction() {
TrackingAction::TrackingAction() : G4UserTrackingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::Initialize() {
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill( 0 );
fArraySumKineticEnergies.fill( 0.0 );
void TrackingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill(0);
fArraySumKineticEnergies.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PreUserTrackingAction( const G4Track* aTrack ) {
// This method is called not only once when a particle is created,
void TrackingAction::PreUserTrackingAction(const G4Track* aTrack)
{
// This method is called not only once when a particle is created,
// but also each time it is resumed, in the case the track gets suspended,
// as it happens in the case of neutrons with _HP Physics Lists.
// To be sure that we collect information about a track one and only once,
// we require that the current step be the first one.
if ( aTrack == nullptr ||
aTrack->GetCurrentStepNumber() != 0 ||
aTrack->GetDefinition() == nullptr ||
aTrack->GetLogicalVolumeAtVertex() == nullptr ||
aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicLayer" ) return;
if (aTrack == nullptr || aTrack->GetCurrentStepNumber() != 0 || aTrack->GetDefinition() == nullptr
|| aTrack->GetLogicalVolumeAtVertex() == nullptr
|| aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicLayer")
return;
G4int iScoringVolume = 0;
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = aTrack->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int absPdg = std::abs( aTrack->GetDefinition()->GetPDGEncoding() );
G4int absPdg = std::abs(aTrack->GetDefinition()->GetPDGEncoding());
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( aTrack->GetDefinition() ) ||
G4IonTable::IsAntiIon( aTrack->GetDefinition() ) ) iParticleType = 8;
// ions (and anti-ions)
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(aTrack->GetDefinition())
|| G4IonTable::IsAntiIon(aTrack->GetDefinition()))
iParticleType = 8;
// ions (and anti-ions)
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
index = GetIndex(iScoringVolume, 0, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
if ( fRunPtr ) {
fRunPtr->SetTrackingArray1( fArrayMultiplicities );
fRunPtr->SetTrackingArray2( fArraySumKineticEnergies );
if (fRunPtr) {
fRunPtr->SetTrackingArray1(fArrayMultiplicities);
fRunPtr->SetTrackingArray2(fArraySumKineticEnergies);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PostUserTrackingAction( const G4Track* /* aTrack */ ) {}
void TrackingAction::PostUserTrackingAction(const G4Track* /* aTrack */) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -31,40 +31,42 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4Threading.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "G4PhysListFactory.hh"
#include "G4RunManagerFactory.hh"
#include "G4Threading.hh"
#include "G4UImanager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv) {
int main(int argc, char** argv)
{
auto* runManager = G4RunManagerFactory::CreateRunManager();
DetectorConstruction* pDetectorInstance = new DetectorConstruction;
runManager->SetUserInitialization( pDetectorInstance );
runManager->SetUserInitialization(pDetectorInstance);
// Physics list factory: use the PHYSLIST environmental variable.
G4PhysListFactory factory;
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
G4VModularPhysicsList* thePL = factory.ReferencePhysList();
runManager->SetUserInitialization( thePL );
runManager->SetUserInitialization( new ActionInitialization );
runManager->SetUserInitialization(thePL);
runManager->SetUserInitialization(new ActionInitialization);
G4UImanager* UI = G4UImanager::GetUIpointer();
if ( argc==1 ) { // Define UI session for interactive mode.
} else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
G4UImanager* UI = G4UImanager::GetUIpointer();
if (argc == 1) { // Define UI session for interactive mode.
}
else { // Batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command + fileName);
}
// job termination
delete runManager;
return 0;
// job termination
delete runManager;
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,7 @@
/// \file ActionInitialization.hh
/// \brief Definition of the ActionInitialization class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -38,7 +38,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class ActionInitialization : public G4VUserActionInitialization {
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
~ActionInitialization() override = default;
@@ -26,7 +26,7 @@
/// \file DetectorConstruction.hh
/// \brief Definition of the DetectorConstruction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -35,7 +35,7 @@
#define DetectorConstruction_H 1
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
#include "globals.hh"
class G4LogicalVolume;
class G4VPhysicalVolume;
@@ -44,41 +44,46 @@ class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction {
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
G4VPhysicalVolume* Construct();
void SetMaterial( const G4String name );
void SetMaterial(const G4String name);
inline G4Material* GetMaterial() const;
inline void SetRadius( const G4double value );
inline void SetRadius(const G4double value);
inline G4double GetRadius() const;
void UpdateGeometry();
private:
G4VPhysicalVolume* ConstructSphere(); // To be invoked each time the geometry needs
// to be updated
void PrintParameters();
G4Material* fMaterial;
G4LogicalVolume* fExperimentalHall_log;
G4LogicalVolume* fExperimentalHall_log;
G4VPhysicalVolume* fExperimentalHall_phys;
G4LogicalVolume* fLogicSphere;
G4LogicalVolume* fLogicSphere;
G4VPhysicalVolume* fPhysiSphere;
G4LogicalVolume* fLogicScoringShell;
G4LogicalVolume* fLogicScoringShell;
G4VPhysicalVolume* fPhysiScoringShell;
DetectorMessenger* fDetectorMessenger;
G4double fRadius;
const G4double fScoringThickness = 10.0; //***LOOKHERE*** thickness of the scoring shell
};
inline G4Material* DetectorConstruction::GetMaterial() const {
inline G4Material* DetectorConstruction::GetMaterial() const
{
return fMaterial;
}
inline void DetectorConstruction::SetRadius( const G4double value ) {
inline void DetectorConstruction::SetRadius(const G4double value)
{
fRadius = value;
}
inline G4double DetectorConstruction::GetRadius() const {
inline G4double DetectorConstruction::GetRadius() const
{
return fRadius;
}
@@ -26,7 +26,7 @@
/// \file DetectorMessenger.hh
/// \brief Definition of the DetectorMessenger class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,8 +34,8 @@
#ifndef DetectorMessenger_h
#define DetectorMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
#include "globals.hh"
class DetectorConstruction;
class G4UIdirectory;
@@ -45,17 +45,19 @@ class G4UIcmdWithoutParameter;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorMessenger: public G4UImessenger {
class DetectorMessenger : public G4UImessenger
{
public:
DetectorMessenger( DetectorConstruction* );
DetectorMessenger(DetectorConstruction*);
~DetectorMessenger();
void SetNewValue( G4UIcommand*, G4String ) override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
G4UIcmdWithAString* fMaterial;
DetectorConstruction* fDetector;
G4UIdirectory* fDetectorDir;
G4UIcmdWithAString* fMaterial;
G4UIcmdWithADoubleAndUnit* fRadius;
G4UIcmdWithoutParameter* fUpdateCommand;
G4UIcmdWithoutParameter* fUpdateCommand;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file PrimaryGeneratorAction.hh
/// \brief Definition of the PrimaryGeneratorAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,12 +41,14 @@ class G4Event;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction();
~PrimaryGeneratorAction();
void GeneratePrimaries( G4Event* anEvent ) override;
void GeneratePrimaries(G4Event* anEvent) override;
void SetGunPosition() const;
private:
G4ParticleGun* fParticleGun;
};
@@ -26,7 +26,7 @@
/// \file Run.hh
/// \brief Definition of the Run class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,87 +34,102 @@
#ifndef Run_h
#define Run_h 1
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4ThreeVector.hh"
#include <array>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class Run : public G4Run {
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
class Run : public G4Run
{
// This class accumulates relevant quantities related to particle fluence collected during
// the run.
// ( Note: these information are provided via calls of accessor methods of this Run class
// made by SteppingAction::UserSteppingAction
// and TrackingAction::PreUserTrackingAction. )
// At the end of a run, the PrintInfo method is called by the run-action to print out
// some summary information about these quantities.
// In multithreaded (MT) mode, an object of this class is filled up for each working thread,
// and then merged (automatically by the Geant4 kernel) into another object (of this class)
// owned by the master class; the PrintInfo method is then called only for the latter run
// object.
// Note that, for simplicity and brevity, we avoid histograms and print-out instead some
// statistics (compute by ourself) at the end of the run.
public:
Run();
~Run() override = default;
void RecordEvent( const G4Event* anEvent ) override;
void RecordEvent(const G4Event* anEvent) override;
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event. In the case of multithreaded mode, it is called only for the working thread
// that handled that event.
void Merge( const G4Run* aRun ) override;
void Merge(const G4Run* aRun) override;
// This method is called automatically by the Geant4 kernel (not by the user!) only in the
// case of multithreaded mode and only for working threads.
void PrintInfo() const;
// This method is called by RunAction::EndOfRunAction : in the case of multithreaded mode,
// only the master thread calls it.
void SetPrimaryParticleId( const G4int inputValue ) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy( const G4double inputValue )
{ fPrimaryParticleEnergy = inputValue; }
void SetPrimaryParticleDirection( const G4ThreeVector &inputValue )
{ fPrimaryParticleDirection = inputValue; }
void SetTargetMaterialName( const G4String &inputValue ) { fTargetMaterialName = inputValue; }
void SetCubicVolumeScoringShell( const G4double inputValue )
{ fCubicVolumeScoringShell = inputValue; }
void SetPrimaryParticleId(const G4int inputValue) { fPrimaryParticleId = inputValue; }
void SetPrimaryParticleEnergy(const G4double inputValue)
{
fPrimaryParticleEnergy = inputValue;
}
void SetPrimaryParticleDirection(const G4ThreeVector& inputValue)
{
fPrimaryParticleDirection = inputValue;
}
void SetTargetMaterialName(const G4String& inputValue) { fTargetMaterialName = inputValue; }
void SetCubicVolumeScoringShell(const G4double inputValue)
{
fCubicVolumeScoringShell = inputValue;
}
G4int GetPrimaryParticleId() const { return fPrimaryParticleId; }
G4double GetPrimaryParticleEnergy() const { return fPrimaryParticleEnergy; }
G4ThreeVector GetPrimaryParticleDirection() const { return fPrimaryParticleDirection; }
G4String GetTargetMaterialName() const { return fTargetMaterialName; }
G4double GetCubicVolumeScoringShell() const { return fCubicVolumeScoringShell; }
void SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray );
std::array< G4double, SteppingAction::fkNumberCombinations > GetSteppingArray() const
{ return fSteppingArray; }
void
SetSteppingArray(const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray);
std::array<G4double, SteppingAction::fkNumberCombinations> GetSteppingArray() const
{
return fSteppingArray;
}
// Accessor methods useful to transfer information collected by the stepping-action
// into this Run class
void SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4long, TrackingAction::fkNumberCombinations > GetTrackingArray1() const
{ return fTrackingArray1; }
void SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray );
std::array< G4double, TrackingAction::fkNumberCombinations > GetTrackingArray2() const
{ return fTrackingArray2; }
void
SetTrackingArray1(const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4long, TrackingAction::fkNumberCombinations> GetTrackingArray1() const
{
return fTrackingArray1;
}
void
SetTrackingArray2(const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray);
std::array<G4double, TrackingAction::fkNumberCombinations> GetTrackingArray2() const
{
return fTrackingArray2;
}
// Accessor methods useful to transfer information collected by the tracking-action
// into this Run class
private:
private:
G4int fNumEvents;
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
G4ThreeVector fPrimaryParticleDirection;
G4String fTargetMaterialName;
G4double fCubicVolumeScoringShell;
std::array< G4double, SteppingAction::fkNumberCombinations > fSteppingArray;
std::array< G4long, TrackingAction::fkNumberCombinations > fTrackingArray1;
std::array< G4double, TrackingAction::fkNumberCombinations > fTrackingArray2;
std::array<G4double, SteppingAction::fkNumberCombinations> fSteppingArray;
std::array<G4long, TrackingAction::fkNumberCombinations> fTrackingArray1;
std::array<G4double, TrackingAction::fkNumberCombinations> fTrackingArray2;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file RunAction.hh
/// \brief Definition of the RunAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -42,17 +42,18 @@ class TrackingAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class RunAction: public G4UserRunAction {
class RunAction : public G4UserRunAction
{
public:
RunAction( SteppingAction* steppingAction = nullptr,
TrackingAction* trackingAction = nullptr );
RunAction(SteppingAction* steppingAction = nullptr, TrackingAction* trackingAction = nullptr);
~RunAction() override = default;
void BeginOfRunAction( const G4Run* aRun ) override;
void EndOfRunAction( const G4Run* aRun ) override;
void BeginOfRunAction(const G4Run* aRun) override;
void EndOfRunAction(const G4Run* aRun) override;
G4Run* GenerateRun() override;
private:
SteppingAction* fSteppingAction;
TrackingAction* fTrackingAction;
TrackingAction* fTrackingAction;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -26,7 +26,7 @@
/// \file SteppingAction.hh
/// \brief Definition of the SteppingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,21 +34,23 @@
#ifndef SteppingAction_H
#define SteppingAction_H 1
#include "globals.hh"
#include "G4UserSteppingAction.hh"
#include "G4ThreeVector.hh"
#include "G4UserSteppingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class SteppingAction : public G4UserSteppingAction {
public:
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction();
~SteppingAction() override = default;
void UserSteppingAction( const G4Step* ) override;
void UserSteppingAction(const G4Step*) override;
// This is the main method where the step lengths of particles inside
// the scoring shell are collected, and then the corresponding fluences
// are filled up in the Run object where they are stored (and then
@@ -62,7 +64,7 @@ class SteppingAction : public G4UserSteppingAction {
// This is necessary because different runs can have different primary particle
// types, kinetic energies, and detector configurations.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// stepping-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the stepping-action
@@ -71,21 +73,21 @@ class SteppingAction : public G4UserSteppingAction {
G4double GetCubicVolumeScoringShell() const { return fCubicVolumeScoringShell; }
// The cubic-volume of the scoring shell is needed to get the fluence from the
// sum of step lengths inside that scoring shell.
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberScoringPositions = 2; // forward, backward (hemisphere with
// respect to the primary particle direction)
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// respect to the primary particle direction)
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberKinematicRegions*fkNumberScoringPositions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberScoringPositions > fkArrayScoringPositionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iKinematicRegion, const G4int iScoringPosition,
const G4int iParticleType );
private:
fkNumberKinematicRegions * fkNumberScoringPositions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberScoringPositions> fkArrayScoringPositionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iKinematicRegion, const G4int iScoringPosition,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
G4int fPrimaryParticleId;
G4double fPrimaryParticleEnergy;
@@ -95,8 +97,8 @@ class SteppingAction : public G4UserSteppingAction {
G4bool fIsFirstStepInTarget;
G4bool fIsFirstStepInScoringShell;
G4double fCubicVolumeScoringShell;
std::array< G4double, fkNumberCombinations > fArraySumStepLengths;
std::array<G4double, fkNumberCombinations> fArraySumStepLengths;
// Array to collect the sum of step lengths in the scoring shell for the whole run,
// according to the various cases (kinematical region, scoring position and particle type).
// Note that the fluence in a scoring volume is defined as sum of step lengths
@@ -26,63 +26,65 @@
/// \file TrackingAction.hh
/// \brief Definition of the TrackingAction class
//
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef TrackingAction_h
#ifndef TrackingAction_h
#define TrackingAction_h 1
#include "globals.hh"
#include "G4UserTrackingAction.hh"
#include "globals.hh"
#include <array>
class Run;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class TrackingAction : public G4UserTrackingAction {
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the target sphere.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
class TrackingAction : public G4UserTrackingAction
{
// We are using this class to monitor the average multiplicity, the average
// kinetic energy, and the average total energy flow (i.e. sum of the
// kinetic energies) of different particle types as they are produced
// inside the target sphere.
// The aim is then to try to correlate some changes in these (more primitive)
// quantities with the observed changes in the (more indirect and complex)
// particle fluences.
public:
TrackingAction();
~TrackingAction() override = default;
void PreUserTrackingAction( const G4Track* ) override;
void PostUserTrackingAction( const G4Track* ) override;
void PreUserTrackingAction(const G4Track*) override;
void PostUserTrackingAction(const G4Track*) override;
void Initialize();
// This method is called by RunAction::BeginOfRunAction for the
// initialization of the tracking-action at the beginning of each Run.
void SetRunPointer( Run* inputValue = nullptr ) { fRunPtr = inputValue; }
void SetRunPointer(Run* inputValue = nullptr) { fRunPtr = inputValue; }
// This method is called by RunAction::BeginOfRunAction for providing to the
// tracking-action the pointer to the run object at the beginning of each Run.
// This pointer is then used to pass the information collected by the tracking-action
// to the run object.
static const G4int fkNumberScoringVolumes = 1; // only the target sphere
static const G4int fkNumberScoringVolumes = 1; // only the target sphere
static const G4int fkNumberKinematicRegions = 3; // all, below 20 MeV, above 20 MeV
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
static const G4int fkNumberParticleTypes = 11; // all, e, gamma, mu, nu, pi, n, p, ions,
// other-mesons, other-baryons
static const G4int fkNumberCombinations =
fkNumberScoringVolumes*fkNumberKinematicRegions*fkNumberParticleTypes;
static const std::array< G4String, fkNumberScoringVolumes > fkArrayScoringVolumeNames;
static const std::array< G4String, fkNumberKinematicRegions > fkArrayKinematicRegionNames;
static const std::array< G4String, fkNumberParticleTypes > fkArrayParticleTypeNames;
static G4int GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType );
fkNumberScoringVolumes * fkNumberKinematicRegions * fkNumberParticleTypes;
static const std::array<G4String, fkNumberScoringVolumes> fkArrayScoringVolumeNames;
static const std::array<G4String, fkNumberKinematicRegions> fkArrayKinematicRegionNames;
static const std::array<G4String, fkNumberParticleTypes> fkArrayParticleTypeNames;
static G4int GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType);
private:
Run* fRunPtr; // Pointer to the Run object
std::array< G4long, fkNumberCombinations > fArrayMultiplicities;
std::array< G4double, fkNumberCombinations > fArraySumKineticEnergies;
std::array<G4long, fkNumberCombinations> fArrayMultiplicities;
std::array<G4double, fkNumberCombinations> fArraySumKineticEnergies;
// Keep record of the number of particles and their kinetic energy at production,
// according to the particle type and their kinetic energy range (below/above 20 MeV).
};
@@ -32,11 +32,12 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "ActionInitialization.hh"
#include "PrimaryGeneratorAction.hh"
#include "Run.hh"
#include "RunAction.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -44,21 +45,23 @@ ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
void ActionInitialization::BuildForMaster() const
{
// This is NOT called in SEQ-mode, while in the MT-mode is called only for the Master thread.
SetUserAction( new RunAction );
SetUserAction(new RunAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
void ActionInitialization::Build() const
{
// This is called in the SEQ-mode and in the MT-mode only for Worker threads.
SetUserAction( new PrimaryGeneratorAction );
SetUserAction(new PrimaryGeneratorAction);
SteppingAction* steppingAction = new SteppingAction;
SetUserAction( steppingAction );
SetUserAction(steppingAction);
TrackingAction* trackingAction = new TrackingAction;
SetUserAction( trackingAction );
SetUserAction( new RunAction( steppingAction, trackingAction ) );
SetUserAction(trackingAction);
SetUserAction(new RunAction(steppingAction, trackingAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,59 +32,67 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
#include "G4Box.hh"
#include "G4GeometryManager.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Box.hh"
#include "G4Orb.hh"
#include "G4Sphere.hh"
#include "G4LogicalVolume.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "globals.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4RunManager.hh"
#include "G4SolidStore.hh"
#include "G4Sphere.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction() :
fMaterial( nullptr ),
fExperimentalHall_log( nullptr ), fExperimentalHall_phys( nullptr ),
fLogicSphere( nullptr ), fPhysiSphere( nullptr ),
fLogicScoringShell( nullptr ), fPhysiScoringShell( nullptr ),
fDetectorMessenger( nullptr ),
fRadius( 1.0*CLHEP::m ) //***LOOKHERE*** Default values
DetectorConstruction::DetectorConstruction()
: fMaterial(nullptr),
fExperimentalHall_log(nullptr),
fExperimentalHall_phys(nullptr),
fLogicSphere(nullptr),
fPhysiSphere(nullptr),
fLogicScoringShell(nullptr),
fPhysiScoringShell(nullptr),
fDetectorMessenger(nullptr),
fRadius(1.0 * CLHEP::m) //***LOOKHERE*** Default values
{
//G4cout << " BEGIN DetectorConstruction::DetectorConstruction()" << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" ); //***LOOKHERE***
// Default material
fDetectorMessenger = new DetectorMessenger( this );
//G4cout << " END DetectorConstruction::DetectorConstruction()" << G4endl;
// G4cout << " BEGIN DetectorConstruction::DetectorConstruction()" << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe"); //***LOOKHERE***
// Default material
fDetectorMessenger = new DetectorMessenger(this);
// G4cout << " END DetectorConstruction::DetectorConstruction()" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction() {
DetectorConstruction::~DetectorConstruction()
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct() {
//G4cout << " BEGIN DetectorConstruction::Construct()" << G4endl;
G4VPhysicalVolume* DetectorConstruction::Construct()
{
// G4cout << " BEGIN DetectorConstruction::Construct()" << G4endl;
return ConstructSphere();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructSphere() {
//G4cout << " BEGIN DetectorConstruction::ConstructSphere()" << G4endl;
G4VPhysicalVolume* DetectorConstruction::ConstructSphere()
{
// G4cout << " BEGIN DetectorConstruction::ConstructSphere()" << G4endl;
// Clean old geometry, if any.
G4GeometryManager::GetInstance()->OpenGeometry();
@@ -97,123 +105,119 @@ G4VPhysicalVolume* DetectorConstruction::ConstructSphere() {
// The world volume (experimental hall) is a box 10% bigger than the sphere
// and it is filled of "G4_Galactic" material.
G4double expHall_x = 1.1*fRadius; // half dimension along x
G4double expHall_y = 1.1*fRadius; // half dimension along y
G4double expHall_z = 1.1*fRadius; // half dimension along z
G4double expHall_x = 1.1 * fRadius; // half dimension along x
G4double expHall_y = 1.1 * fRadius; // half dimension along y
G4double expHall_z = 1.1 * fRadius; // half dimension along z
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Galactic" );
G4Material* vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
// Experimental hall
G4Box* experimentalHall_box = new G4Box( "expHall_box", expHall_x, expHall_y, expHall_z );
fExperimentalHall_log = new G4LogicalVolume( experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fExperimentalHall_phys = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Box* experimentalHall_box = new G4Box("expHall_box", expHall_x, expHall_y, expHall_z);
fExperimentalHall_log = new G4LogicalVolume(experimentalHall_box, // solid
vacuum, // material
"expHall_log", // name
0, // field manager
0, // sensitive detector
0); // user limits
fExperimentalHall_phys = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"expHall", // name
fExperimentalHall_log, // logical volume
0, // mother physical volume
false, // boolean operation
0); // copy number
// Target sphere
G4Orb* solidSphere = new G4Orb( "solidSphere", // name
fRadius ); // outer radius
fLogicSphere = new G4LogicalVolume( solidSphere, // solid
fMaterial, // material
"logicSphere", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiSphere = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiSphere", // name
fLogicSphere, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Orb* solidSphere = new G4Orb("solidSphere", // name
fRadius); // outer radius
fLogicSphere = new G4LogicalVolume(solidSphere, // solid
fMaterial, // material
"logicSphere", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiSphere = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiSphere", // name
fLogicSphere, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
// Scoring shell (a thin vacuum layer, immediately outside the target sphere)
G4Sphere* solidScoringShell = new G4Sphere( "solidScoringShell", // name
fRadius, // Inner radius (the radius
// of the target sphere)
fRadius + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0*CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi ); // Delta Theta angle of the
// segment in radians
fLogicScoringShell = new G4LogicalVolume( solidScoringShell, // solid
vacuum, // material
"logicScoringShell", // name
0, // field manager
0, // sensitive detector
0 ); // user limits
fPhysiScoringShell = new G4PVPlacement( 0, // rotation
G4ThreeVector(), // translation
"physiScoringShell", // name
fLogicScoringShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0 ); // copy number
G4Sphere* solidScoringShell = new G4Sphere("solidScoringShell", // name
fRadius, // Inner radius (the radius
// of the target sphere)
fRadius + fScoringThickness, // Outer radius
0.0, // Starting Phi angle of the
// segment in radians
2.0 * CLHEP::pi, // Delta Phi angle of the
// segment in radians
0.0, // Starting Theta angle of
// the segment in radians
CLHEP::pi); // Delta Theta angle of the
// segment in radians
fLogicScoringShell = new G4LogicalVolume(solidScoringShell, // solid
vacuum, // material
"logicScoringShell", // name
0, // field manager
0, // sensitive detector
0); // user limits
fPhysiScoringShell = new G4PVPlacement(0, // rotation
G4ThreeVector(), // translation
"physiScoringShell", // name
fLogicScoringShell, // logical volume
fExperimentalHall_phys, // mother physical volume
false, // boolean operation
0); // copy number
G4cout << G4endl
<< "DetectorConstruction::ConstructSphere() : " << G4endl
<< "\t World (box) size: " << G4endl
<< "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl
<< G4endl << G4endl;
G4cout << G4endl << "DetectorConstruction::ConstructSphere() : " << G4endl
<< "\t World (box) size: " << G4endl << "\t \t x : -/+ " << expHall_x << " mm ;"
<< "\t y : -/+ " << expHall_y << " mm ;"
<< "\t z : -/+ " << expHall_z << " mm ;" << G4endl << G4endl << G4endl;
//G4cout << " END DetectorConstruction::ConstructSphere()
// G4cout << " END DetectorConstruction::ConstructSphere()
return fExperimentalHall_phys;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterial( const G4String name ) {
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( name );
if ( fMaterial == nullptr ) {
G4cout << G4endl << G4endl
<< "WARNING: the name of the material has not been recognized!" << G4endl
<< " ===> the default * G4_Fe * will be used."
<< G4endl << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial( "G4_Fe" );
void DetectorConstruction::SetMaterial(const G4String name)
{
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial(name);
if (fMaterial == nullptr) {
G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!"
<< G4endl << " ===> the default * G4_Fe * will be used." << G4endl << G4endl;
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe");
}
if ( fLogicSphere ) fLogicSphere->SetMaterial( fMaterial );
//G4cout << " Absorber Material = " << logicSphere->GetMaterial()->GetName() << G4endl;
if (fLogicSphere) fLogicSphere->SetMaterial(fMaterial);
// G4cout << " Absorber Material = " << logicSphere->GetMaterial()->GetName() << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::UpdateGeometry() {
//G4cout << " BEGIN DetectorConstruction::UpdateGeometry" << G4endl;
void DetectorConstruction::UpdateGeometry()
{
// G4cout << " BEGIN DetectorConstruction::UpdateGeometry" << G4endl;
G4RunManager::GetRunManager()->ReinitializeGeometry();
PrintParameters();
// Update also the position of the gun
const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast< const PrimaryGeneratorAction* >
( G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction() );
if ( pPrimaryAction ) pPrimaryAction->SetGunPosition();
//G4cout << " END DetectorConstruction::UpdateGeometry" << G4endl;
const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast<const PrimaryGeneratorAction*>(
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
if (pPrimaryAction) pPrimaryAction->SetGunPosition();
// G4cout << " END DetectorConstruction::UpdateGeometry" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::PrintParameters() {
G4cout << G4endl << G4endl
<< " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
void DetectorConstruction::PrintParameters()
{
G4cout << G4endl << G4endl << " ------ DetectorConstruction::PrintParameters() ------ " << G4endl
<< " Material = " << fMaterial->GetName() << G4endl
<< " Radius = " << fRadius << " mm" << G4endl
<< " ScoringThickness = " << fScoringThickness << " mm" << G4endl
<< " -------------------------------------------------------- "
<< G4endl << G4endl;
<< " -------------------------------------------------------- " << G4endl << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,42 +32,46 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorMessenger.hh"
#include "DetectorConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIdirectory.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::DetectorMessenger( DetectorConstruction* myDet ) : fDetector( myDet ) {
fDetectorDir = new G4UIdirectory( "/mydet/" );
fDetectorDir->SetGuidance( "Detector control." );
DetectorMessenger::DetectorMessenger(DetectorConstruction* myDet) : fDetector(myDet)
{
fDetectorDir = new G4UIdirectory("/mydet/");
fDetectorDir->SetGuidance("Detector control.");
fMaterial = new G4UIcmdWithAString( "/mydet/material", this );
fMaterial->SetGuidance( "Choice of the material:" );
fMaterial->SetGuidance( " a Geant4 NIST material, e.g. G4_Fe " );
fMaterial->SetParameterName( "choiceMaterial", true );
fMaterial->SetDefaultValue( "G4_Fe" );
fMaterial->AvailableForStates( G4State_PreInit, G4State_Idle );
fRadius = new G4UIcmdWithADoubleAndUnit( "/mydet/radius", this );
fRadius->SetParameterName( "choiceRadius", true );
fRadius->SetGuidance( "Target sphere radius" );
fRadius->SetDefaultValue( 1000.0 ); // default: 1 meter.
fRadius->AvailableForStates( G4State_PreInit, G4State_Idle );
fMaterial = new G4UIcmdWithAString("/mydet/material", this);
fMaterial->SetGuidance("Choice of the material:");
fMaterial->SetGuidance(" a Geant4 NIST material, e.g. G4_Fe ");
fMaterial->SetParameterName("choiceMaterial", true);
fMaterial->SetDefaultValue("G4_Fe");
fMaterial->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter( "/mydet/update", this);
fUpdateCommand->SetGuidance( "Update geometry." );
fUpdateCommand->SetGuidance( "This command MUST be applied before \"beamOn\" " );
fUpdateCommand->SetGuidance( "if you changed geometrical value(s)." );
fUpdateCommand->AvailableForStates( G4State_Idle );
fRadius = new G4UIcmdWithADoubleAndUnit("/mydet/radius", this);
fRadius->SetParameterName("choiceRadius", true);
fRadius->SetGuidance("Target sphere radius");
fRadius->SetDefaultValue(1000.0); // default: 1 meter.
fRadius->AvailableForStates(G4State_PreInit, G4State_Idle);
fUpdateCommand = new G4UIcmdWithoutParameter("/mydet/update", this);
fUpdateCommand->SetGuidance("Update geometry.");
fUpdateCommand->SetGuidance("This command MUST be applied before \"beamOn\" ");
fUpdateCommand->SetGuidance("if you changed geometrical value(s).");
fUpdateCommand->AvailableForStates(G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorMessenger::~DetectorMessenger() {
DetectorMessenger::~DetectorMessenger()
{
delete fDetectorDir;
delete fMaterial;
delete fRadius;
@@ -76,14 +80,15 @@ DetectorMessenger::~DetectorMessenger() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorMessenger::SetNewValue( G4UIcommand* command, G4String newValue ) {
if ( command == fMaterial ) {
fDetector->SetMaterial( newValue );
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fMaterial) {
fDetector->SetMaterial(newValue);
}
if ( command == fRadius ) {
fDetector->SetRadius( fRadius->GetNewDoubleValue( newValue ) );
if (command == fRadius) {
fDetector->SetRadius(fRadius->GetNewDoubleValue(newValue));
}
if ( command == fUpdateCommand ) {
if (command == fUpdateCommand) {
fDetector->UpdateGeometry();
}
}
@@ -32,45 +32,50 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "PrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction() : G4VUserPrimaryGeneratorAction(),
fParticleGun( nullptr ) {
PrimaryGeneratorAction::PrimaryGeneratorAction()
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr)
{
G4int n_particle = 1;
fParticleGun = new G4ParticleGun( n_particle );
fParticleGun = new G4ParticleGun(n_particle);
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition( particleTable->FindParticle( "geantino" ) );
fParticleGun->SetParticleEnergy( 10.0*GeV );
//***LOOKHERE*** Default particle and energy
fParticleGun->SetParticleDefinition(particleTable->FindParticle("geantino"));
fParticleGun->SetParticleEnergy(10.0 * GeV);
SetGunPosition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete fParticleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::SetGunPosition() const {
void PrimaryGeneratorAction::SetGunPosition() const
{
// Shoot the particle from the center of the sphere
fParticleGun->SetParticlePosition( G4ThreeVector( 0.0, 0.0, 0.0 ) );
fParticleGun->SetParticlePosition(G4ThreeVector(0.0, 0.0, 0.0));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries( G4Event* anEvent ) {
G4ThreeVector v( 0.0, 0.0, 1.0 ); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection( v );
fParticleGun->GeneratePrimaryVertex( anEvent );
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
G4ThreeVector v(0.0, 0.0, 1.0); //***LOOKHERE*** default shoot along the z-axis
fParticleGun->SetParticleMomentumDirection(v);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,88 +32,94 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "Run.hh"
#include "G4SystemOfUnits.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() : G4Run(), fNumEvents( 0 ),
fPrimaryParticleId( 0 ), fPrimaryParticleEnergy( 0.0 ),
fPrimaryParticleDirection( G4ThreeVector( 0.0, 0.0, 0.0 ) ),
fTargetMaterialName( "" ), fCubicVolumeScoringShell( 1.0 )
Run::Run()
: G4Run(),
fNumEvents(0),
fPrimaryParticleId(0),
fPrimaryParticleEnergy(0.0),
fPrimaryParticleDirection(G4ThreeVector(0.0, 0.0, 0.0)),
fTargetMaterialName(""),
fCubicVolumeScoringShell(1.0)
{
fSteppingArray.fill( 0.0 );
fTrackingArray1.fill( 0 );
fTrackingArray2.fill( 0.0 );
fSteppingArray.fill(0.0);
fTrackingArray1.fill(0);
fTrackingArray2.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::RecordEvent( const G4Event* anEvent ) {
void Run::RecordEvent(const G4Event* anEvent)
{
// This method is called automatically by the Geant4 kernel (not by the user!) at the end
// of each event : in MT-mode, it is called only for the working thread that handled the event.
G4int nEvt = anEvent->GetEventID();
if ( nEvt % 10 == 0 ) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent( anEvent );
if (nEvt % 10 == 0) G4cout << " Event#=" << nEvt << G4endl;
G4Run::RecordEvent(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge( const G4Run* aRun ) {
void Run::Merge(const G4Run* aRun)
{
// This method is called automatically by the Geant4 kernel (not by the user!) only in the case
// of multithreaded mode and only for working threads.
const Run* localRun = static_cast< const Run* >( aRun );
const Run* localRun = static_cast<const Run*>(aRun);
fPrimaryParticleId = localRun->GetPrimaryParticleId();
fPrimaryParticleEnergy = localRun->GetPrimaryParticleEnergy();
fPrimaryParticleDirection = localRun->GetPrimaryParticleDirection();
fTargetMaterialName = localRun->GetTargetMaterialName();
fCubicVolumeScoringShell = localRun->GetCubicVolumeScoringShell();
fNumEvents += localRun->GetNumberOfEvent();
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] += localRun->GetSteppingArray()[i];
}
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] += localRun->GetTrackingArray1()[i];
fTrackingArray2[i] += localRun->GetTrackingArray2()[i];
}
G4Run::Merge( aRun );
G4Run::Merge(aRun);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::PrintInfo() const {
void Run::PrintInfo() const
{
// This method is called by RunAction::EndOfRunAction. In MT-mode, only the master thread
// calls it.
const G4double floatingNumberOfEvents =
std::max( 1.0, fNumEvents > 0 ? fNumEvents*1.0 : GetNumberOfEvent()*1.0 );
std::max(1.0, fNumEvents > 0 ? fNumEvents * 1.0 : GetNumberOfEvent() * 1.0);
// The fluence in the scoring shell is defined as sum of step lengths in that shell
// divided by the cubic-volume of that scoring shell.
const G4double conversionFactor = CLHEP::cm * CLHEP::cm; // From mm^-2 to cm^-2
const G4double factor =
conversionFactor / ( 0.5*fCubicVolumeScoringShell*floatingNumberOfEvents );
conversionFactor / (0.5 * fCubicVolumeScoringShell * floatingNumberOfEvents);
G4cout << std::setprecision(6) << G4endl << G4endl
<< " =============== Run::PrintInfo() =============== \t RunID = " << GetRunID()
<< G4endl
<< " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV
<< " GeV" << G4endl
<< " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< G4endl << " Primary particle PDG code = " << fPrimaryParticleId << G4endl
<< " Primary particle kinetic energy = " << fPrimaryParticleEnergy / CLHEP::GeV << " GeV"
<< G4endl << " Primary particle direction = " << fPrimaryParticleDirection << G4endl
<< " Target material = " << fTargetMaterialName << G4endl
<< " Cubic-volume scoring shell = " << fCubicVolumeScoringShell << " mm^3" << G4endl
<< " Number of events = " << floatingNumberOfEvents << G4endl
<< " Conversion factor: fluence from mm^-2 to cm^-2 = " << conversionFactor << G4endl
<< " Particle fluence in unit of cm^-2 :" << G4endl;
for ( G4int i = 0; i < SteppingAction::fkNumberKinematicRegions; ++i ) {
for ( G4int j = 0; j < SteppingAction::fkNumberScoringPositions; ++j ) {
for ( G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k ) {
G4int index = SteppingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k )=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << SteppingAction::fkArrayKinematicRegionNames[i]
<< " " << std::setw(12) << SteppingAction::fkArrayScoringPositionNames[j]
<< " " << std::setw(12) << SteppingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << factor*fSteppingArray[index] << G4endl;
for (G4int i = 0; i < SteppingAction::fkNumberKinematicRegions; ++i) {
for (G4int j = 0; j < SteppingAction::fkNumberScoringPositions; ++j) {
for (G4int k = 0; k < SteppingAction::fkNumberParticleTypes; ++k) {
G4int index = SteppingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k )=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< SteppingAction::fkArrayKinematicRegionNames[i] << " " << std::setw(12)
<< SteppingAction::fkArrayScoringPositionNames[j] << " " << std::setw(12)
<< SteppingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< factor * fSteppingArray[index] << G4endl;
}
}
}
@@ -121,21 +127,19 @@ void Run::PrintInfo() const {
<< " Extra information: particle production \t \t <N> <E_kin> <Sum_Ekin> [MeV]"
<< G4endl;
const G4double normalization = 1.0 / floatingNumberOfEvents;
for ( G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i ) {
for ( G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j ) {
for ( G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k ) {
G4int index = TrackingAction::GetIndex( i, j, k );
//G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index
<< " " << std::setw(12) << TrackingAction::fkArrayScoringVolumeNames[i]
<< " " << std::setw(12) << TrackingAction::fkArrayKinematicRegionNames[j]
<< " " << std::setw(12) << TrackingAction::fkArrayParticleTypeNames[k]
<< " " << std::setw( 8) << normalization * fTrackingArray1[index]
<< " " << std::setw( 8) << ( fTrackingArray1[index] > 0 ?
fTrackingArray2[index] / fTrackingArray1[index] :
0.0 )
<< " " << std::setw( 8) << normalization * fTrackingArray2[index]
<< G4endl;
for (G4int i = 0; i < TrackingAction::fkNumberScoringVolumes; ++i) {
for (G4int j = 0; j < TrackingAction::fkNumberKinematicRegions; ++j) {
for (G4int k = 0; k < TrackingAction::fkNumberParticleTypes; ++k) {
G4int index = TrackingAction::GetIndex(i, j, k);
// G4cout << "(i, j, k)=(" << i << ", " << j << ", " << k << ") ->" << index;
G4cout << " case=" << std::setw(3) << index << " " << std::setw(12)
<< TrackingAction::fkArrayScoringVolumeNames[i] << " " << std::setw(12)
<< TrackingAction::fkArrayKinematicRegionNames[j] << " " << std::setw(12)
<< TrackingAction::fkArrayParticleTypeNames[k] << " " << std::setw(8)
<< normalization * fTrackingArray1[index] << " " << std::setw(8)
<< (fTrackingArray1[index] > 0 ? fTrackingArray2[index] / fTrackingArray1[index]
: 0.0)
<< " " << std::setw(8) << normalization * fTrackingArray2[index] << G4endl;
}
}
}
@@ -144,27 +148,30 @@ void Run::PrintInfo() const {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetSteppingArray( const std::array< G4double,
SteppingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i ) {
void Run::SetSteppingArray(
const std::array<G4double, SteppingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < SteppingAction::fkNumberCombinations; ++i) {
fSteppingArray[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray1( const std::array< G4long,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray1(
const std::array<G4long, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray1[i] = inputArray[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::SetTrackingArray2( const std::array< G4double,
TrackingAction::fkNumberCombinations >& inputArray ) {
for ( G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i ) {
void Run::SetTrackingArray2(
const std::array<G4double, TrackingAction::fkNumberCombinations>& inputArray)
{
for (G4int i = 0; i < TrackingAction::fkNumberCombinations; ++i) {
fTrackingArray2[i] = inputArray[i];
}
}
@@ -32,46 +32,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "RunAction.hh"
#include "globals.hh"
#include "G4Run.hh"
#include "Run.hh"
#include "SteppingAction.hh"
#include "TrackingAction.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction( SteppingAction* steppingAction, TrackingAction* trackingAction ) :
G4UserRunAction(), fSteppingAction( steppingAction ), fTrackingAction( trackingAction ) {}
RunAction::RunAction(SteppingAction* steppingAction, TrackingAction* trackingAction)
: G4UserRunAction(), fSteppingAction(steppingAction), fTrackingAction(trackingAction)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun() {
G4Run* RunAction::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction( const G4Run* aRun ) {
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
G4cout << "### Run " << aRun->GetRunID() << " starts." << G4endl;
Run* run = const_cast< Run* >( static_cast< const Run* >( aRun ) );
if ( run == nullptr ) return;
if ( fSteppingAction != nullptr ) {
Run* run = const_cast<Run*>(static_cast<const Run*>(aRun));
if (run == nullptr) return;
if (fSteppingAction != nullptr) {
fSteppingAction->Initialize();
fSteppingAction->SetRunPointer( run );
fSteppingAction->SetRunPointer(run);
}
if ( fTrackingAction != nullptr ) {
if (fTrackingAction != nullptr) {
fTrackingAction->Initialize();
fTrackingAction->SetRunPointer( run );
fTrackingAction->SetRunPointer(run);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction( const G4Run* aRun ) {
const Run* run = static_cast< const Run* >( aRun );
if ( run == nullptr || run->GetNumberOfEvent() == 0 ) return;
if ( IsMaster() ) run->PrintInfo();
void RunAction::EndOfRunAction(const G4Run* aRun)
{
const Run* run = static_cast<const Run*>(aRun);
if (run == nullptr || run->GetNumberOfEvent() == 0) return;
if (IsMaster()) run->PrintInfo();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -32,44 +32,47 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "SteppingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include "G4VSolid.hh"
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, SteppingAction::fkNumberKinematicRegions >
SteppingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
#include "G4IonTable.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VSolid.hh"
#include "G4VTouchable.hh"
const std::array< G4String, SteppingAction::fkNumberScoringPositions >
SteppingAction::fkArrayScoringPositionNames = { "forward", "backward" };
const std::array<G4String, SteppingAction::fkNumberKinematicRegions>
SteppingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array< G4String, SteppingAction::fkNumberParticleTypes >
SteppingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, SteppingAction::fkNumberScoringPositions>
SteppingAction::fkArrayScoringPositionNames = {"forward", "backward"};
const std::array<G4String, SteppingAction::fkNumberParticleTypes>
SteppingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int SteppingAction::GetIndex( const G4int iKinematicRegion, const G4int iScoringPosition,
const G4int iParticleType ) {
G4int SteppingAction::GetIndex(const G4int iKinematicRegion, const G4int iScoringPosition,
const G4int iParticleType)
{
G4int index = -1;
if ( iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iScoringPosition >= 0 && iScoringPosition < fkNumberScoringPositions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iKinematicRegion * fkNumberScoringPositions * fkNumberParticleTypes +
iScoringPosition * fkNumberParticleTypes +
iParticleType;
if (iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions && iScoringPosition >= 0
&& iScoringPosition < fkNumberScoringPositions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iKinematicRegion * fkNumberScoringPositions * fkNumberParticleTypes
+ iScoringPosition * fkNumberParticleTypes + iParticleType;
}
if ( index < 0 || index >= fkNumberCombinations ) {
if (index < 0 || index >= fkNumberCombinations) {
G4cerr << "SteppingAction::GetIndex : WRONG index=" << index << " set it to 0 !" << G4endl;
index = 0;
}
@@ -78,23 +81,25 @@ G4int SteppingAction::GetIndex( const G4int iKinematicRegion, const G4int iScori
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SteppingAction::SteppingAction() :G4UserSteppingAction() {
SteppingAction::SteppingAction() : G4UserSteppingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::Initialize() {
// Initialization needed at the beginning of each Run
void SteppingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fPrimaryParticleId = 0;
fPrimaryParticleEnergy = 0.0;
fPrimaryParticleDirection = G4ThreeVector( 0.0, 0.0, 1.0 );
fPrimaryParticleDirection = G4ThreeVector(0.0, 0.0, 1.0);
fTargetMaterialName = "";
fIsFirstStepOfTheEvent = true;
fIsFirstStepInTarget = true;
fIsFirstStepInScoringShell = true;
fIsFirstStepInScoringShell = true;
fCubicVolumeScoringShell = 1.0;
for ( G4int i = 0; i < fkNumberCombinations; ++i ) {
for (G4int i = 0; i < fkNumberCombinations; ++i) {
fArraySumStepLengths[i] = 0.0;
}
/*
@@ -119,47 +124,50 @@ void SteppingAction::Initialize() {
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
void SteppingAction::UserSteppingAction(const G4Step* theStep)
{
// Get information on the primary particle
if ( fIsFirstStepOfTheEvent ) {
if ( theStep->GetTrack()->GetParentID() == 0 ) {
if (fIsFirstStepOfTheEvent) {
if (theStep->GetTrack()->GetParentID() == 0) {
fPrimaryParticleId = theStep->GetTrack()->GetDefinition()->GetPDGEncoding();
fPrimaryParticleEnergy = theStep->GetPreStepPoint()->GetKineticEnergy();
fPrimaryParticleDirection = theStep->GetPreStepPoint()->GetMomentumDirection();
if ( fRunPtr ) {
fRunPtr->SetPrimaryParticleId( fPrimaryParticleId );
fRunPtr->SetPrimaryParticleEnergy( fPrimaryParticleEnergy );
fRunPtr->SetPrimaryParticleDirection( fPrimaryParticleDirection );
if (fRunPtr) {
fRunPtr->SetPrimaryParticleId(fPrimaryParticleId);
fRunPtr->SetPrimaryParticleEnergy(fPrimaryParticleEnergy);
fRunPtr->SetPrimaryParticleDirection(fPrimaryParticleDirection);
}
fIsFirstStepOfTheEvent = false;
}
}
// Get information on the target material
if ( fIsFirstStepInTarget &&
theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiSphere" ) {
if (fIsFirstStepInTarget
&& theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiSphere")
{
fTargetMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
if ( fRunPtr ) fRunPtr->SetTargetMaterialName( fTargetMaterialName );
if (fRunPtr) fRunPtr->SetTargetMaterialName(fTargetMaterialName);
fIsFirstStepInTarget = false;
}
// Get information on step lengths in the scoring shell
if ( theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringShell" ) {
if ( fIsFirstStepInScoringShell ) {
if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringShell") {
if (fIsFirstStepInScoringShell) {
fCubicVolumeScoringShell =
theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
if ( fRunPtr ) fRunPtr->SetCubicVolumeScoringShell( fCubicVolumeScoringShell );
if (fRunPtr) fRunPtr->SetCubicVolumeScoringShell(fCubicVolumeScoringShell);
fIsFirstStepInScoringShell = false;
}
G4double stepLength = theStep->GetTrack()->GetStepLength() * theStep->GetTrack()->GetWeight();
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr ? 0 :
std::abs( theStep->GetTrack()->GetDefinition()->GetPDGEncoding() );
/*
G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr
? 0
: std::abs(theStep->GetTrack()->GetDefinition()->GetPDGEncoding());
/*
G4cout << theStep->GetTrack()->GetDefinition()->GetParticleName() << " absPdg=" << absPdg
<< " Ekin[MeV]=" << theStep->GetPreStepPoint()->GetKineticEnergy()
<< " r[mm]=" << theStep->GetTrack()->GetPosition().mag()
<< " z[mm]=" << theStep->GetTrack()->GetPosition().z()
<< " " << theStep->GetTrack()->GetVolume()->GetName()
<< " " << theStep->GetTrack()->GetMaterial()->GetName()
<< " L[mm]=" << stepLength << " "
<< " L[mm]=" << stepLength << " "
<< ( fPrimaryParticleDirection.dot( theStep->GetTrack()->GetPosition().unit() ) > 0.0
? "forward" : "backward" ) << G4endl;
*/
@@ -168,35 +176,45 @@ void SteppingAction::UserSteppingAction( const G4Step* theStep ) {
// Two scoring positions: [0] : forward hemisphere ; [1] : backward hemisphere
// (with respect to the primary particle initial direction)
G4int iScoringPosition =
fPrimaryParticleDirection.dot( theStep->GetTrack()->GetPosition().unit() ) > 0.0 ? 0 : 1;
fPrimaryParticleDirection.dot(theStep->GetTrack()->GetPosition().unit()) > 0.0 ? 0 : 1;
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4; // neutrinos (and
// anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( theStep->GetTrack()->GetDefinition() ) || // ions (and anti-ions)
G4IonTable::IsAntiIon( theStep->GetTrack()->GetDefinition() ) ) iParticleType = 8;
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4; // neutrinos (and
// anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(theStep->GetTrack()->GetDefinition()) || // ions (and anti-ions)
G4IonTable::IsAntiIon(theStep->GetTrack()->GetDefinition()))
iParticleType = 8;
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons) (Note: this works
// in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons, anti-hyperons,
// etc.)
// Consider the specific case : kinematic region, scoring position, and particle type
G4int index = GetIndex( iKinematicRegion, iScoringPosition, iParticleType );
G4int index = GetIndex(iKinematicRegion, iScoringPosition, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "all" particle case, with the same kinematic region and scoring position
index = GetIndex( iKinematicRegion, iScoringPosition, 0 );
index = GetIndex(iKinematicRegion, iScoringPosition, 0);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region case, with the same scoring position and particle type
index = GetIndex( 0, iScoringPosition, iParticleType );
index = GetIndex(0, iScoringPosition, iParticleType);
fArraySumStepLengths[index] += stepLength;
// Consider the "any" kinematic region and "all" particle, with the same scoring position
index = GetIndex( 0, iScoringPosition, 0 );
index = GetIndex(0, iScoringPosition, 0);
fArraySumStepLengths[index] += stepLength;
if ( fRunPtr ) fRunPtr->SetSteppingArray( fArraySumStepLengths );
if (fRunPtr) fRunPtr->SetSteppingArray(fArraySumStepLengths);
}
}
@@ -32,112 +32,127 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "TrackingAction.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4IonTable.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "Run.hh"
const std::array< G4String, TrackingAction::fkNumberScoringVolumes >
TrackingAction::fkArrayScoringVolumeNames = { "sphere" };
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4Track.hh"
const std::array< G4String, TrackingAction::fkNumberKinematicRegions >
TrackingAction::fkArrayKinematicRegionNames = { "", "below 20 MeV", "above 20 MeV" };
const std::array<G4String, TrackingAction::fkNumberScoringVolumes>
TrackingAction::fkArrayScoringVolumeNames = {"sphere"};
const std::array< G4String, TrackingAction::fkNumberParticleTypes >
TrackingAction::fkArrayParticleTypeNames = { "all", "electron", "gamma", "muon", "neutrino",
"pion", "neutron", "proton", "ion", "otherMeson",
"otherBaryon" };
const std::array<G4String, TrackingAction::fkNumberKinematicRegions>
TrackingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
const std::array<G4String, TrackingAction::fkNumberParticleTypes>
TrackingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
"neutrino", "pion", "neutron", "proton",
"ion", "otherMeson", "otherBaryon"};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int TrackingAction::GetIndex( const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType ) {
G4int TrackingAction::GetIndex(const G4int iScoringVolume, const G4int iKinematicRegion,
const G4int iParticleType)
{
G4int index = -1;
if ( iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes &&
iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions &&
iParticleType >= 0 && iParticleType < fkNumberParticleTypes ) {
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes +
iKinematicRegion * fkNumberParticleTypes +
iParticleType;
if (iScoringVolume >= 0 && iScoringVolume < fkNumberScoringVolumes && iKinematicRegion >= 0
&& iKinematicRegion < fkNumberKinematicRegions && iParticleType >= 0
&& iParticleType < fkNumberParticleTypes)
{
index = iScoringVolume * fkNumberKinematicRegions * fkNumberParticleTypes
+ iKinematicRegion * fkNumberParticleTypes + iParticleType;
}
return index;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TrackingAction::TrackingAction() : G4UserTrackingAction() {
TrackingAction::TrackingAction() : G4UserTrackingAction()
{
Initialize();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::Initialize() {
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill( 0 );
fArraySumKineticEnergies.fill( 0.0 );
void TrackingAction::Initialize()
{
// Initialization needed at the beginning of each Run
fArrayMultiplicities.fill(0);
fArraySumKineticEnergies.fill(0.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PreUserTrackingAction( const G4Track* aTrack ) {
// This method is called not only once when a particle is created,
void TrackingAction::PreUserTrackingAction(const G4Track* aTrack)
{
// This method is called not only once when a particle is created,
// but also each time it is resumed, in the case the track gets suspended,
// as it happens in the case of neutrons with _HP Physics Lists.
// To be sure that we collect information about a track one and only once,
// we require that the current step be the first one.
if ( aTrack == nullptr ||
aTrack->GetCurrentStepNumber() != 0 ||
aTrack->GetDefinition() == nullptr ||
aTrack->GetLogicalVolumeAtVertex() == nullptr ||
aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicSphere" ) return;
if (aTrack == nullptr || aTrack->GetCurrentStepNumber() != 0 || aTrack->GetDefinition() == nullptr
|| aTrack->GetLogicalVolumeAtVertex() == nullptr
|| aTrack->GetLogicalVolumeAtVertex()->GetName() != "logicSphere")
return;
G4int iScoringVolume = 0;
// Three kinematical regions: [0] : any value ; [1] : below 20 MeV ; [2] : above 20 MeV
G4int iKinematicRegion = aTrack->GetKineticEnergy() < 20.0 ? 1 : 2;
G4int absPdg = std::abs( aTrack->GetDefinition()->GetPDGEncoding() );
G4int absPdg = std::abs(aTrack->GetDefinition()->GetPDGEncoding());
G4int iParticleType = -1;
if ( absPdg == 11 ) iParticleType = 1; // electron (and positron)
else if ( absPdg == 22 ) iParticleType = 2; // gamma
else if ( absPdg == 13 ) iParticleType = 3; // muons (mu- and mu+)
else if ( absPdg == 12 || absPdg == 14 || absPdg == 16 ) iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if ( absPdg == 111 || absPdg == 211 ) iParticleType = 5; // (charged) pions
else if ( absPdg == 2112 ) iParticleType = 6; // neutron (and anti-neutron)
else if ( absPdg == 2212 ) iParticleType = 7; // proton (and anti-proton)
else if ( G4IonTable::IsIon( aTrack->GetDefinition() ) ||
G4IonTable::IsAntiIon( aTrack->GetDefinition() ) ) iParticleType = 8;
// ions (and anti-ions)
else if ( absPdg < 1000 ) iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if ( absPdg > 1000 ) iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
if (absPdg == 11)
iParticleType = 1; // electron (and positron)
else if (absPdg == 22)
iParticleType = 2; // gamma
else if (absPdg == 13)
iParticleType = 3; // muons (mu- and mu+)
else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
iParticleType = 4;
// neutrinos (and anti-neutrinos), all flavors
else if (absPdg == 111 || absPdg == 211)
iParticleType = 5; // (charged) pions
else if (absPdg == 2112)
iParticleType = 6; // neutron (and anti-neutron)
else if (absPdg == 2212)
iParticleType = 7; // proton (and anti-proton)
else if (G4IonTable::IsIon(aTrack->GetDefinition())
|| G4IonTable::IsAntiIon(aTrack->GetDefinition()))
iParticleType = 8;
// ions (and anti-ions)
else if (absPdg < 1000)
iParticleType = 9; // other mesons (e.g. kaons)
// (Note: this works in most cases, but not always!)
else if (absPdg > 1000)
iParticleType = 10; // other baryons (e.g. hyperons,
// anti-hyperons, etc.)
// Consider the specific case : scoring volume, kinematic region and particle type
G4int index = GetIndex( iScoringVolume, iKinematicRegion, iParticleType );
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex( iScoringVolume, iKinematicRegion, 0 );
G4int index = GetIndex(iScoringVolume, iKinematicRegion, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex( iScoringVolume, 0, iParticleType );
// Consider the "all" particle case, with the same scoring volume and kinematic region
index = GetIndex(iScoringVolume, iKinematicRegion, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region case, with the same scoring volume and particle type
index = GetIndex(iScoringVolume, 0, iParticleType);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
// Consider the "any" kinematic region and "all" particle, with the same scoring volume
index = GetIndex( iScoringVolume, 0, 0 );
index = GetIndex(iScoringVolume, 0, 0);
++fArrayMultiplicities[index];
fArraySumKineticEnergies[index] += aTrack->GetKineticEnergy();
if ( fRunPtr ) {
fRunPtr->SetTrackingArray1( fArrayMultiplicities );
fRunPtr->SetTrackingArray2( fArraySumKineticEnergies );
if (fRunPtr) {
fRunPtr->SetTrackingArray1(fArrayMultiplicities);
fRunPtr->SetTrackingArray2(fArraySumKineticEnergies);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void TrackingAction::PostUserTrackingAction( const G4Track* /* aTrack */ ) {}
void TrackingAction::PostUserTrackingAction(const G4Track* /* aTrack */) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......