Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 /// \file medical/GammaTherapy/src/DetectorCon 28 /// \brief Implementation of the DetectorConst 29 // 30 // 31 // ------------------------------------------- 32 // GEANT4 ibrem test 33 // 34 // Authors: V.Grichine, V.Ivanchenko 35 // 36 // Modified: 37 // 38 // 18-02-03 V.Ivanchenko create 39 // 40 // ------------------------------------------- 41 42 //....oooOO0OOooo........oooOO0OOooo........oo 43 //....oooOO0OOooo........oooOO0OOooo........oo 44 45 #include "DetectorConstruction.hh" 46 47 #include "CheckVolumeSD.hh" 48 #include "DetectorMessenger.hh" 49 #include "PhantomSD.hh" 50 #include "TargetSD.hh" 51 52 #include "G4Box.hh" 53 #include "G4Colour.hh" 54 #include "G4GeometryManager.hh" 55 #include "G4LogicalVolume.hh" 56 #include "G4LogicalVolumeStore.hh" 57 #include "G4Material.hh" 58 #include "G4NistManager.hh" 59 #include "G4PVPlacement.hh" 60 #include "G4PhysicalConstants.hh" 61 #include "G4PhysicalVolumeStore.hh" 62 #include "G4RunManager.hh" 63 #include "G4SDManager.hh" 64 #include "G4SolidStore.hh" 65 #include "G4SystemOfUnits.hh" 66 #include "G4Tubs.hh" 67 #include "G4VPhysicalVolume.hh" 68 #include "G4VisAttributes.hh" 69 #include "G4ios.hh" 70 #include "globals.hh" 71 72 //....oooOO0OOooo........oooOO0OOooo........oo 73 74 DetectorConstruction::DetectorConstruction() 75 { 76 fLogicTarget1 = 0; 77 fLogicTarget2 = 0; 78 79 fMessenger = new DetectorMessenger(this); 80 fVerbose = false; 81 82 fNumZ = 60; 83 fNumR = 80; 84 85 fNumE = 200; 86 fMaxEnergy = 50.0 * MeV; 87 88 fDistanceVacuumTarget = 30. * mm, 89 90 fDelta = 0.001 * mm; 91 92 fTargetRadius = 100. * mm; 93 fTarget1Z = 9. * mm; 94 fTarget2Z = 6. * mm; 95 96 fGasVolumeRadius = 210. * mm; 97 fGasVolumeZ = 690. * mm; 98 fMylarVolumeZ = 0.02 * mm; 99 100 fCheckVolumeZ = 0.1 * mm; 101 fCheckShiftZ = 200. * mm; 102 103 fAbsorberRadius = 200. * mm; 104 fPhantomRadius = 300. * mm; 105 fPhantomZ = 300. * mm; 106 107 fAirZ = 210. * mm; 108 fAbsorberShiftZ = 70. * mm; 109 fWindowZ = 0.05 * mm; 110 111 G4NistManager* man = G4NistManager::Instance 112 // man->SetVerbose(1); 113 114 fTarget1Material = man->FindOrBuildMaterial( 115 fWindowMaterial = fTarget1Material; 116 fTarget2Material = man->FindOrBuildMaterial( 117 fLightMaterial = man->FindOrBuildMaterial("G 118 fAbsorberMaterial = man->FindOrBuildMaterial 119 fWorldMaterial = man->FindOrBuildMaterial("G 120 fMylar = man->FindOrBuildMaterial("G4_MYLAR" 121 122 G4cout << *(G4Material::GetMaterialTable()) 123 } 124 125 //....oooOO0OOooo........oooOO0OOooo........oo 126 127 DetectorConstruction::~DetectorConstruction() 128 { 129 delete fMessenger; 130 } 131 132 //....oooOO0OOooo........oooOO0OOooo........oo 133 134 void DetectorConstruction::InitialiseGeometryP 135 { 136 // Volumee sizes 137 138 G4double factor = 1.2; 139 140 fWorldXY = factor * std::max(fPhantomRadius, 141 fAbsorberZ = fPhantomZ / fNumZ; 142 fGasVolumeZ = 1000. * mm - fAbsorberShiftZ - 143 144 G4double ztot = fGasVolumeZ + fAirZ + fPhant 145 fTargetVolumeZ = fDistanceVacuumTarget + fTa 146 fWorldZ = factor * ztot * 0.5; 147 148 if (fCheckShiftZ < fDelta) { 149 fCheckShiftZ = fDelta; 150 } 151 if (fCheckShiftZ > fAirZ - fCheckVolumeZ - f 152 fCheckShiftZ = fAirZ - fCheckVolumeZ - fDe 153 } 154 155 // Z position of volumes from upstream to do 156 157 fWindowPosZ = -(ztot + fWindowZ) * 0.5; 158 fGeneratorPosZ = fWindowPosZ - 0.5 * fWindow 159 160 fTargetVolumePosZ = -0.5 * (ztot - fTargetVo 161 fTarget1PosZ = -0.5 * (fTargetVolumeZ - fTar 162 fTarget2PosZ = fTarget1PosZ + 0.5 * (fTarget 163 164 fGasVolumePosZ = fTargetVolumePosZ + 0.5 * ( 165 fCheckVolumePosZ = fGasVolumePosZ + 0.5 * (f 166 fMylarPosZ = fGasVolumePosZ + 0.5 * (fGasVol 167 168 fPhantomPosZ = fGasVolumePosZ + 0.5 * (fGasV 169 fAbsorberPosZ = fAbsorberShiftZ - 0.5 * (fPh 170 171 fShiftZPh = fPhantomPosZ - 0.5 * fPhantomZ; 172 173 DumpGeometryParameters(); 174 } 175 176 //....oooOO0OOooo........oooOO0OOooo........oo 177 178 G4VPhysicalVolume* DetectorConstruction::Const 179 { 180 InitialiseGeometryParameters(); 181 182 G4GeometryManager::GetInstance()->OpenGeomet 183 G4PhysicalVolumeStore::GetInstance()->Clean( 184 G4LogicalVolumeStore::GetInstance()->Clean() 185 G4SolidStore::GetInstance()->Clean(); 186 // 187 // World 188 // 189 190 G4Box* solidWorld = new G4Box("World", fWorl 191 G4LogicalVolume* logicWorld = new G4LogicalV 192 G4VPhysicalVolume* physWorld = 193 new G4PVPlacement(0, G4ThreeVector(), "Wor 194 195 // Be Vacuum window 196 G4Tubs* solidWin = new G4Tubs("Window", 0., 197 G4LogicalVolume* logicWin = new G4LogicalVol 198 new G4PVPlacement(0, G4ThreeVector(0., 0., f 199 200 // Target Volume 201 G4Tubs* solidTGVolume = 202 new G4Tubs("TargetVolume", 0., fTargetRadi 203 G4LogicalVolume* logicTGVolume = 204 new G4LogicalVolume(solidTGVolume, fLightM 205 new G4PVPlacement(0, G4ThreeVector(0., 0., f 206 logicWorld, false, 0); 207 208 // Target 1 209 G4Tubs* solidTarget1 = new G4Tubs("Target1", 210 fLogicTarget1 = new G4LogicalVolume(solidTar 211 fTarget1 = new G4PVPlacement(0, G4ThreeVecto 212 logicTGVolume, 213 // fLogicTarget1->SetSensitiveDetector(fTar 214 215 // Target 2 (for combined targets) 216 G4Tubs* solidTarget2 = new G4Tubs("Target2", 217 fLogicTarget2 = new G4LogicalVolume(solidTar 218 fTarget2 = new G4PVPlacement(0, G4ThreeVecto 219 logicTGVolume, 220 221 // fLogicTarget2->SetSensitiveDetector(fTar 222 223 // Gas Volume 224 G4Tubs* solidGasVolume = 225 new G4Tubs("GasVolume", 0., fGasVolumeRadi 226 G4LogicalVolume* logicGasVolume = 227 new G4LogicalVolume(solidGasVolume, fLight 228 fGasVolume = new G4PVPlacement(0, G4ThreeVec 229 logicGasVolum 230 231 // Mylar window 232 G4Tubs* sMylarVolume = new G4Tubs("Mylar", 0 233 G4LogicalVolume* lMylarVolume = new G4Logica 234 new G4PVPlacement(0, G4ThreeVector(0., 0., f 235 0); 236 237 // Check Volume 238 G4Tubs* solidCheckVolume = 239 new G4Tubs("CheckVolume", 0., fGasVolumeRa 240 fLogicCheckVolume = new G4LogicalVolume(soli 241 fCheckVolume = new G4PVPlacement(0, G4ThreeV 242 fLogicCheck 243 // logicCheckVolume->SetSensitiveDetector(f 244 245 // Phantom 246 G4Box* solidPhantom = new G4Box("Phantom", f 247 G4LogicalVolume* logicPhantom = new G4Logica 248 G4VPhysicalVolume* physPhantom = new G4PVPla 249 250 251 G4Tubs* solidPh = new G4Tubs("PhantomSD", 0. 252 fLogicPh = new G4LogicalVolume(solidPh, fAbs 253 fPhantom = 254 new G4PVPlacement(0, G4ThreeVector(0., 0., 255 G4cout << "Phantom R= " << fAbsorberRadius < 256 257 // Sensitive Absorber 258 G4double absWidth = 0.5 * fAbsorberZ; 259 G4Tubs* solidAbsorber = new G4Tubs("Absorber 260 fLogicAbsorber = new G4LogicalVolume(solidAb 261 G4cout << "Absorber R= " << fAbsorberRadius 262 << G4endl; 263 264 new G4PVPlacement(0, G4ThreeVector(0., 0., f 265 false, 0); 266 267 G4double stepR = fAbsorberRadius / (G4double 268 269 G4double r1 = 0.0; 270 G4double r2 = 0.0; 271 G4Tubs* solidRing; 272 273 G4VisAttributes* VisAtt_ring = new G4VisAttr 274 for (G4int k = 0; k < fNumR; k++) { 275 r2 = r1 + stepR; 276 if (k == fNumR - 1) r2 = fAbsorberRadius; 277 // G4cout << "New ring r1= " << r1 << " 278 // << " dz= " << absWidth << G4endl; 279 solidRing = new G4Tubs("Ring", r1, r2, abs 280 G4LogicalVolume* logicRing = new G4Logical 281 // logicRing->SetSensitiveDetector(fPha 282 logicRing->SetVisAttributes(VisAtt_ring); 283 fLogicRing.push_back(logicRing); 284 new G4PVPlacement(0, G4ThreeVector(0., 0., 285 r1 = r2; 286 } 287 288 // 289 // Visualization attributes 290 // 291 G4VisAttributes* VisAtt = 0; 292 VisAtt = new G4VisAttributes(G4Colour(1.0, 1 293 VisAtt->SetVisibility(true); 294 fLogicAbsorber->SetVisAttributes(VisAtt); 295 296 VisAtt = new G4VisAttributes(G4Colour(1.0, 1 297 VisAtt->SetVisibility(true); 298 logicPhantom->SetVisAttributes(VisAtt); 299 300 VisAtt = new G4VisAttributes(G4Colour(1.0, 0 301 VisAtt->SetVisibility(true); 302 fLogicPh->SetVisAttributes(VisAtt); 303 304 VisAtt = new G4VisAttributes(G4Colour(1.0, 1 305 VisAtt->SetVisibility(true); 306 fLogicAbsorber->SetVisAttributes(VisAtt); 307 308 VisAtt = new G4VisAttributes(G4Colour(0.1, 1 309 VisAtt->SetVisibility(true); 310 logicWorld->SetVisAttributes(VisAtt); 311 312 VisAtt = new G4VisAttributes(G4Colour(1.0, 1 313 VisAtt->SetVisibility(true); 314 logicGasVolume->SetVisAttributes(VisAtt); 315 316 VisAtt = new G4VisAttributes(G4Colour(0.0, 0 317 VisAtt->SetVisibility(true); 318 fLogicTarget1->SetVisAttributes(VisAtt); 319 fLogicTarget2->SetVisAttributes(VisAtt); 320 logicTGVolume->SetVisAttributes(VisAtt); 321 322 return physWorld; 323 } 324 325 void DetectorConstruction::ConstructSDandField 326 { 327 static G4ThreadLocal G4bool initialized = fa 328 if (!initialized) { 329 // Prepare sensitive detectors 330 CheckVolumeSD* fCheckSD = new CheckVolumeS 331 (G4SDManager::GetSDMpointer())->AddNewDete 332 fLogicCheckVolume->SetSensitiveDetector(fC 333 334 TargetSD* fTargetSD = new TargetSD("target 335 (G4SDManager::GetSDMpointer())->AddNewDete 336 fLogicTarget1->SetSensitiveDetector(fTarge 337 fLogicTarget2->SetSensitiveDetector(fTarge 338 339 PhantomSD* fPhantomSD = new PhantomSD("pha 340 (G4SDManager::GetSDMpointer())->AddNewDete 341 fPhantomSD->SetShiftZ(fShiftZPh); 342 for (auto& v : fLogicRing) 343 v->SetSensitiveDetector(fPhantomSD); 344 fLogicPh->SetSensitiveDetector(fPhantomSD) 345 fLogicAbsorber->SetSensitiveDetector(fPhan 346 initialized = true; 347 } 348 } 349 350 //....oooOO0OOooo........oooOO0OOooo........oo 351 352 void DetectorConstruction::SetTarget1Material( 353 { 354 // search the material by its name 355 G4Material* pttoMaterial = G4NistManager::In 356 if (!pttoMaterial) { 357 G4cout << "Material " << mat << " is not f 358 } 359 else if (pttoMaterial != fTarget1Material) { 360 G4cout << "New target1 material " << mat < 361 if (fLogicTarget1) { 362 fLogicTarget1->SetMaterial(fTarget1Mater 363 } 364 G4RunManager::GetRunManager()->PhysicsHasB 365 } 366 } 367 368 //....oooOO0OOooo........oooOO0OOooo........oo 369 370 void DetectorConstruction::SetTarget2Material( 371 { 372 // search the material by its name 373 G4Material* pttoMaterial = G4NistManager::In 374 375 if (!pttoMaterial) { 376 G4cout << "Material " << mat << " is not f 377 } 378 else if (pttoMaterial != fTarget2Material) { 379 fTarget2Material = pttoMaterial; 380 G4cout << "New target2 material " << mat < 381 if (fLogicTarget2) { 382 fLogicTarget2->SetMaterial(fTarget2Mater 383 } 384 G4RunManager::GetRunManager()->PhysicsHasB 385 } 386 } 387 388 //....oooOO0OOooo........oooOO0OOooo........oo 389 390 void DetectorConstruction::DumpGeometryParamet 391 { 392 G4cout << "================================= 393 G4cout << "# GammaTherapy Geometry 394 G4cout << "================================= 395 G4cout << " World width= " << fWorldZ / m 396 G4cout << " Window width= " << fWindowZ / 397 << " mm:" << G4endl; 398 G4cout << " TargetV width= " << fTargetVolu 399 << " mm position = " << fTargetVolum 400 G4cout << " Target1 width= " << fTarget1Z / 401 << " mm:" << G4endl; 402 G4cout << " Target2 width= " << fTarget2Z / 403 << " mm:" << G4endl; 404 G4cout << " Gas width= " << fGasVolumeZ 405 << " mm:" << G4endl; 406 G4cout << " Mylar width= " << fMylarVolum 407 << " mm:" << G4endl; 408 G4cout << " Check width= " << fCheckVolum 409 << " mm position = " << fCheckVol 410 G4cout << " Air width= " << fAirZ / mm 411 G4cout << " Phantom width= " << fPhantomZ / 412 << " mm:" << G4endl; 413 G4cout << " Absorb width= " << fAbsorberZ 414 << " mm:" << G4endl; 415 G4cout << " Absorb shift= " << fShiftZPh / 416 G4cout << " Target1 " << fTarget1Mat 417 G4cout << " Target2 " << fTarget2Mat 418 G4cout << " Phantom " << fAbsorberMa 419 G4cout << "================================= 420 } 421