Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // 27 /// \file DetectorConstruction.cc 28 /// \brief DetectorConstruction class 29 // 30 // 31 #include "DetectorConstruction.hh" 32 33 #include "G4Box.hh" 34 #include "G4GeometryManager.hh" 35 #include "G4LogicalVolume.hh" 36 #include "G4Material.hh" 37 #include "G4NistManager.hh" 38 #include "G4PVPlacement.hh" 39 #include "G4ProductionCuts.hh" 40 #include "G4RunManager.hh" 41 #include "G4SystemOfUnits.hh" 42 #include "G4ThreeVector.hh" 43 #include "G4Tubs.hh" 44 #include "G4UnitsTable.hh" 45 #include "G4VPhysicalVolume.hh" 46 #include "G4VisAttributes.hh" 47 48 const bool check_intersections = true; // to control geometry for errors 49 50 // new unit 51 const G4double ug = 1.e-6 * g; 52 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 54 55 G4VPhysicalVolume* DetectorConstruction::Construct() 56 { 57 auto man = G4NistManager::Instance(); 58 59 // registering new useful unit 60 new G4UnitDefinition("microgram", "ug", "Mass", ug); 61 62 // geometric parameters 63 G4double worldSize = 8 * cm; 64 G4double worldDensity = 0.15 * mg / m3; // imperfect vacuum as in a real-world experiment 65 66 G4double IV_diameter = 10 * mm; 67 G4double IV_height = 20 * mm; 68 G4double IV_vertical_offset = -5 * mm; // instead of moving beam axis, the IV is moved 69 G4double IV_density = 0.45 * ug / cm3; 70 71 G4double wall_tot_mass_thickness = 0.98 * mg / cm2; // Mylar wall thickness -> 7 µm 72 G4double wall_inner_layer_mass_thickness = 73 0.02 * mg / cm2; // inner layer of wall made of water material at Mylar density 74 75 fCollDiameter = 3 * mm; // inner diameter of the collimator, the outer is twice that 76 fCollLength = 23 * mm; 77 fCollExitPosition = -5.5 * mm; // exit of the collimator, where the beam is already formed 78 79 G4double enDet_diameter = 10 * mm; 80 G4double enDet_thickness = 150 * um; 81 G4double enDet_distance = 10 * mm; 82 83 // materials 84 auto worldMaterial = 85 man->BuildMaterialWithNewDensity("WORLD_WATER_VACUUM", "G4_WATER", worldDensity); 86 auto targetMaterial = man->BuildMaterialWithNewDensity("TARGET_WATER", "G4_WATER", IV_density); 87 auto wallMaterial = man->FindOrBuildMaterial("G4_MYLAR"); 88 auto collMaterial = man->FindOrBuildMaterial("G4_BRASS"); 89 auto enDetMaterial = man->FindOrBuildMaterial("G4_Si"); 90 91 // auxiliary variables: 92 G4ThreeVector origin(0, 0, 0); 93 G4ThreeVector IV_centre(0, 0, IV_vertical_offset); 94 G4ThreeVector enDet_centre(enDet_distance + IV_diameter / 2., 0, 0); 95 96 G4double mylarDensity = wallMaterial->GetDensity(); 97 G4double wall_total_thickness = wall_tot_mass_thickness / mylarDensity; 98 G4double wall_inner_layer_thickness = wall_inner_layer_mass_thickness / mylarDensity; 99 100 // materials continued 101 auto innerWallMaterial = man->BuildMaterialWithNewDensity("WALL_WATER", "G4_WATER", mylarDensity); 102 103 // SAVING DETECTOR SETTINGS TO FILE: 104 auto filename = "SIM_GEOMETRY_SETTINGS.txt"; 105 std::ofstream TextFile; 106 TextFile.open(filename, std::fstream::out); 107 TextFile << "worldSize = " << worldSize / cm << " cm\n"; 108 TextFile << "worldDensity = " << worldDensity / (mg / m3) << " mg/m3\n"; 109 TextFile << "IV_diameter = " << IV_diameter / mm << " mm\n"; 110 TextFile << "IV_height = " << IV_height / mm << " mm\n"; 111 TextFile << "IV_vertical_offset = " << IV_vertical_offset / mm << " mm\n"; 112 TextFile << "IV_density = " << IV_density / (ug / cm3) << " ug/cm3\n"; 113 TextFile << "wall_tot_mass_thickness = " << wall_tot_mass_thickness / (mg / cm2) << " mg/cm2\n"; 114 TextFile << "wall_inner_layer_mass_thickness = " << wall_inner_layer_mass_thickness / (mg / cm2) 115 << " mg/cm2\n"; 116 TextFile << "fCollDiameter = " << fCollDiameter / mm << " mm\n"; 117 TextFile << "fCollLength = " << fCollLength / mm << " mm\n"; 118 TextFile << "fCollExitPosition = " << fCollExitPosition / mm << " mm\n"; 119 TextFile << "enDet_diameter = " << enDet_diameter / mm << " mm\n"; 120 TextFile << "enDet_thickness = " << enDet_thickness / mm << " mm\n"; 121 TextFile << "enDet_distance = " << enDet_distance / mm << " mm\n"; 122 TextFile << "worldMaterial: " << worldMaterial->GetName() << "\n"; 123 TextFile << "targetMaterial: " << targetMaterial->GetName() << "\n"; 124 TextFile << "wallMaterial: " << wallMaterial->GetName() << "\n"; 125 TextFile << "collMaterial: " << collMaterial->GetName() << "\n"; 126 TextFile << "enDetMaterial: " << enDetMaterial->GetName() << "\n"; 127 TextFile << "innerWallMaterial: " << innerWallMaterial->GetName() << "\n"; 128 129 // WORLD VOLUME 130 131 auto worldSolid = new G4Box("worldSolid", // its name 132 worldSize / 2, worldSize / 2, 133 worldSize / 2); // its size 134 135 auto worldLogic = new G4LogicalVolume(worldSolid, // its solid 136 worldMaterial, // its material 137 "worldLogic"); // its name 138 139 auto worldPhys = new G4PVPlacement(nullptr, // no rotation 140 G4ThreeVector(0, 0, 0), // placement 141 worldLogic, // its logical volume 142 "worldPhys", // its name 143 nullptr, // its mother volume 144 false, // no boolean operation 145 0, // copy number 146 check_intersections); // check intersections 147 148 // INTERACTION VOLUME (IV, also called chamber) 149 auto chamberSolid = new G4Tubs("chamberSolid", // its name 150 0, // rMin 151 IV_diameter / 2., // rMax 152 IV_height / 2., // height/2 153 0 * deg, // phiMin 154 360 * deg); // phiMax 155 156 auto chamberLogic = new G4LogicalVolume(chamberSolid, // its solid 157 targetMaterial, // its material 158 "chamberLogic"); // its name 159 160 new G4PVPlacement(nullptr, IV_centre, chamberLogic, "chamberPhys", worldLogic, false, 0, 161 check_intersections); 162 163 // SENSITIVE VOLUME (SV, also called target) - in general a sub-volume of the 164 // IV, but in this case entire IV is the SV only ionisations that occur in the 165 // SV will be counted 166 auto targetSolid = new G4Tubs("targetSolid", // name 167 0, // rMin 168 IV_diameter / 2., // rMax 169 IV_height / 2., // height/2 170 0 * deg, // phiMin 171 360 * deg); // phiMax 172 173 auto targetLogic = new G4LogicalVolume(targetSolid, targetMaterial, "targetLogic"); 174 175 new G4PVPlacement(nullptr, origin, targetLogic, "targetPhys", chamberLogic, false, 0, 176 check_intersections); 177 178 // WALLS: 179 // 180 181 auto wallSolid = new G4Tubs("wallSolid", // name 182 IV_diameter / 2., // rMin 183 IV_diameter / 2. + wall_total_thickness, // rMax 184 IV_height / 2., // height/2 185 0 * deg, // phiMin 186 360 * deg); // phiMax 187 188 auto wallLogic = new G4LogicalVolume(wallSolid, wallMaterial, "wallSolid"); 189 new G4PVPlacement(nullptr, IV_centre, wallLogic, "wallPhys", worldLogic, false, 0, 190 check_intersections); 191 192 // wall inner layer made of water 193 auto innerWallSolid = new G4Tubs("innerWallSolid", // name 194 IV_diameter / 2., // rMin 195 IV_diameter / 2. + wall_inner_layer_thickness, // rMax 196 IV_height / 2., // height/2 197 0 * deg, // phiMin 198 360 * deg); // phiMax 199 200 auto innerWallLogic = new G4LogicalVolume(innerWallSolid, innerWallMaterial, "innerWallLogic"); 201 new G4PVPlacement(nullptr, origin, innerWallLogic, "innerWallPhys", wallLogic, false, 0, 202 check_intersections); 203 204 // COLLIMATOR: 205 auto collSolid = new G4Tubs("collSolid", // name 206 fCollDiameter / 2., // rMin 207 fCollDiameter, // rMax 208 fCollLength / 2., // height/2 209 0 * deg, // phiMin 210 360 * deg); // phiMax 211 212 auto collLogic = new G4LogicalVolume(collSolid, collMaterial, "collSolid"); 213 214 auto rot = new G4RotationMatrix(); 215 rot->rotateY(90 * deg); 216 new G4PVPlacement(rot, G4ThreeVector(-fCollLength / 2 + fCollExitPosition, 0, 0), collLogic, 217 "collPhys", worldLogic, false, 0, check_intersections); 218 219 // SILICON DETECTOR - present only in macrometric geometry 220 221 auto enDetSolid = new G4Tubs("enDetSolid", // name 222 0, // rMin 223 enDet_diameter / 2., // rMax 224 enDet_thickness / 2., // height/2 225 0 * deg, 360 * deg); 226 227 auto enDetLogic = new G4LogicalVolume(enDetSolid, enDetMaterial, "enDetLogic"); 228 new G4PVPlacement(rot, enDet_centre, enDetLogic, "enDetPhys", worldLogic, false, 0, 229 check_intersections); 230 231 // VISUALISATION ATTRIBUTES 232 233 auto worldVisAtt = new G4VisAttributes(G4Colour(1, 1, 1, 0.1)); 234 worldLogic->SetVisAttributes(worldVisAtt); 235 236 auto targetVisAtt = new G4VisAttributes(G4Colour(0.1, 0.5, 1, 0.7)); 237 targetLogic->SetVisAttributes(targetVisAtt); 238 239 auto innerWallVisAtt = new G4VisAttributes(G4Colour(0, 1, 1, 0.7)); 240 innerWallLogic->SetVisAttributes(innerWallVisAtt); 241 242 auto collVisAtt = new G4VisAttributes(G4Colour(0.7, 0.65, .25, 0.5)); 243 collLogic->SetVisAttributes(collVisAtt); 244 245 auto enDetVisAtt = new G4VisAttributes(G4Colour(0.5, 0.7, .5, 1.)); 246 enDetLogic->SetVisAttributes(enDetVisAtt); 247 248 // Create Target G4Region and add logical volume 249 250 auto region = new G4Region("Target"); 251 252 auto cuts = new G4ProductionCuts(); 253 254 G4double defCut = 1 * nanometer; 255 cuts->SetProductionCut(defCut, "gamma"); 256 cuts->SetProductionCut(defCut, "e-"); 257 cuts->SetProductionCut(defCut, "e+"); 258 cuts->SetProductionCut(defCut, "proton"); 259 260 region->SetProductionCuts(cuts); 261 region->AddRootLogicalVolume(chamberLogic); 262 region->AddRootLogicalVolume(targetLogic); 263 region->AddRootLogicalVolume(innerWallLogic); 264 265 return worldPhys; 266 } 267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 268