File indexing completed on 2026-04-08 07:52:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "DetectorConstruction.hh"
0030
0031 #include "DetectorMessenger.hh"
0032
0033 #include "G4AutoDelete.hh"
0034 #include "G4Box.hh"
0035 #include "G4GeometryManager.hh"
0036 #include "G4GlobalMagFieldMessenger.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4LogicalVolumeStore.hh"
0039 #include "G4Material.hh"
0040 #include "G4NistManager.hh"
0041 #include "G4PVPlacement.hh"
0042 #include "G4PVReplica.hh"
0043 #include "G4PhysicalConstants.hh"
0044 #include "G4PhysicalVolumeStore.hh"
0045 #include "G4RunManager.hh"
0046 #include "G4SolidStore.hh"
0047 #include "G4SystemOfUnits.hh"
0048 #include "G4UImanager.hh"
0049 #include "G4UniformMagField.hh"
0050 #include "G4UnitsTable.hh"
0051
0052 #include <iomanip>
0053
0054
0055
0056 DetectorConstruction::DetectorConstruction()
0057 {
0058
0059 fNbOfAbsor = 1;
0060 fAbsorThickness[0] = 0. * mm;
0061 fAbsorThickness[1] = 1. * mm;
0062 fAbsorSizeYZ = 1. * mm;
0063 for (G4int iAbs = 0; iAbs < kMaxAbsor; iAbs++) {
0064 fNbOfDivisions[iAbs] = 1;
0065 }
0066 ComputeParameters();
0067
0068
0069 DefineMaterials();
0070 SetAbsorMaterial(1, "G4_Si");
0071
0072
0073 fDetectorMessenger = new DetectorMessenger(this);
0074 }
0075
0076
0077
0078 DetectorConstruction::~DetectorConstruction()
0079 {
0080 delete fDetectorMessenger;
0081 }
0082
0083
0084
0085 G4VPhysicalVolume* DetectorConstruction::Construct()
0086 {
0087 return ConstructVolumes();
0088 }
0089
0090
0091
0092 void DetectorConstruction::DefineMaterials()
0093 {
0094 G4NistManager* man = G4NistManager::Instance();
0095
0096 man->FindOrBuildMaterial("G4_Al");
0097 man->FindOrBuildMaterial("G4_Si");
0098 man->FindOrBuildMaterial("G4_Fe");
0099 man->FindOrBuildMaterial("G4_Cu");
0100 man->FindOrBuildMaterial("G4_Ge");
0101 man->FindOrBuildMaterial("G4_Mo");
0102 man->FindOrBuildMaterial("G4_Ta");
0103 man->FindOrBuildMaterial("G4_W");
0104 man->FindOrBuildMaterial("G4_Au");
0105 man->FindOrBuildMaterial("G4_Pb");
0106 man->FindOrBuildMaterial("G4_PbWO4");
0107 man->FindOrBuildMaterial("G4_SODIUM_IODIDE");
0108
0109 man->FindOrBuildMaterial("G4_AIR");
0110 man->FindOrBuildMaterial("G4_WATER");
0111
0112 G4Element* H = man->FindOrBuildElement("H");
0113 G4Element* O = man->FindOrBuildElement("O");
0114
0115 G4Material* H2O = new G4Material("Water", 1.000 * g / cm3, 2);
0116 H2O->AddElement(H, 2);
0117 H2O->AddElement(O, 1);
0118 H2O->GetIonisation()->SetMeanExcitationEnergy(78.0 * eV);
0119
0120 G4double density = universe_mean_density;
0121 G4double pressure = 3.e-18 * pascal;
0122 G4double temperature = 2.73 * kelvin;
0123 G4Material* Galactic =
0124 new G4Material("Galactic", 1., 1.008 * g / mole, density, kStateGas, temperature, pressure);
0125
0126 fDefaultMaterial = Galactic;
0127
0128
0129 }
0130
0131
0132
0133 void DetectorConstruction::ComputeParameters()
0134 {
0135
0136 fAbsorSizeX = 0.;
0137 for (G4int iAbs = 1; iAbs <= fNbOfAbsor; iAbs++) {
0138 fAbsorSizeX += fAbsorThickness[iAbs];
0139 }
0140 }
0141
0142
0143
0144 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
0145 {
0146
0147 ComputeParameters();
0148
0149
0150 G4GeometryManager::GetInstance()->OpenGeometry();
0151 G4PhysicalVolumeStore::GetInstance()->Clean();
0152 G4LogicalVolumeStore::GetInstance()->Clean();
0153 G4SolidStore::GetInstance()->Clean();
0154
0155
0156
0157
0158 G4Box* solidWorld = new G4Box("World",
0159 fAbsorSizeX / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);
0160
0161 G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld,
0162 fDefaultMaterial,
0163 "World");
0164
0165 fPhysiWorld = new G4PVPlacement(0,
0166 G4ThreeVector(),
0167 logicWorld,
0168 "World",
0169 0,
0170 false,
0171 0);
0172
0173
0174
0175
0176 fXfront[0] = -0.5 * fAbsorSizeX;
0177
0178 for (G4int k = 1; k <= fNbOfAbsor; k++) {
0179 G4Material* material = fAbsorMaterial[k];
0180 G4String matname = material->GetName();
0181
0182 G4Box* solidAbsor =
0183 new G4Box(matname, fAbsorThickness[k] / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);
0184
0185 G4LogicalVolume* logicAbsor = new G4LogicalVolume(solidAbsor,
0186 material,
0187 matname);
0188
0189 fXfront[k] = fXfront[k - 1] + fAbsorThickness[k - 1];
0190 G4double xcenter = fXfront[k] + 0.5 * fAbsorThickness[k];
0191 G4ThreeVector position = G4ThreeVector(xcenter, 0., 0.);
0192
0193 new G4PVPlacement(0,
0194 position,
0195 logicAbsor,
0196 matname,
0197 logicWorld,
0198 false,
0199 k);
0200
0201
0202
0203 G4double LayerThickness = fAbsorThickness[k] / fNbOfDivisions[k];
0204 G4Box* solidLayer = new G4Box(matname, LayerThickness / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);
0205
0206 G4LogicalVolume* logicLayer = new G4LogicalVolume(solidLayer,
0207 material,
0208 matname);
0209
0210 new G4PVReplica(matname,
0211 logicLayer,
0212 logicAbsor,
0213 kXAxis,
0214 fNbOfDivisions[k],
0215 LayerThickness);
0216 }
0217
0218 PrintParameters();
0219
0220
0221
0222 return fPhysiWorld;
0223 }
0224
0225
0226
0227 void DetectorConstruction::PrintParameters()
0228 {
0229 G4cout << "\n-------------------------------------------------------------"
0230 << "\n ---> The Absorber is " << fNbOfAbsor << " layers of:";
0231 for (G4int i = 1; i <= fNbOfAbsor; i++) {
0232 G4cout << "\n \t" << std::setw(16) << fAbsorMaterial[i]->GetName() << ": " << std::setw(6)
0233 << G4BestUnit(fAbsorThickness[i], "Length") << " divided in " << fNbOfDivisions[i]
0234 << " slices";
0235 }
0236 G4cout << "\n-------------------------------------------------------------\n" << G4endl;
0237 }
0238
0239
0240
0241 void DetectorConstruction::SetNbOfAbsor(G4int ival)
0242 {
0243
0244
0245 if (ival < 1 || ival > (kMaxAbsor - 1)) {
0246 G4cout << "\n ---> warning from SetfNbOfAbsor: " << ival << " must be at least 1 and and most "
0247 << kMaxAbsor - 1 << ". Command refused" << G4endl;
0248 return;
0249 }
0250 fNbOfAbsor = ival;
0251 G4RunManager::GetRunManager()->ReinitializeGeometry();
0252 }
0253
0254
0255
0256 void DetectorConstruction::SetAbsorMaterial(G4int iabs, const G4String& material)
0257 {
0258
0259
0260 if (iabs > fNbOfAbsor || iabs <= 0) {
0261 G4cout << "\n --->warning from SetfAbsorMaterial: absor number " << iabs
0262 << " out of range. Command refused" << G4endl;
0263 return;
0264 }
0265
0266 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(material);
0267 if (pttoMaterial) {
0268 fAbsorMaterial[iabs] = pttoMaterial;
0269 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0270 G4cout << "\n " << pttoMaterial << G4endl;
0271 }
0272 }
0273
0274
0275
0276 void DetectorConstruction::SetAbsorThickness(G4int iabs, G4double val)
0277 {
0278
0279
0280 if (iabs > fNbOfAbsor || iabs <= 0) {
0281 G4cout << "\n --->warning from SetfAbsorThickness: absor number " << iabs
0282 << " out of range. Command refused" << G4endl;
0283 return;
0284 }
0285 if (val <= DBL_MIN) {
0286 G4cout << "\n --->warning from SetfAbsorThickness: thickness " << val
0287 << " out of range. Command refused" << G4endl;
0288 return;
0289 }
0290 fAbsorThickness[iabs] = val;
0291 G4RunManager::GetRunManager()->ReinitializeGeometry();
0292 }
0293
0294
0295
0296 void DetectorConstruction::SetAbsorSizeYZ(G4double val)
0297 {
0298
0299
0300 if (val <= DBL_MIN) {
0301 G4cout << "\n --->warning from SetfAbsorSizeYZ: thickness " << val
0302 << " out of range. Command refused" << G4endl;
0303 return;
0304 }
0305 fAbsorSizeYZ = val;
0306 G4RunManager::GetRunManager()->ReinitializeGeometry();
0307 }
0308
0309
0310
0311 void DetectorConstruction::SetNbOfDivisions(G4int iabs, G4int ival)
0312 {
0313
0314
0315 if (iabs > fNbOfAbsor || iabs < 1) {
0316 G4cout << "\n --->warning from SetNbOfDivisions: absor number " << iabs
0317 << " out of range. Command refused" << G4endl;
0318 return;
0319 }
0320
0321 if (ival < 1) {
0322 G4cout << "\n --->warning from SetNbOfDivisions: " << ival
0323 << " must be at least 1. Command refused" << G4endl;
0324 return;
0325 }
0326 fNbOfDivisions[iabs] = ival;
0327 G4RunManager::GetRunManager()->ReinitializeGeometry();
0328 }
0329
0330
0331
0332 void DetectorConstruction::ConstructSDandField()
0333 {
0334 if (fFieldMessenger.Get() == 0) {
0335
0336
0337
0338 G4ThreeVector fieldValue = G4ThreeVector();
0339 G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue);
0340
0341 G4AutoDelete::Register(msg);
0342 fFieldMessenger.Put(msg);
0343 }
0344 }
0345
0346