Warning, file /geant4/examples/basic/B3/B3b/src/DetectorConstruction.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 #include "DetectorConstruction.hh"
0031
0032 #include "G4Box.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4MultiFunctionalDetector.hh"
0035 #include "G4NistManager.hh"
0036 #include "G4PSDoseDeposit.hh"
0037 #include "G4PSEnergyDeposit.hh"
0038 #include "G4PVPlacement.hh"
0039 #include "G4PhysicalConstants.hh"
0040 #include "G4RotationMatrix.hh"
0041 #include "G4SDManager.hh"
0042 #include "G4SystemOfUnits.hh"
0043 #include "G4Transform3D.hh"
0044 #include "G4Tubs.hh"
0045 #include "G4VisAttributes.hh"
0046
0047 namespace B3
0048 {
0049
0050
0051
0052 DetectorConstruction::DetectorConstruction()
0053 {
0054 DefineMaterials();
0055 }
0056
0057
0058
0059 void DetectorConstruction::DefineMaterials()
0060 {
0061 G4NistManager* man = G4NistManager::Instance();
0062
0063 G4bool isotopes = false;
0064
0065 G4Element* O = man->FindOrBuildElement("O", isotopes);
0066 G4Element* Si = man->FindOrBuildElement("Si", isotopes);
0067 G4Element* Lu = man->FindOrBuildElement("Lu", isotopes);
0068
0069 auto LSO = new G4Material("Lu2SiO5", 7.4 * g / cm3, 3);
0070 LSO->AddElement(Lu, 2);
0071 LSO->AddElement(Si, 1);
0072 LSO->AddElement(O, 5);
0073 }
0074
0075
0076
0077 G4VPhysicalVolume* DetectorConstruction::Construct()
0078 {
0079
0080
0081 G4double cryst_dX = 6 * cm, cryst_dY = 6 * cm, cryst_dZ = 3 * cm;
0082 G4int nb_cryst = 32;
0083 G4int nb_rings = 9;
0084
0085 G4double dPhi = twopi / nb_cryst, half_dPhi = 0.5 * dPhi;
0086 G4double cosdPhi = std::cos(half_dPhi);
0087 G4double tandPhi = std::tan(half_dPhi);
0088
0089 G4double ring_R1 = 0.5 * cryst_dY / tandPhi;
0090 G4double ring_R2 = (ring_R1 + cryst_dZ) / cosdPhi;
0091
0092 G4double detector_dZ = nb_rings * cryst_dX;
0093
0094 G4NistManager* nist = G4NistManager::Instance();
0095 G4Material* default_mat = nist->FindOrBuildMaterial("G4_AIR");
0096 G4Material* cryst_mat = nist->FindOrBuildMaterial("Lu2SiO5");
0097
0098
0099
0100
0101 G4double world_sizeXY = 2.4 * ring_R2;
0102 G4double world_sizeZ = 1.2 * detector_dZ;
0103
0104 auto solidWorld =
0105 new G4Box("World",
0106 0.5 * world_sizeXY, 0.5 * world_sizeXY, 0.5 * world_sizeZ);
0107
0108 auto logicWorld = new G4LogicalVolume(solidWorld,
0109 default_mat,
0110 "World");
0111
0112 auto physWorld = new G4PVPlacement(nullptr,
0113 G4ThreeVector(),
0114 logicWorld,
0115 "World",
0116 nullptr,
0117 false,
0118 0,
0119 fCheckOverlaps);
0120
0121
0122
0123
0124 auto solidRing = new G4Tubs("Ring", ring_R1, ring_R2, 0.5 * cryst_dX, 0., twopi);
0125
0126 auto logicRing = new G4LogicalVolume(solidRing,
0127 default_mat,
0128 "Ring");
0129
0130
0131
0132
0133 G4double gap = 0.5 * mm;
0134 G4double dX = cryst_dX - gap, dY = cryst_dY - gap;
0135 auto solidCryst = new G4Box("crystal", dX / 2, dY / 2, cryst_dZ / 2);
0136
0137 auto logicCryst = new G4LogicalVolume(solidCryst,
0138 cryst_mat,
0139 "CrystalLV");
0140
0141
0142
0143 for (G4int icrys = 0; icrys < nb_cryst; icrys++) {
0144 G4double phi = icrys * dPhi;
0145 G4RotationMatrix rotm = G4RotationMatrix();
0146 rotm.rotateY(90 * deg);
0147 rotm.rotateZ(phi);
0148 G4ThreeVector uz = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
0149 G4ThreeVector position = (ring_R1 + 0.5 * cryst_dZ) * uz;
0150 G4Transform3D transform = G4Transform3D(rotm, position);
0151
0152 new G4PVPlacement(transform,
0153 logicCryst,
0154 "crystal",
0155 logicRing,
0156 false,
0157 icrys,
0158 fCheckOverlaps);
0159 }
0160
0161
0162
0163
0164 auto solidDetector = new G4Tubs("Detector", ring_R1, ring_R2, 0.5 * detector_dZ, 0., twopi);
0165
0166 auto logicDetector = new G4LogicalVolume(solidDetector,
0167 default_mat,
0168 "Detector");
0169
0170
0171
0172
0173 G4double OG = -0.5 * (detector_dZ + cryst_dX);
0174 for (G4int iring = 0; iring < nb_rings; iring++) {
0175 OG += cryst_dX;
0176 new G4PVPlacement(nullptr,
0177 G4ThreeVector(0, 0, OG),
0178 logicRing,
0179 "ring",
0180 logicDetector,
0181 false,
0182 iring,
0183 fCheckOverlaps);
0184 }
0185
0186
0187
0188
0189 new G4PVPlacement(nullptr,
0190 G4ThreeVector(),
0191 logicDetector,
0192 "Detector",
0193 logicWorld,
0194 false,
0195 0,
0196 fCheckOverlaps);
0197
0198
0199
0200
0201 G4double patient_radius = 8 * cm;
0202 G4double patient_dZ = 10 * cm;
0203 G4Material* patient_mat = nist->FindOrBuildMaterial("G4_BRAIN_ICRP");
0204
0205 auto solidPatient = new G4Tubs("Patient", 0., patient_radius, 0.5 * patient_dZ, 0., twopi);
0206
0207 auto logicPatient = new G4LogicalVolume(solidPatient,
0208 patient_mat,
0209 "PatientLV");
0210
0211
0212
0213
0214 new G4PVPlacement(nullptr,
0215 G4ThreeVector(),
0216 logicPatient,
0217 "Patient",
0218 logicWorld,
0219 false,
0220 0,
0221 fCheckOverlaps);
0222
0223
0224
0225 logicRing->SetVisAttributes(G4VisAttributes::GetInvisible());
0226 logicDetector->SetVisAttributes(G4VisAttributes::GetInvisible());
0227
0228
0229 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0230
0231
0232
0233 return physWorld;
0234 }
0235
0236
0237
0238 void DetectorConstruction::ConstructSDandField()
0239 {
0240 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
0241
0242
0243
0244 auto cryst = new G4MultiFunctionalDetector("crystal");
0245 G4SDManager::GetSDMpointer()->AddNewDetector(cryst);
0246 G4VPrimitiveScorer* primitiv1 = new G4PSEnergyDeposit("edep");
0247 cryst->RegisterPrimitive(primitiv1);
0248 SetSensitiveDetector("CrystalLV", cryst);
0249
0250
0251
0252 auto patient = new G4MultiFunctionalDetector("patient");
0253 G4SDManager::GetSDMpointer()->AddNewDetector(patient);
0254 G4VPrimitiveScorer* primitiv2 = new G4PSDoseDeposit("dose");
0255 patient->RegisterPrimitive(primitiv2);
0256 SetSensitiveDetector("PatientLV", patient);
0257 }
0258
0259
0260
0261 }