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 // ------------------------------------------------------------ 28 // GEANT 4 class implementation file 29 // CERN Geneva Switzerland 30 // 31 // 32 // ------------ GammaRayTelDetectorConstruction ------ 33 // by F.Longo, R.Giannitrapani & G.Santin (13 nov 2000) 34 // 35 // ************************************************************ 36 37 #include "GammaRayTelAnticoincidenceSD.hh" 38 #include "GammaRayTelCalorimeterSD.hh" 39 #include "GammaRayTelDetectorConstruction.hh" 40 #include "GammaRayTelDetectorMessenger.hh" 41 #include "GammaRayTelTrackerSD.hh" 42 43 #include "G4AutoDelete.hh" 44 #include "G4Box.hh" 45 #include "G4Colour.hh" 46 #include "G4FieldManager.hh" 47 #include "G4GlobalMagFieldMessenger.hh" 48 #include "G4LogicalVolume.hh" 49 #include "G4Material.hh" 50 #include "G4PhysicalConstants.hh" 51 #include "G4PVPlacement.hh" 52 #include "G4PVReplica.hh" 53 #include "G4RegionStore.hh" 54 #include "G4RunManager.hh" 55 #include "G4SDManager.hh" 56 #include "G4SystemOfUnits.hh" 57 #include "G4TransportationManager.hh" 58 #include "G4UImanager.hh" 59 #include "G4UniformMagField.hh" 60 #include "G4VisAttributes.hh" 61 62 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 63 64 G4ThreadLocal G4GlobalMagFieldMessenger *GammaRayTelDetectorConstruction::fMagFieldMessenger = nullptr; 65 66 GammaRayTelDetectorConstruction::GammaRayTelDetectorConstruction() 67 { 68 // Initialize thread-local sensitive detectors 69 trackerSD.Put(nullptr); 70 calorimeterSD.Put(nullptr); 71 anticoincidenceSD.Put(nullptr); 72 73 ComputePayloadParameters(); 74 75 // create commands for interactive definition of the payload 76 detectorMessenger = new GammaRayTelDetectorMessenger(this); 77 } 78 79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 80 81 GammaRayTelDetectorConstruction::~GammaRayTelDetectorConstruction() { 82 delete detectorMessenger; 83 } 84 85 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 86 87 auto GammaRayTelDetectorConstruction::Construct() -> G4VPhysicalVolume* { 88 DefineMaterials(); 89 return ConstructPayload(); 90 } 91 92 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 93 94 void GammaRayTelDetectorConstruction::DefineMaterials() { 95 G4String name; 96 G4String symbol; 97 98 G4int numberOfAtoms; 99 G4int numberOfComponents; 100 101 // 102 // define Elements 103 // 104 105 constexpr auto HYDROGEN_ATOMIC_NUMBER{1.}; 106 constexpr auto HYDROGEN_MOLAR_MASS{1.01 * g / mole}; 107 auto *hydrogen = new G4Element(name = "Hydrogen", symbol = "H", HYDROGEN_ATOMIC_NUMBER, HYDROGEN_MOLAR_MASS); 108 109 constexpr auto CARBON_ATOMIC_NUMBER{6.}; 110 constexpr auto CARBON_MOLAR_MASS{12.01 * g / mole}; 111 auto *carbon = new G4Element(name = "Carbon", symbol = "C", CARBON_ATOMIC_NUMBER, CARBON_MOLAR_MASS); 112 113 constexpr auto NITROGEN_ATOMIC_NUMBER{7.}; 114 constexpr auto NITROGEN_MOLAR_MASS{14.006 * g / mole}; 115 auto *nitrogen = new G4Element(name = "Nitrogen", symbol = "N", NITROGEN_ATOMIC_NUMBER, NITROGEN_MOLAR_MASS); 116 117 constexpr auto OXYGEN_ATOMIC_NUMBER{8.}; 118 constexpr auto OXYGEN_MOLAR_MASS{15.99 * g / mole}; 119 auto *oxygen = new G4Element(name = "Oxygen", symbol = "O", OXYGEN_ATOMIC_NUMBER, OXYGEN_MOLAR_MASS); 120 121 constexpr auto ALUMINIUM_ATOMIC_NUMBER{13.}; 122 constexpr auto ALUMINIUM_MOLAR_MASS{26.98 * g / mole}; 123 auto *aluminium = new G4Element(name = "Aluminum", symbol = "Al", ALUMINIUM_ATOMIC_NUMBER, ALUMINIUM_MOLAR_MASS); 124 125 constexpr auto SILICON_ATOMIC_NUMBER{14.}; 126 constexpr auto SILICON_MOLAR_MASS{28.09 * g / mole}; 127 auto *silicon = new G4Element(name = "Silicon", symbol = "Si", SILICON_ATOMIC_NUMBER, SILICON_MOLAR_MASS); 128 129 constexpr auto IRON_ATOMIC_NUMBER{26.}; 130 constexpr auto IRON_MOLAR_MASS{55.845 * g / mole}; 131 auto *iron = new G4Element(name = "Iron", symbol = "Fe", IRON_ATOMIC_NUMBER, IRON_MOLAR_MASS); 132 133 constexpr auto IODINE_ATOMIC_NUMBER{53.}; 134 constexpr auto IODINE_MOLAR_MASS{126.904 * g / mole}; 135 auto *iodine = new G4Element(name = "Iodine", symbol = "I", IODINE_ATOMIC_NUMBER, IODINE_MOLAR_MASS); 136 137 constexpr auto CESIUM_ATOMIC_NUMBER{55}; 138 constexpr auto CESIUM_MOLAR_MASS{132.905 * g / mole}; 139 auto *cesium = new G4Element(name = "Cesium", symbol = "Cs", CESIUM_ATOMIC_NUMBER, CESIUM_MOLAR_MASS); 140 141 constexpr auto LEAD_ATOMIC_NUMBER{82}; 142 constexpr auto LEAD_MOLAR_MASS{207.19 * g / mole}; 143 auto *lead = new G4Element(name = "Lead", symbol = "Pb", LEAD_ATOMIC_NUMBER, LEAD_MOLAR_MASS); 144 145 // 146 // define simple materials 147 // 148 149 constexpr auto TUNGSTEN_ATOMIC_NUMBER{74.}; 150 constexpr auto TUNGSTEN_DENSITY{19.3 * g / cm3}; 151 constexpr auto TUNGSTEN_MOLAR_MASS{183.84 * g / mole}; 152 auto *tungsten = new G4Material(name = "Tungsten", TUNGSTEN_ATOMIC_NUMBER, TUNGSTEN_MOLAR_MASS, TUNGSTEN_DENSITY); 153 154 // 155 // Define a material from elements. 156 // Case 1: chemical molecule 157 // 158 159 constexpr auto SCINTILLATOR_MATERIAL_DENSITY{1.032 * g / cm3}; 160 auto *scintillatorMaterial = new G4Material(name = "Scintillator", SCINTILLATOR_MATERIAL_DENSITY, numberOfComponents = 2); 161 scintillatorMaterial->AddElement(carbon, numberOfAtoms = 9); 162 scintillatorMaterial->AddElement(hydrogen, numberOfAtoms = 10); 163 164 constexpr auto CESIUM_IODIDE_DENSITY{4.53 * g / cm3}; 165 auto *cesiumIodide = new G4Material(name = "CesiumIodide", CESIUM_IODIDE_DENSITY, numberOfComponents = 2); 166 cesiumIodide->AddElement(cesium, numberOfAtoms = 5); 167 cesiumIodide->AddElement(iodine, numberOfAtoms = 5); 168 169 // 170 // Define a material from elements. 171 // Case 2: mixture by fractional mass 172 // 173 174 constexpr auto AIR_DENSITY{1.290 * mg / cm3}; 175 constexpr auto AIR_NITROGEN_MASS_FRACTION{0.7}; 176 constexpr auto AIR_OXYGEN_MASS_FRACTION{0.3}; 177 178 auto *air = new G4Material(name = "Air", AIR_DENSITY, numberOfComponents = 2); 179 air->AddElement(nitrogen, AIR_NITROGEN_MASS_FRACTION); 180 air->AddElement(oxygen, AIR_OXYGEN_MASS_FRACTION); 181 182 constexpr auto ALUMINIUM_DENSITY{2.700 * g / cm3}; 183 constexpr auto ALUMINIUM_MASS_FRACTION{1.}; 184 auto *Al = new G4Material(name = "Aluminum", ALUMINIUM_DENSITY, numberOfComponents = 1); 185 Al->AddElement(aluminium, ALUMINIUM_MASS_FRACTION); 186 187 constexpr auto SILICON_DENSITY{2.333 * g / cm3}; 188 constexpr auto SILICON_MASS_FRACTION{1.}; 189 auto *Si = new G4Material(name = "Silicon", SILICON_DENSITY, numberOfComponents = 1); 190 Si->AddElement(silicon, SILICON_MASS_FRACTION); 191 192 constexpr auto IRON_DENSITY{7.87 * g / cm3}; 193 constexpr auto IRON_MASS_FRACTION{1.}; 194 auto *Fe = new G4Material(name = "Iron", IRON_DENSITY, numberOfComponents = 1); 195 Fe->AddElement(iron, IRON_MASS_FRACTION); 196 197 constexpr auto LEAD_DENSITY{11.35 * g / cm3}; 198 constexpr auto LEAD_MASS_FRACTION{1.}; 199 auto *Pb = new G4Material(name = "Lead", LEAD_DENSITY, numberOfComponents = 1); 200 Pb->AddElement(lead, LEAD_MASS_FRACTION); 201 202 // 203 // examples of vacuum 204 // 205 constexpr auto VACUUM_ATOMIC_NUMBER{1.}; 206 constexpr auto VACUUM_DENSITY{universe_mean_density}; // from PhysicalConstants.h 207 constexpr auto VACUUM_MOLAR_MASS{1.01 * g / mole}; 208 constexpr auto VACUUM_PRESSURE{3.e-18 * pascal}; 209 constexpr auto VACUUM_TEMPERATURE{2.73 * kelvin}; 210 auto *vacuum = new G4Material(name = "Galactic", VACUUM_ATOMIC_NUMBER, VACUUM_MOLAR_MASS, VACUUM_DENSITY, kStateGas, VACUUM_TEMPERATURE, VACUUM_PRESSURE); 211 212 constexpr auto BEAM_DENSITY{1.e-5 * g / cm3}; 213 constexpr auto BEAM_MASS_FRACTION{1.}; 214 constexpr auto BEAM_PRESSURE{2.e-2 * bar}; 215 constexpr auto BEAM_TEMPERATURE{STP_Temperature}; // from PhysicalConstants.h 216 auto *beam = new G4Material(name = "Beam", BEAM_DENSITY, numberOfComponents = 1, kStateGas, BEAM_TEMPERATURE, BEAM_PRESSURE); 217 beam->AddMaterial(air, BEAM_MASS_FRACTION); 218 219 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 220 221 // default materials of the payload 222 223 defaultMaterial = vacuum; 224 225 converterMaterial = tungsten; 226 acdMaterial = scintillatorMaterial; // anticoincidence (ACD) 227 calMaterial = cesiumIodide; // calorimeter (CAL) 228 tkrMaterial = Si; // tracker (TKR) 229 } 230 231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 232 233 auto GammaRayTelDetectorConstruction::ConstructPayload() -> G4VPhysicalVolume* { 234 // complete the payload parameters definition 235 ComputePayloadParameters(); 236 237 // 238 // World 239 // 240 241 solidWorld = new G4Box("World", worldSizeXY / 2, worldSizeXY / 2, worldSizeZ / 2); 242 logicWorld = new G4LogicalVolume(solidWorld, defaultMaterial, "World"); 243 physiWorld = new G4PVPlacement(nullptr, G4ThreeVector(), "World", logicWorld, nullptr, false, 0); 244 245 // 246 // Payload 247 // 248 249 solidPayload = new G4Box("Payload", payloadSizeXY / 2, payloadSizeXY / 2, payloadSizeZ / 2); 250 logicPayload = new G4LogicalVolume(solidPayload, defaultMaterial, "Payload"); 251 physiPayload = new G4PVPlacement(nullptr, G4ThreeVector(), "Payload", logicPayload, physiWorld, false, 0); 252 253 // 254 // Calorimeter (CAL) 255 // 256 257 solidCAL = new G4Box("CAL", calSizeXY / 2, calSizeXY / 2, calSizeZ / 2); 258 logicCAL = new G4LogicalVolume(solidCAL, defaultMaterial, "CAL"); 259 physiCAL = new G4PVPlacement(nullptr, 260 G4ThreeVector(0, 0, 261 -payloadSizeZ / 2 + calSizeZ / 2), 262 "CAL", logicCAL, physiPayload, false, 0); 263 264 // 265 // Tracker (TKR) 266 // 267 268 solidTKR = new G4Box("TKR", tkrSizeXY / 2, tkrSizeXY / 2, tkrSizeZ / 2); 269 logicTKR = new G4LogicalVolume(solidTKR, defaultMaterial, "TKR"); 270 physiTKR = new G4PVPlacement(nullptr, 271 G4ThreeVector(0, 0, 272 -payloadSizeZ / 2 + calSizeZ + calTKRDistance 273 + tkrSizeZ / 2), 274 "TKR", logicTKR, physiPayload, false, 0); 275 276 // 277 // Anticoincidence, Top Side (ACT) 278 // 279 280 solidACT = new G4Box("ACT", actSizeXY / 2, actSizeXY / 2, actSizeZ / 2); 281 logicACT = new G4LogicalVolume(solidACT, acdMaterial, "ACT"); 282 physiACT = new G4PVPlacement(nullptr, 283 G4ThreeVector(0, 0, 284 -payloadSizeZ / 2 + calSizeZ + calTKRDistance + tkrSizeZ 285 + acdTKRDistance + actSizeZ / 2), 286 "ACT", logicACT, physiPayload, false, 0); 287 288 // 289 // Anticoincidence, Lateral Side (ACL) 290 // 291 292 solidACL1 = new G4Box("ACL1", acl1SizeX / 2, acl1SizeY / 2, acl1SizeZ / 2); 293 logicACL1 = new G4LogicalVolume(solidACL1, acdMaterial, "ACL"); 294 295 physiACL1 = new G4PVPlacement(nullptr, 296 G4ThreeVector(-payloadSizeXY / 2 + acl1SizeX / 2, 297 -payloadSizeXY / 2 + acl1SizeY / 2, 298 -payloadSizeZ / 2 + acl1SizeZ / 2), 299 "ACL1", logicACL1, physiPayload, false, 0); 300 301 physiACL1 = new G4PVPlacement(nullptr, 302 G4ThreeVector(payloadSizeXY / 2 - acl1SizeX / 2, 303 payloadSizeXY / 2 - acl1SizeY / 2, 304 -payloadSizeZ / 2 + acl1SizeZ / 2), 305 "ACL1", logicACL1, physiPayload, false, 1); 306 307 solidACL2 = new G4Box("ACL2", acl2SizeX / 2, acl2SizeY / 2, acl2SizeZ / 2); 308 logicACL2 = new G4LogicalVolume(solidACL2, acdMaterial, "ACL2"); 309 310 physiACL2 = new G4PVPlacement(nullptr, 311 G4ThreeVector(-payloadSizeXY / 2 + acl2SizeX / 2, 312 payloadSizeXY / 2 - acl2SizeY / 2, 313 -payloadSizeZ / 2 + acl2SizeZ / 2), 314 "ACL2", logicACL2, physiPayload, false, 0); 315 316 physiACL2 = new G4PVPlacement(nullptr, 317 G4ThreeVector(payloadSizeXY / 2 - acl2SizeX / 2, 318 -payloadSizeXY / 2 + acl2SizeY / 2, 319 -payloadSizeZ / 2 + acl2SizeZ / 2), 320 "ACL2", logicACL2, physiPayload, false, 1); 321 322 // 323 // Tracker Structure (Plane + Converter + TKRDetectorX + TKRDetectorY) 324 // 325 326 solidPlane = new G4Box("Plane", tkrSizeXY / 2, tkrSizeXY / 2, tkrSupportThickness / 2); 327 logicPlane = new G4LogicalVolume(solidPlane, defaultMaterial, "Plane"); 328 329 solidTKRDetectorY = new G4Box("TKRDetectorY", tkrSizeXY / 2, tkrSizeXY / 2, tkrSiliconThickness / 2); 330 logicTKRDetectorY = new G4LogicalVolume(solidTKRDetectorY, tkrMaterial, "TKRDetector Y"); 331 332 solidTKRDetectorX = new G4Box("TKRDetectorX", tkrSizeXY / 2, tkrSizeXY / 2, tkrSiliconThickness / 2); 333 logicTKRDetectorX = new G4LogicalVolume(solidTKRDetectorX, tkrMaterial, "TKRDetector X"); 334 335 solidConverter = new G4Box("Converter", tkrSizeXY / 2, tkrSizeXY / 2, converterThickness / 2); 336 logicConverter = new G4LogicalVolume(solidConverter, converterMaterial, "Converter"); 337 338 G4int i = 0; 339 340 for (i = 0; i < numberOfTKRLayers; i++) { 341 physiTKRDetectorY = new G4PVPlacement(nullptr, 342 G4ThreeVector(0., 0., 343 -tkrSizeZ / 2 + tkrSiliconThickness / 2 344 + (i) * tkrLayerDistance), 345 "TKRDetectorY", logicTKRDetectorY, physiTKR, false, i); 346 347 physiTKRDetectorX = new G4PVPlacement(nullptr, 348 G4ThreeVector(0., 0., 349 -tkrSizeZ / 2 + tkrSiliconThickness / 2 350 + tkrViewsDistance + tkrSiliconThickness 351 + (i) * tkrLayerDistance), 352 "TKRDetectorX", logicTKRDetectorX, physiTKR, false, i); 353 354 physiConverter = new G4PVPlacement(nullptr, 355 G4ThreeVector(0., 0., 356 -tkrSizeZ / 2 + 2 * tkrSiliconThickness 357 + tkrViewsDistance + converterThickness / 2 358 + (i) * tkrLayerDistance), 359 "Converter", logicConverter, physiTKR, false, i); 360 361 physiPlane = new G4PVPlacement(nullptr, 362 G4ThreeVector(0., 0., 363 -tkrSizeZ / 2 + 2 * tkrSiliconThickness 364 + tkrViewsDistance + converterThickness 365 + tkrSupportThickness / 2 366 + (i) * tkrLayerDistance), 367 "Plane", logicPlane, physiTKR, false, i); 368 } 369 370 auto *solidTKRActiveTileX = new G4Box("Active Tile X", tkrActiveTileXY / 2, tkrActiveTileXY / 2, tkrActiveTileZ / 2); 371 auto *solidTKRActiveTileY = new G4Box("Active Tile Y", tkrActiveTileXY / 2, tkrActiveTileXY / 2, tkrActiveTileZ / 2); 372 373 auto *logicTKRActiveTileX = new G4LogicalVolume(solidTKRActiveTileX, tkrMaterial, "Active Tile X", nullptr, nullptr, nullptr); 374 auto *logicTKRActiveTileY = new G4LogicalVolume(solidTKRActiveTileY, tkrMaterial, "Active Tile Y", nullptr, nullptr, nullptr); 375 376 G4int j = 0; 377 G4int k = 0; 378 379 G4double x = 0.; 380 G4double y = 0.; 381 G4double z = 0.; 382 383 for (i = 0; i < numberOfTKRTiles; i++) { 384 for (j = 0; j < numberOfTKRTiles; j++) { 385 k = i * numberOfTKRTiles + j; 386 387 x = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing 388 + tkrActiveTileXY / 2 389 + (i) 390 * ((2 * siliconGuardRing) + tilesSeparation 391 + tkrActiveTileXY); 392 393 y = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing 394 + tkrActiveTileXY / 2 395 + (j) 396 * ((2 * siliconGuardRing) + tilesSeparation 397 + tkrActiveTileXY); 398 z = 0.; 399 400 new G4PVPlacement(nullptr, G4ThreeVector(x, y, z), logicTKRActiveTileY, "Active Tile Y", logicTKRDetectorY, false, k); 401 402 x = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing 403 + tkrActiveTileXY / 2 404 + (j) 405 * ((2 * siliconGuardRing) + tilesSeparation 406 + tkrActiveTileXY); 407 408 y = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing 409 + tkrActiveTileXY / 2 410 + (i) 411 * ((2 * siliconGuardRing) + tilesSeparation 412 + tkrActiveTileXY); 413 z = 0.; 414 415 new G4PVPlacement(nullptr, G4ThreeVector(x, y, z), logicTKRActiveTileX, "Active Tile X", logicTKRDetectorX, false, k); 416 } 417 } 418 419 // Strips 420 421 // Silicon Strips 422 423 /* 424 G4double tkrXStripX{0.}; 425 G4double tkrYStripY{0.}; 426 G4double tkrYStripX{0.}; 427 G4double tkrXStripY{0.}; 428 */ 429 430 tkrXStripX = tkrYStripY = tkrSiliconPitch; 431 tkrYStripX = tkrXStripY = tkrActiveTileXY; 432 tkrZStrip = tkrSiliconThickness; 433 434 auto *solidTKRStripX = new G4Box("Strip X", tkrXStripX / 2, tkrYStripX / 2, tkrZStrip / 2); 435 logicTKRStripX = new G4LogicalVolume(solidTKRStripX, tkrMaterial, "Strip X", nullptr, nullptr, nullptr); 436 437 auto *solidTKRStripY = new G4Box("Strip Y", tkrXStripY / 2, tkrYStripY / 2, tkrZStrip / 2); 438 logicTKRStripY = new G4LogicalVolume(solidTKRStripY, tkrMaterial, "Strip Y", nullptr, nullptr, nullptr); 439 440 for (i = 0; i < numberOfTKRStrips; i++) { 441 new G4PVPlacement(nullptr, 442 G4ThreeVector( 443 -tkrActiveTileXY / 2 + tkrSiliconPitch / 2 444 + (i) * tkrSiliconPitch, 0., 0.), 445 logicTKRStripX, "Strip X", logicTKRActiveTileX, false, i); 446 447 new G4PVPlacement(nullptr, 448 G4ThreeVector(0., 449 -tkrActiveTileXY / 2 + tkrSiliconPitch / 2 450 + (i) * tkrSiliconPitch, 0.), 451 logicTKRStripY, "Strip Y", logicTKRActiveTileY, false, i); 452 } 453 454 // 455 // Calorimeter Structure (CALLayerX + CALLayerY) 456 // 457 458 solidCALLayerX = new G4Box("CALLayerX", calSizeXY / 2, calSizeXY / 2, calBarThickness / 2); 459 logicCALLayerX = new G4LogicalVolume(solidCALLayerX, calMaterial, "CALLayerX"); 460 461 solidCALLayerY = new G4Box("CALLayerY", calSizeXY / 2, calSizeXY / 2, calBarThickness / 2); 462 logicCALLayerY = new G4LogicalVolume(solidCALLayerY, calMaterial, "CALLayerY"); 463 464 for (i = 0; i < numberOfCALLayers; i++) { 465 physiCALLayerY = new G4PVPlacement(nullptr, 466 G4ThreeVector(0, 0, 467 -calSizeZ / 2 + calBarThickness / 2 468 + (i) * 2 * calBarThickness), 469 "CALLayerY", logicCALLayerY, physiCAL, false, i); 470 471 physiCALLayerX = new G4PVPlacement(nullptr, 472 G4ThreeVector(0, 0, 473 -calSizeZ / 2 + calBarThickness / 2 + calBarThickness 474 + (i) * 2 * calBarThickness), 475 "CALLayerX", logicCALLayerX, physiCAL, false, i); 476 } 477 478 // 479 // Calorimeter Structure (CALDetectorX + CALDetectorY) 480 // 481 482 solidCALDetectorX = new G4Box("CALDetectorX", calBarX / 2, calBarY / 2, calBarThickness / 2); 483 logicCALDetectorX = new G4LogicalVolume(solidCALDetectorX, calMaterial, "CALDetectorX"); 484 485 solidCALDetectorY = new G4Box("CALDetectorY", calBarY / 2, calBarX / 2, calBarThickness / 2); 486 logicCALDetectorY = new G4LogicalVolume(solidCALDetectorY, calMaterial, "CALDetectorY"); 487 488 for (i = 0; i < numberOfCALBars; i++) { 489 physiCALDetectorY = new G4PVPlacement(nullptr, 490 G4ThreeVector(-calSizeXY / 2 + calBarY / 2 + (i) * calBarY, 0, 0), 491 logicCALDetectorY, "CALDetectorY", logicCALLayerY, false, i); 492 493 physiCALDetectorX = new G4PVPlacement(nullptr, 494 G4ThreeVector(0, -calSizeXY / 2 + calBarY / 2 + (i) * calBarY, 0), 495 logicCALDetectorX, "CALDetectorX", logicCALLayerX, false, i); 496 } 497 498 /* 499 // Cuts by Region 500 501 G4String regionName[] = {"Calorimeter", "Tracker"}; 502 503 if (calorimeterCutRegion) { 504 delete calorimeterCutRegion; 505 } 506 calorimeterCutRegion = new G4Region(regionName[0]); 507 logicCAL->SetRegion(calorimeterCutRegion); 508 calorimeterCutRegion->AddRootLogicalVolume(logicCAL); 509 510 if (trackerCutRegion != nullptr) { 511 delete trackerCutRegion; 512 } 513 trackerCutRegion = new G4Region(regionName[1]); 514 logicTKR->SetRegion(trackerCutRegion); 515 trackerCutRegion->AddRootLogicalVolume(logicTKR); 516 */ 517 518 // 519 // Visualization attributes 520 // 521 // Invisible Volume 522 logicWorld->SetVisAttributes(G4VisAttributes::GetInvisible()); 523 logicPayload->SetVisAttributes(G4VisAttributes::GetInvisible()); 524 logicTKR->SetVisAttributes(G4VisAttributes::GetInvisible()); 525 logicTKRActiveTileX->SetVisAttributes(G4VisAttributes::GetInvisible()); 526 logicTKRActiveTileY->SetVisAttributes(G4VisAttributes::GetInvisible()); 527 logicPlane->SetVisAttributes(G4VisAttributes::GetInvisible()); 528 logicConverter->SetVisAttributes(G4VisAttributes::GetInvisible()); 529 logicCAL->SetVisAttributes(G4VisAttributes::GetInvisible()); 530 logicCALLayerX->SetVisAttributes(G4VisAttributes::GetInvisible()); 531 logicCALLayerY->SetVisAttributes(G4VisAttributes::GetInvisible()); 532 logicTKRStripX->SetVisAttributes(G4VisAttributes::GetInvisible()); 533 logicTKRStripY->SetVisAttributes(G4VisAttributes::GetInvisible()); 534 535 // Some visualization styles 536 537 auto *visualizationStyle1 = new G4VisAttributes(G4Colour(0.3, 0.8, 0.1)); 538 visualizationStyle1->SetVisibility(true); 539 visualizationStyle1->SetForceSolid(TRUE); 540 541 auto *visualizationStyle2 = new G4VisAttributes(G4Colour(0.2, 0.3, 0.8)); 542 visualizationStyle2->SetVisibility(true); 543 visualizationStyle2->SetForceSolid(FALSE); 544 545 auto *visualizationStyle3 = new G4VisAttributes(G4Colour(0.8, 0.2, 0.3)); 546 visualizationStyle3->SetVisibility(true); 547 visualizationStyle3->SetForceWireframe(TRUE); 548 549 // Visible Volumes 550 551 logicCALDetectorX->SetVisAttributes(visualizationStyle1); 552 logicCALDetectorY->SetVisAttributes(visualizationStyle1); 553 logicTKRDetectorX->SetVisAttributes(visualizationStyle2); 554 logicTKRDetectorY->SetVisAttributes(visualizationStyle2); 555 logicACT->SetVisAttributes(visualizationStyle3); 556 logicACL1->SetVisAttributes(visualizationStyle3); 557 logicACL2->SetVisAttributes(visualizationStyle3); 558 559 // 560 // always return the physical World 561 // 562 PrintPayloadParameters(); 563 564 return physiWorld; 565 } 566 567 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 568 569 void GammaRayTelDetectorConstruction::ConstructSDandField() { 570 // 571 // Sensitive detector: Tracker 572 // 573 if (trackerSD.Get() == nullptr) { 574 constexpr auto TRACKER_SENSITIVE_DETECTOR_NAME = "TrackerSD"; 575 auto *sensitiveDetector = new GammaRayTelTrackerSD(TRACKER_SENSITIVE_DETECTOR_NAME); 576 trackerSD.Put(sensitiveDetector); 577 } 578 579 G4SDManager::GetSDMpointer()->AddNewDetector(trackerSD.Get()); 580 581 // Flags the strips as sensitive . 582 if (logicTKRStripX != nullptr) { 583 SetSensitiveDetector(logicTKRStripX, trackerSD.Get()); // ActiveStripX 584 } 585 if (logicTKRStripY != nullptr) { 586 SetSensitiveDetector(logicTKRStripY, trackerSD.Get()); // ActiveStripY 587 } 588 589 // 590 // Sensitive detector: Calorimeter 591 // 592 if (calorimeterSD.Get() == nullptr) { 593 constexpr auto CALORIMETER_SENSITIVE_DETECTOR_NAME = "CalorimeterSD"; 594 auto *sensitiveDetector = new GammaRayTelCalorimeterSD(CALORIMETER_SENSITIVE_DETECTOR_NAME); 595 calorimeterSD.Put(sensitiveDetector); 596 } 597 598 G4SDManager::GetSDMpointer()->AddNewDetector(calorimeterSD.Get()); 599 if (logicCALDetectorX != nullptr) { 600 SetSensitiveDetector(logicCALDetectorX, calorimeterSD.Get()); // CAL BarX 601 } 602 if (logicCALDetectorY != nullptr) { 603 SetSensitiveDetector(logicCALDetectorY, calorimeterSD.Get()); // CAL BarY 604 } 605 606 // 607 // Sensitive detector: Anticoincidence 608 // 609 if (anticoincidenceSD.Get() == nullptr) { 610 constexpr auto ANTICOINCIDENCE_SENSITIVE_DETECTOR_NAME = "AnticoincidenceSD"; 611 auto *sensitiveDetector = new GammaRayTelAnticoincidenceSD(ANTICOINCIDENCE_SENSITIVE_DETECTOR_NAME); 612 anticoincidenceSD.Put(sensitiveDetector); 613 } 614 615 G4SDManager::GetSDMpointer()->AddNewDetector(anticoincidenceSD.Get()); 616 if (logicACT != nullptr) { 617 SetSensitiveDetector(logicACT, anticoincidenceSD.Get()); // ACD top 618 } 619 if (logicACL1 != nullptr) { 620 SetSensitiveDetector(logicACL1, anticoincidenceSD.Get()); // ACD lateral side 621 } 622 if (logicACL2 != nullptr) { 623 SetSensitiveDetector(logicACL2, anticoincidenceSD.Get()); // ACD lateral side 624 } 625 626 // Create global magnetic field messenger. 627 // Uniform magnetic field is then created automatically if the field value is not zero. 628 auto fieldValue = G4ThreeVector(); 629 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue); 630 fMagFieldMessenger->SetVerboseLevel(1); 631 632 // Register the field messenger for deleting 633 G4AutoDelete::Register (fMagFieldMessenger); 634 } 635 636 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 637 638 void GammaRayTelDetectorConstruction::PrintPayloadParameters() { 639 G4cout 640 << "\n---------------------------------------------------------------------------------\n" 641 << "---> The tracker is composed by " << numberOfTKRLayers << " layers" 642 << ", each made of " << converterMaterial->GetName() 643 << " and " << converterThickness / mm << " mm long." 644 << "\n---------------------------------------------------------------------------------\n"; 645 } 646 647 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 648 649 void GammaRayTelDetectorConstruction::SetConverterMaterial(G4String materialChoice) { 650 // search the material by its name 651 G4Material *material = G4Material::GetMaterial(materialChoice); 652 if (material != nullptr) { 653 converterMaterial = material; 654 logicConverter->SetMaterial(material); 655 PrintPayloadParameters(); 656 } 657 } 658 659 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 660 661 void GammaRayTelDetectorConstruction::SetConverterThickness(G4double value) { 662 converterThickness = value; 663 } 664 665 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 666 667 void GammaRayTelDetectorConstruction::SetTKRSiliconThickness(G4double value) { 668 tkrSiliconThickness = value; 669 } 670 671 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 672 673 void GammaRayTelDetectorConstruction::SetTKRSiliconPitch(G4double value) { 674 tkrSiliconPitch = value; 675 } 676 677 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 678 679 void GammaRayTelDetectorConstruction::SetTKRTileSizeXY(G4double value) { 680 tkrSiliconTileXY = value; 681 } 682 683 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 684 685 void GammaRayTelDetectorConstruction::SetNbOfTKRLayers(G4int value) { 686 numberOfTKRLayers = value; 687 } 688 689 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 690 691 void GammaRayTelDetectorConstruction::SetNbOfTKRTiles(G4int value) { 692 numberOfTKRTiles = value; 693 } 694 695 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 696 697 void GammaRayTelDetectorConstruction::SetTKRLayerDistance(G4double value) { 698 tkrLayerDistance = value; 699 } 700 701 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 702 703 void GammaRayTelDetectorConstruction::SetTKRViewsDistance(G4double value) { 704 tkrViewsDistance = value; 705 } 706 707 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 708 709 void GammaRayTelDetectorConstruction::SetNbOfCALLayers(G4int value) { 710 numberOfCALLayers = value; 711 } 712 713 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 714 715 void GammaRayTelDetectorConstruction::SetNbOfCALBars(G4int value) { 716 numberOfCALBars = value; 717 } 718 719 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 720 721 void GammaRayTelDetectorConstruction::SetCALBarThickness(G4double value) { 722 calBarThickness = value; 723 } 724 725 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 726 727 void GammaRayTelDetectorConstruction::SetACDThickness(G4double value) { 728 acdThickness = value; 729 } 730 731 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 732 733 void GammaRayTelDetectorConstruction::SetMagField(G4double fieldValue) { 734 // Just invoke manually the MT-safe command /globalField/setValue instantiated by the GlobalFieldMessenger 735 std::stringstream stream; 736 stream << "/globalField/setValue 0 0 " << fieldValue / tesla << " tesla"; 737 738 G4String command = stream.str(); 739 G4cout << "Going to execute: " << command << G4endl; 740 741 auto *uiManager = G4UImanager::GetUIpointer(); 742 uiManager->ApplyCommand(command); 743 } 744 745 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 746 747 void GammaRayTelDetectorConstruction::UpdateGeometry() { 748 // delete payloadSD; 749 G4RunManager::GetRunManager()->DefineWorldVolume(ConstructPayload()); 750 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 751 G4RegionStore::GetInstance()->UpdateMaterialList(physiWorld); 752 G4RunManager::GetRunManager()->ReinitializeGeometry(); 753 } 754