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