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 // Hadrontherapy advanced example for Geant4 27 // See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy 28 29 #include "globals.hh" 30 #include "G4SystemOfUnits.hh" 31 #include "G4Box.hh" 32 #include "G4Tubs.hh" 33 #include "G4UnionSolid.hh" 34 #include "G4Trd.hh" 35 #include "G4AssemblyVolume.hh" 36 #include "G4VisAttributes.hh" 37 #include "G4Colour.hh" 38 #include "G4RunManager.hh" 39 #include "G4LogicalVolume.hh" 40 #include "G4PVPlacement.hh" 41 #include "G4PVReplica.hh" 42 #include "G4RotationMatrix.hh" 43 #include "G4NistManager.hh" 44 #include "G4NistElementBuilder.hh" 45 #include "HadrontherapyDetectorConstruction.hh" 46 #include "HadrontherapyTIFPAPassiveProtonBeamLine.hh" 47 #include "HadrontherapyTIFPAPassiveProtonBeamLineMessenger.hh" 48 49 ///////////////////////////////////////////////////////////////////////////// 50 TrentoPassiveProtonBeamLine::TrentoPassiveProtonBeamLine(): 51 logicTreatmentRoom(0), physicalTreatmentRoom(0),hadrontherapyDetectorConstruction(0), 52 physiBeamLineSupport(0), physiBeamLineCover(0), physiBeamLineCover2(0), 53 physiMonitorLayer1(0), physiMonitorLayer2(0), 54 ScatteringFoil(0), logicScatteringFoil(0), physiScatteringFoil(0), ridgeFilterPhys(0), preCollimator(0), physiPreCollimator(0), Collimator(0), physiCollimator(0), solidAirTube(0), solidAirPreTube(0), physiAirTube(0), physiAirPreTube(0) 55 56 57 { 58 // Messenger to change parameters of the passiveTrentoBeamLine geometry 59 TrentoPassiveMessenger = new TrentoPassiveProtonBeamLineMessenger(this); 60 61 //***************************** PW *********************************** 62 static G4String ROGeometryName = "DetectorROGeometry"; 63 RO = new HadrontherapyDetectorROGeometry(ROGeometryName); 64 65 G4cout << "Going to register Parallel world..."; 66 RegisterParallelWorld(RO); 67 G4cout << "... done" << G4endl; 68 //******************************************************************** 69 70 } 71 ///////////////////////////////////////////////////////////////////////////// 72 TrentoPassiveProtonBeamLine::~TrentoPassiveProtonBeamLine() 73 { 74 delete TrentoPassiveMessenger; 75 delete hadrontherapyDetectorConstruction; 76 } 77 78 using namespace std; 79 80 ///////////////////////////////////////////////////////////////////////////// 81 G4VPhysicalVolume* TrentoPassiveProtonBeamLine::Construct() 82 { 83 // Sets default geometry and materials 84 SetDefaultDimensions(); 85 86 // Construct the whole Passive Beam Line 87 ConstructTrentoPassiveProtonBeamLine(); 88 89 //***************************** PW *************************************** 90 if (!hadrontherapyDetectorConstruction) 91 92 // HadrontherapyDetectorConstruction builds ONLY the phantom and the detector with its associated ROGeometry 93 hadrontherapyDetectorConstruction = new HadrontherapyDetectorConstruction(physicalTreatmentRoom); 94 95 96 //******************************************************************** 97 98 hadrontherapyDetectorConstruction->InitializeDetectorROGeometry(RO,hadrontherapyDetectorConstruction->GetDetectorToWorldPosition()); 99 100 return physicalTreatmentRoom; 101 } 102 103 // In the following method the DEFAULTS used in the geometry of 104 // passive beam line are provided 105 // HERE THE USER CAN CHANGE THE GEOMETRY CHARACTERISTICS OF BEAM 106 // LINE ELEMENTS, ALTERNATIVELY HE/SHE CAN USE THE MACRO FILE (IF A 107 // MESSENGER IS PROVIDED) 108 // 109 // DEFAULT MATERIAL ARE ALSO PROVIDED 110 // and COLOURS ARE ALSO DEFINED 111 // ---------------------------------------------------------- 112 ///////////////////////////////////////////////////////////////////////////// 113 void TrentoPassiveProtonBeamLine::SetDefaultDimensions() 114 { 115 // Set of coulors that can be used 116 white = new G4VisAttributes( G4Colour()); 117 white -> SetVisibility(true); 118 white -> SetForceSolid(true); 119 120 blue = new G4VisAttributes(G4Colour(0. ,0. ,1.)); 121 blue -> SetVisibility(true); 122 blue -> SetForceSolid(true); 123 124 gray = new G4VisAttributes( G4Colour(0.5, 0.5, 0.5 )); 125 gray-> SetVisibility(true); 126 gray-> SetForceSolid(true); 127 128 red = new G4VisAttributes(G4Colour(1. ,0. ,0.)); 129 red-> SetVisibility(true); 130 red-> SetForceSolid(true); 131 132 yellow = new G4VisAttributes(G4Colour(1., 1., 0. )); 133 yellow-> SetVisibility(true); 134 yellow-> SetForceSolid(true); 135 136 green = new G4VisAttributes( G4Colour(25/255. , 255/255. , 25/255. )); 137 green -> SetVisibility(true); 138 green -> SetForceSolid(true); 139 140 darkGreen = new G4VisAttributes( G4Colour(0/255. , 100/255. , 0/255. )); 141 darkGreen -> SetVisibility(true); 142 darkGreen -> SetForceSolid(true); 143 144 darkOrange3 = new G4VisAttributes( G4Colour(205/255. , 102/255. , 000/255. )); 145 darkOrange3 -> SetVisibility(true); 146 darkOrange3 -> SetForceSolid(false); 147 148 skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. )); 149 skyBlue -> SetVisibility(true); 150 skyBlue -> SetForceSolid(true); 151 152 153 154 // SCATTERING FOIL: it is a thin foil that provides the 155 // final diffusion of the beam. 156 G4double defaultScatteringFoilXSize = 0.75*cm; 157 ScatteringFoilXSize = defaultScatteringFoilXSize; 158 159 G4double defaultScatteringFoilYSize = 100*mm; 160 ScatteringFoilYSize = defaultScatteringFoilYSize; 161 162 G4double defaultScatteringFoilZSize = 100 *mm; 163 ScatteringFoilZSize = defaultScatteringFoilZSize; 164 165 G4double defaultScatteringFoilXPosition = -273.*cm; 166 ScatteringFoilXPosition = defaultScatteringFoilXPosition; 167 168 G4double defaultScatteringFoilYPosition = 0 *mm; 169 ScatteringFoilYPosition = defaultScatteringFoilYPosition; 170 171 G4double defaultScatteringFoilZPosition = 0 *mm; 172 ScatteringFoilZPosition = defaultScatteringFoilZPosition; 173 174 //PRE COLLIMATOR: it is a PMMA collimator 175 G4double defaultPreCollimatorXHalfSide = 12.5 * cm; 176 preCollimatorXHalfSide = defaultPreCollimatorXHalfSide; 177 178 G4double defaultPreCollimatorXPosition = -50.*cm; 179 preCollimatorXPosition = defaultPreCollimatorXPosition; 180 181 //DEFAULT DEFINITION OF THE AIR TUBE 182 G4double defaultYHalfSideAirTube= 5.*cm; 183 YHalfSideAirTube = defaultYHalfSideAirTube; 184 185 G4double defaultZHalfSideAirTube = 5.*cm; 186 ZHalfSideAirTube = defaultZHalfSideAirTube; 187 188 189 // DEFAULT DEFINITION OF THE MATERIALS 190 // All elements and compound definition follows the NIST database 191 192 // ELEMENTS 193 G4bool isotopes = false; 194 G4Material* aluminumNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Al", isotopes); 195 G4Material* copperNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu", isotopes); 196 G4Element* zincNist = G4NistManager::Instance()->FindOrBuildElement("Zn"); 197 G4Element* copper = G4NistManager::Instance()->FindOrBuildElement("Cu"); 198 G4Element* silicNist = G4NistManager::Instance()->FindOrBuildElement("Si"); 199 G4Element* hydrogenNist = G4NistManager::Instance()->FindOrBuildElement("H"); 200 G4Element* oxygenNist = G4NistManager::Instance()->FindOrBuildElement("O"); 201 G4Element* carbonNist = G4NistManager::Instance()->FindOrBuildElement("C"); 202 203 // COMPOUND 204 G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes); 205 G4Material* PMMANist = G4NistManager::Instance()->FindOrBuildMaterial("G4_PLEXIGLASS", isotopes); 206 G4Material* MylarNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_MYLAR"); 207 208 G4int nComponents; // Number of components 209 G4int nAtoms; //Number of atoms 210 G4double fractionmass; // Fraction in mass of an element in a material 211 212 //Quartz 213 G4Material* SiO2 = new G4Material("quartz", 2.200*g/cm3, nComponents=2); 214 SiO2->AddElement(silicNist, nAtoms=1); 215 SiO2->AddElement(oxygenNist , nAtoms=2); 216 217 //Epoxy (for FR4 ) 218 G4Material* Epoxy = new G4Material("Epoxy" , 1.2*g/cm3, nComponents=2); 219 Epoxy->AddElement(hydrogenNist, nAtoms=2); 220 Epoxy->AddElement(carbonNist, nAtoms=2); 221 222 //FR4 (Glass + Epoxy) 223 G4Material* FR4 = new G4Material("FR4" , 1.86*g/cm3, nComponents=2); 224 FR4->AddMaterial(SiO2, fractionmass=0.528); 225 FR4->AddMaterial(Epoxy, fractionmass=0.472); 226 227 //Brass 228 G4Material* brass = new G4Material("Brass", 8.40*g/cm3, nComponents=2); 229 brass -> AddElement(zincNist, fractionmass = 30 *perCent); 230 brass -> AddElement(copper, fractionmass = 70 *perCent); 231 232 //Plastic 233 G4Material* plastic = new G4Material("Plastic", 1.40*g/cm3, nComponents=3); 234 plastic -> AddElement(carbonNist, nAtoms = 21); 235 plastic -> AddElement(oxygenNist, nAtoms = 4); 236 plastic -> AddElement(hydrogenNist, nAtoms = 24); 237 238 239 //***************************** PW *************************************** 240 241 // DetectorROGeometry Material 242 new G4Material("dummyMat", 1., 1.*g/mole, 1.*g/cm3); 243 244 245 // MATERIAL ASSIGNMENT 246 // Support of the beam line 247 beamLineSupportMaterial = aluminumNist; 248 249 // Matreial of the monitor chamber 250 layerMonitorChamberMaterial = MylarNist; 251 layerDefaultMaterial = airNist; 252 internalStructureMaterial = FR4; 253 FoilMaterial = copperNist; 254 airgapMaterial = airNist; 255 256 // Material of the scattering foil 257 ScatteringFoilMaterial = copperNist; 258 259 //Material of the ridge filter 260 singleTrapMaterial = plastic; 261 262 // Materials of the collimators 263 preCollimatorMaterial = PMMANist; 264 CollimatorMaterial = brass; 265 266 // Material of the final brass tube 267 airTubeMaterial = airTube2Material = airTube3Material = airNist; 268 269 } 270 271 ///////////////////////////////////////////////////////////////////////////// 272 void TrentoPassiveProtonBeamLine::ConstructTrentoPassiveProtonBeamLine() 273 { 274 // ----------------------------- 275 // Treatment room - World volume 276 //------------------------------ 277 // Treatment room sizes 278 const G4double worldX = 400.0 *cm; 279 const G4double worldY = 400.0 *cm; 280 const G4double worldZ = 400.0 *cm; 281 G4bool isotopes = false; 282 283 G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes); 284 285 G4Box* treatmentRoom = new G4Box("TreatmentRoom", 286 worldX, 287 worldY, 288 worldZ); 289 290 logicTreatmentRoom = new G4LogicalVolume(treatmentRoom, 291 airNist, 292 "logicTreatmentRoom", 293 0,0,0); 294 295 physicalTreatmentRoom = new G4PVPlacement(0, 296 G4ThreeVector(), 297 "physicalTreatmentRoom", 298 logicTreatmentRoom, 299 0, 300 false, 301 0); 302 303 304 // The treatment room is invisible in the Visualisation 305 logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::GetInvisible()); 306 307 // Components of the Passive Proton Beam Line 308 HadrontherapyBeamLineSupport(); 309 HadrontherapyBeamMonitoring(); 310 HadrontherapyBeamScatteringFoils(); 311 HadrontherapyRidgeFilter(); 312 HadrontherapyBeamCollimators(); 313 314 } 315 316 ///////////////////////////////////////////////////////////////////////////// 317 void TrentoPassiveProtonBeamLine::HadrontherapyBeamLineSupport() 318 { 319 // ------------------// 320 // BEAM LINE SUPPORT // 321 //-------------------// 322 const G4double beamLineSupportXSize = 1.2*m; 323 const G4double beamLineSupportYSize = 20.*mm; 324 const G4double beamLineSupportZSize = 600.*mm; 325 326 const G4double beamLineSupportXPosition = -1745.09 *mm; 327 const G4double beamLineSupportYPosition = -230. *mm; 328 const G4double beamLineSupportZPosition = 0.*mm; 329 330 G4Box* beamLineSupport = new G4Box("BeamLineSupport", 331 beamLineSupportXSize, 332 beamLineSupportYSize, 333 beamLineSupportZSize); 334 335 G4LogicalVolume* logicBeamLineSupport = new G4LogicalVolume(beamLineSupport, 336 beamLineSupportMaterial, 337 "BeamLineSupport"); 338 339 physiBeamLineSupport = new G4PVPlacement(0, G4ThreeVector(beamLineSupportXPosition, 340 beamLineSupportYPosition, 341 beamLineSupportZPosition), 342 "BeamLineSupport", 343 logicBeamLineSupport, 344 physicalTreatmentRoom, 345 false, 346 0); 347 348 // Visualisation attributes of the beam line support 349 logicBeamLineSupport -> SetVisAttributes(gray); 350 351 //---------------------------------// 352 // Beam line cover 1 (left panel) // 353 //---------------------------------// 354 const G4double beamLineCoverXSize = 1.2*m; 355 const G4double beamLineCoverYSize = 750.*mm; 356 const G4double beamLineCoverZSize = 10.*mm; 357 358 const G4double beamLineCoverXPosition = -1745.09 *mm; 359 const G4double beamLineCoverYPosition = -1000.*mm; 360 const G4double beamLineCoverZPosition = 600.*mm; 361 362 G4Box* beamLineCover = new G4Box("BeamLineCover", 363 beamLineCoverXSize, 364 beamLineCoverYSize, 365 beamLineCoverZSize); 366 367 G4LogicalVolume* logicBeamLineCover = new G4LogicalVolume(beamLineCover, 368 beamLineSupportMaterial, 369 "BeamLineCover"); 370 371 physiBeamLineCover = new G4PVPlacement(0, G4ThreeVector(beamLineCoverXPosition, 372 beamLineCoverYPosition, 373 beamLineCoverZPosition), 374 "BeamLineCover", 375 logicBeamLineCover, 376 physicalTreatmentRoom, 377 false, 378 0); 379 380 // ---------------------------------// 381 // Beam line cover 2 (rigth panel) // 382 // ---------------------------------// 383 // It has the same characteristic of beam line cover 1 but set in a different position 384 physiBeamLineCover2 = new G4PVPlacement(0, G4ThreeVector(beamLineCoverXPosition, 385 beamLineCoverYPosition, 386 - beamLineCoverZPosition), 387 "BeamLineCover2", 388 logicBeamLineCover, 389 physicalTreatmentRoom, 390 false, 391 0); 392 393 logicBeamLineCover -> SetVisAttributes(blue); 394 } 395 396 ///////////////////////////////////////////////////////////////////////////// 397 void TrentoPassiveProtonBeamLine::HadrontherapyBeamMonitoring() 398 { 399 // ---------------------------- 400 // MONITOR CHAMBER 401 // ---------------------------- 402 // The monitor chamber is a ionisation chamber 403 // Each chamber consist in a sequence of 2 mm of air and 404 // 8 microm copper layers which contain 800 microm of Fr4 in a box 405 // that has the two layer of Mylar 406 407 408 //////////////////////////////////////////// 409 ///External Structure of the Monitor Chamber 410 //////////////////////////////////////////// 411 412 const G4double monitorXSize = 12.*um; 413 const G4double monitorYSize = 12.7*cm; 414 const G4double monitorZSize = 12.7*cm; 415 416 const G4double shift = 17.*cm; 417 418 const G4double monitorlayer1XPosition = -269.*cm +shift; 419 const G4double monitorlayer2XPosition = -270.4104*cm +shift; 420 421 422 // First Mylar layer of the monitor chamber 423 G4Box* solidMonitorLayer1 = new G4Box("MonitorLayer1", 424 monitorXSize/2, 425 monitorYSize/2, 426 monitorZSize/2); 427 428 G4LogicalVolume* logicMonitorLayer1 = new G4LogicalVolume(solidMonitorLayer1, 429 layerMonitorChamberMaterial, 430 "MonitorLayer1"); 431 432 physiMonitorLayer1 = new G4PVPlacement(0, 433 G4ThreeVector(monitorlayer1XPosition, 0.*cm, 0.*cm), 434 "MonitorLayer1", 435 logicMonitorLayer1, 436 physicalTreatmentRoom, 437 false, 438 0); 439 440 // Second Mylar layer of the monitor chamber 441 G4Box* solidMonitorLayer2 = new G4Box("MonitorLayer2", 442 monitorXSize/2, 443 monitorYSize/2, 444 monitorZSize/2); 445 446 G4LogicalVolume* logicMonitorLayer2 = new G4LogicalVolume(solidMonitorLayer2, 447 layerMonitorChamberMaterial, 448 "MonitorLayer2"); 449 450 physiMonitorLayer2 = new G4PVPlacement(0, 451 G4ThreeVector(monitorlayer2XPosition, 0.*cm, 0.*cm), 452 "MonitorLayer2", 453 logicMonitorLayer2, 454 physicalTreatmentRoom, 455 false, 456 0); 457 458 logicMonitorLayer1 -> SetVisAttributes(gray); 459 logicMonitorLayer2 -> SetVisAttributes(gray); 460 461 462 /////////////////////////////////////////// 463 // Internal Structure of the Monitor Chamber 464 //////////////////////////////////////////// 465 466 const G4double layerThickness = 816*um; 467 const G4double layerXposition = -270.2684*cm; 468 const G4int nofLayers = 5; 469 const G4double internalStructureThickness = 800.*um; 470 const G4double airGapThickness = 2.*mm; 471 const G4double foilThickness = 8.*um; 472 const G4double FirstCoppperLayerXPosition = -404.*um; 473 const G4double SecondCoppperLayerXPosition = 404.*um; 474 const G4double InternalStructureXPosition = 0.; 475 476 // Air Layer 477 G4VSolid* SolidAirLayer= new G4Box("Layer", 478 layerThickness, 479 monitorYSize/2, 480 monitorZSize/2); 481 482 new G4LogicalVolume(SolidAirLayer, 483 layerDefaultMaterial, 484 "Layer"); 485 486 487 488 // First Copper Layer 489 G4VSolid* SolidFirstCoppperLayer = new G4Box("SolidFirstCoppperLayer", 490 foilThickness/2, 491 monitorYSize/2, 492 monitorZSize/2); 493 494 G4LogicalVolume* LogicFirstCoppperLayer = new G4LogicalVolume( 495 SolidFirstCoppperLayer, 496 FoilMaterial, 497 "SolidFirstCoppperLayer"); 498 499 500 // Fr4 Internal Layer 501 G4VSolid* SolidInternalStructure = new G4Box("SolidInternalStructure", 502 internalStructureThickness/2, 503 monitorYSize/2, 504 monitorZSize/2); 505 506 G4LogicalVolume* LogicInternalStructure = new G4LogicalVolume( 507 SolidInternalStructure, 508 internalStructureMaterial, 509 "SolidInternalStructure"); 510 511 512 513 // Second Copper Layer 514 G4VSolid* SolidSecondCoppperLayer = new G4Box("SolidSecondCoppperLayer", 515 foilThickness/2, 516 monitorYSize/2, 517 monitorZSize/2); // its size 518 519 G4LogicalVolume* LogicSecondCoppperLayer= new G4LogicalVolume( 520 SolidSecondCoppperLayer, 521 FoilMaterial, 522 "SolidSecondCoppperLayer"); 523 524 525 G4RotationMatrix Ra, Rm; 526 G4ThreeVector Ta; 527 G4Transform3D Tr; 528 G4AssemblyVolume* assemblyMonitor = new G4AssemblyVolume(); 529 530 531 Ta.setX(FirstCoppperLayerXPosition); Ta.setY(0.); Ta.setZ(0.); 532 Tr = G4Transform3D(Ra,Ta); 533 assemblyMonitor->AddPlacedVolume(LogicFirstCoppperLayer, Tr); 534 535 Ta.setX(InternalStructureXPosition); Ta.setY(0.); Ta.setZ(0.); 536 Tr = G4Transform3D(Ra,Ta); 537 assemblyMonitor->AddPlacedVolume(LogicInternalStructure, Tr ); 538 539 Ta.setX(SecondCoppperLayerXPosition); Ta.setY(0.); Ta.setZ(0.); 540 Tr = G4Transform3D(Ra,Ta); 541 542 assemblyMonitor->AddPlacedVolume(LogicSecondCoppperLayer, Tr ); 543 544 545 for( unsigned int i = 0; i<nofLayers; i++ ) 546 { 547 G4ThreeVector Tm(shift+layerXposition + i*(airGapThickness), 0., 0.); 548 Tr = G4Transform3D(Rm,Tm); 549 assemblyMonitor -> MakeImprint(logicTreatmentRoom, Tr); 550 } 551 552 } 553 554 555 void TrentoPassiveProtonBeamLine::HadrontherapyBeamScatteringFoils() 556 { 557 558 // ---------------------------// 559 // SCATTERING FOIL // 560 // ---------------------------// 561 // It is a metal foil and provides the 562 // initial diffusion of the beam. 563 564 565 566 ScatteringFoil = new G4Box("ScatteringFoil", 567 ScatteringFoilXSize, 568 ScatteringFoilYSize, 569 ScatteringFoilZSize); 570 571 572 logicScatteringFoil = new G4LogicalVolume(ScatteringFoil, 573 ScatteringFoilMaterial, 574 "ScatteringFoil"); 575 576 physiScatteringFoil = new G4PVPlacement(0, G4ThreeVector(ScatteringFoilXPosition, 577 ScatteringFoilYPosition, 578 ScatteringFoilZPosition), 579 "SeconScatteringFoil", 580 logicScatteringFoil, 581 physicalTreatmentRoom, 582 false, 583 0); 584 585 logicScatteringFoil -> SetVisAttributes(skyBlue); 586 } 587 588 void TrentoPassiveProtonBeamLine::HadrontherapyRidgeFilter() 589 { 590 // ---------------------------- // 591 // THE Ridge Filter // 592 // -----------------------------// 593 // Energy degreader of 594 // primary beam. Made of a series of pin-substructures. 595 596 597 G4double ridgeXPosition = -200*cm; 598 599 const G4double XBase = 0.1 *mm; 600 const G4double YBase = 38.75*mm; 601 602 G4VSolid* RidgeBase = new G4Box("Base_RidgeFilter", 603 XBase, 604 YBase, 605 YBase); 606 607 G4LogicalVolume* RidgeBaseLog = new G4LogicalVolume(RidgeBase, 608 singleTrapMaterial, 609 "Base_RidgeFilter"); 610 611 new G4PVPlacement(0, 612 G4ThreeVector( 613 -199.7*cm, 614 0., 615 0.), 616 "Base_RidgeFilter", 617 RidgeBaseLog, 618 physicalTreatmentRoom, 619 false, 620 0); 621 622 RidgeBaseLog->SetVisAttributes(yellow); 623 624 625 626 G4double x0 = 1.215*mm; 627 G4double x1 = 1*mm; 628 G4double x2 = 0.95*mm; 629 G4double x3 = 0.87*mm; 630 G4double x4 = 0.76*mm; 631 G4double x5 = 0.71*mm; 632 G4double x6 = 0.65*mm; 633 G4double x7 = 0.56*mm; 634 G4double x8 = 0.529*mm; 635 G4double x9 = 0.258*mm; 636 G4double x10 = 0.225*mm; 637 G4double x11 = 0.144*mm; 638 G4double x12 = 0.055*mm; 639 640 G4double heigth = 0.13*mm; 641 G4double heigth0 = 0.11*mm; 642 G4double heigth1 = 2.3*mm; 643 G4double heigth2 = 0.65*mm; 644 G4double heigth3 = 1.9*mm; 645 G4double heigth4 = 0.615*mm; 646 G4double heigth5 = 2.23*mm; 647 G4double heigth6 = 0.3*mm; 648 G4double heigth7 = 4.1*mm; 649 G4double heigth8 = 0.1*mm; 650 G4double heigth9 = 0.105*mm; 651 G4double heigth10 = 0.065*mm; 652 653 G4VSolid* Trap00 = new G4Trd("singleTrap00", x0, x1, x0, x1, heigth); 654 G4VSolid* Trap0 = new G4Trd("singleTrap0", x1, x2, x1, x2, heigth0); 655 G4VSolid* Trap1 = new G4Trd("singleTrap1", x2, x3, x2, x3, heigth1); 656 G4VSolid* Trap2 = new G4Trd("singleTrap2", x3, x4, x3, x4, heigth2); 657 G4VSolid* Trap3 = new G4Trd("singleTrap3", x4, x5, x4, x5, heigth3); 658 G4VSolid* Trap4 = new G4Trd("singleTrap4", x5, x6, x5, x6, heigth4); 659 G4VSolid* Trap5 = new G4Trd("singleTrap5", x6, x7, x6, x7, heigth5); 660 G4VSolid* Trap6 = new G4Trd("singleTrap6", x7, x8, x7, x8, heigth6); 661 G4VSolid* Trap7 = new G4Trd("singleTrap7", x8, x9, x8, x9, heigth7); 662 G4VSolid* Trap8 = new G4Trd("singleTrap8", x9, x10, x9, x10, heigth8); 663 G4VSolid* Trap9 = new G4Trd("singleTrap9", x10, x11, x10, x11, heigth9); 664 G4VSolid* Trap10 = new G4Trd("singleTrap10", x11, x12, x11, x12, heigth10); 665 666 667 G4ThreeVector tr0(0., 0., 0.24); 668 G4ThreeVector tr1(0., 0., 2.54); 669 G4ThreeVector tr2(0., 0., 2.55); 670 G4ThreeVector tr3(0., 0., 2.845); 671 G4ThreeVector tr4(0., 0., 4.4); 672 673 G4RotationMatrix* yRot = new G4RotationMatrix; 674 yRot->rotateY(0); 675 G4UnionSolid* unionTrap00 = new G4UnionSolid("Trap01", Trap00, Trap0, yRot, tr0); 676 G4UnionSolid* unionTrap01 = new G4UnionSolid("Trap01", unionTrap00, Trap1, yRot, tr1); 677 G4UnionSolid* unionTrap23 = new G4UnionSolid("Trap23", Trap2, Trap3, yRot, tr2); 678 G4UnionSolid* unionTrap45 = new G4UnionSolid("Trap45", Trap4, Trap5, yRot, tr3); 679 G4UnionSolid* unionTrap67 = new G4UnionSolid("Trap67", Trap6, Trap7, yRot, tr4); 680 681 G4ThreeVector tr03(0., 0., 5.09); 682 G4UnionSolid* unionTrap03 = new G4UnionSolid("unionTrap03", unionTrap01, unionTrap23, yRot, tr03); 683 684 G4ThreeVector tr05(0., 0., 7.935); 685 G4UnionSolid* unionTrap05 = new G4UnionSolid("unionTrap05", unionTrap03, unionTrap45, yRot, tr05); 686 687 G4ThreeVector tr_blocco1(0., 0., 12.335); 688 G4UnionSolid* unionTrap_blocco1 = new G4UnionSolid("unionTrap_blocco1", unionTrap05, unionTrap67, yRot, tr_blocco1); 689 690 G4ThreeVector tr_blocco2( 0., 0., 12.435); 691 G4UnionSolid* unionTrap_blocco2 = new G4UnionSolid("unionTrap_blocco2", unionTrap_blocco1, Trap8, yRot, tr_blocco2); 692 693 G4ThreeVector tr_blocco3(0., 0., 12.54); 694 G4UnionSolid* unionTrap_blocco3 = new G4UnionSolid("unionTrap_blocco3", unionTrap_blocco2, Trap9, yRot, tr_blocco3); 695 696 G4ThreeVector tr_tot( 0., 0., 12.605); 697 G4UnionSolid* unionTrap = new G4UnionSolid("unionTrap", unionTrap_blocco3, Trap10, yRot, tr_tot); 698 699 700 G4LogicalVolume* singleTrapLog = new G4LogicalVolume(unionTrap, singleTrapMaterial, "singleTrap"); 701 702 703 singleTrapLog->SetVisAttributes(yellow); 704 705 706 G4int numberOfLayers = 31; 707 G4double minZ = -37.5*mm; 708 G4double minY = -37.5*mm; 709 G4double sum_space = 1.25*mm; 710 711 vector<G4ThreeVector> singleTrapPositions; 712 713 for (int i = 0; i < numberOfLayers; i++) 714 { 715 for (int j = 0; j < numberOfLayers; j++) 716 { 717 singleTrapPositions.push_back({-0.01*cm+ridgeXPosition, 718 minY + 2*i*sum_space, 719 minZ + 2*j*sum_space,}); 720 } 721 } 722 723 G4double ti = - 90. *deg; 724 G4RotationMatrix rt; 725 rt.rotateY(ti); 726 727 G4int peaks = numberOfLayers*numberOfLayers; 728 for (int i = 0; i < peaks; i++) 729 { 730 731 ostringstream tName;tName << "singleTrap" << i; 732 new G4PVPlacement(G4Transform3D(rt, 733 singleTrapPositions[i]), 734 singleTrapLog, 735 "tName.str()", 736 logicTreatmentRoom, 737 0, 738 i); 739 740 } 741 742 743 } 744 745 void TrentoPassiveProtonBeamLine::HadrontherapyBeamCollimators() 746 { 747 748 // ------------------------// 749 // PRE - COLLIMATOR // 750 // -----------------------// 751 // It is a plastic collimator to limit neutron dose and reduce activation 752 753 const G4double preCollimatorYHalfSide = 10.*cm; 754 const G4double preCollimatorZHalfSide = 10.*cm; 755 756 preCollimator = new G4Box("PreCollimator", 757 preCollimatorXHalfSide, 758 preCollimatorYHalfSide, 759 preCollimatorZHalfSide); 760 761 762 G4LogicalVolume* logicPreCollimator = new G4LogicalVolume(preCollimator, 763 preCollimatorMaterial, 764 "PreCollimator"); 765 766 767 physiPreCollimator = new G4PVPlacement(0, 768 G4ThreeVector( 769 -50.*cm, 770 0., 771 0.), 772 "PreCollimator", 773 logicPreCollimator, 774 physicalTreatmentRoom, 775 false, 776 0); 777 778 779 780 logicPreCollimator -> SetVisAttributes(white); 781 782 783 // -----------------// 784 // COLLIMATOR // 785 // -----------------// 786 // It is a brass collimator 787 788 789 G4double collimatorYHalfSide = 10.*cm; 790 G4double collimatorZHalfSide = 10.*cm; 791 G4double collimatorXHalfSide = 3.25*cm; 792 793 G4double CollimatorXPosition = -34.25*cm; 794 795 Collimator = new G4Box("Collimator", 796 collimatorXHalfSide, 797 collimatorYHalfSide, 798 collimatorZHalfSide); 799 800 801 G4LogicalVolume* logicCollimator = new G4LogicalVolume(Collimator, 802 CollimatorMaterial, 803 "Collimator"); 804 805 806 807 physiCollimator = new G4PVPlacement(0, G4ThreeVector(CollimatorXPosition, 808 0., 809 0.), 810 "Collimator", 811 logicCollimator, 812 physicalTreatmentRoom, 813 false, 814 0); 815 816 817 818 logicCollimator -> SetVisAttributes(darkGreen); 819 820 821 822 // ---------------------------------// 823 // AIR BOX Collimator // 824 // ---------------------------------// 825 826 827 solidAirTube = new G4Box("AirTube", 828 collimatorXHalfSide, 829 YHalfSideAirTube, 830 ZHalfSideAirTube); 831 832 G4LogicalVolume* logicAirTube = new G4LogicalVolume(solidAirTube, 833 airTubeMaterial, 834 "AirTube", 835 0, 0, 0); 836 837 838 physiAirTube = new G4PVPlacement(0, G4ThreeVector(0, 839 0., 840 0.), 841 "AirTube", 842 logicAirTube, 843 physiCollimator, 844 false, 845 0); 846 847 logicAirTube -> SetVisAttributes(darkOrange3); 848 849 850 851 // // ---------------------------------// 852 // // AIR BOX PreCollimator // 853 // // ---------------------------------// 854 855 856 solidAirPreTube = new G4Box("AirPreTube", 857 preCollimatorXHalfSide, 858 YHalfSideAirTube, 859 ZHalfSideAirTube); 860 861 G4LogicalVolume* logicAirPreTube = new G4LogicalVolume(solidAirPreTube, 862 airTubeMaterial, 863 "AirPreTube", 864 0, 0, 0); 865 866 867 physiAirPreTube = new G4PVPlacement(0, 868 G4ThreeVector(0, 869 0., 870 0.), 871 "AirPreTube", 872 logicAirPreTube, 873 physiPreCollimator, 874 false, 875 0); 876 877 logicAirPreTube -> SetVisAttributes(darkOrange3); 878 879 880 881 } 882 883 884 ///////////////////////////////////////////////////////////////////////////// 885 /////////////////////////// MESSENGER /////////////////////////////////////// 886 ///////////////////////////////////////////////////////////////////////////// 887 888 889 void TrentoPassiveProtonBeamLine::SetScatteringFoilXSize(G4double value) 890 { 891 ScatteringFoil -> SetXHalfLength(value); 892 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 893 G4cout <<"The X size of the second scattering foil is (mm):"<< 894 ((ScatteringFoil -> GetXHalfLength())*2.)/mm 895 << G4endl; 896 } 897 898 899 void TrentoPassiveProtonBeamLine::SetPreCollimatorXSize(G4double value) 900 { 901 preCollimator -> SetXHalfLength(value); 902 G4cout<<"The size of the pre collimator is (mm)" 903 << ((preCollimator -> GetXHalfLength())*2)/mm << G4endl; 904 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 905 906 } 907 908 void TrentoPassiveProtonBeamLine::SetPreCollimatorXPosition(G4double value) 909 { 910 physiPreCollimator -> SetTranslation(G4ThreeVector(value, 0., 0.)); 911 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 912 G4cout <<" The pre collimator is translated to" << value/mm <<"mm along the X axis" << G4endl; 913 914 } 915 916 void TrentoPassiveProtonBeamLine::SetAirTubeYSize(G4double value) 917 { 918 solidAirTube -> SetYHalfLength(value); 919 G4cout<<"The y side of brass tube is (mm)" 920 << ((preCollimator -> GetYHalfLength())*2) << G4endl; 921 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 922 } 923 924 925 void TrentoPassiveProtonBeamLine::SetAirTubeZSize(G4double value) 926 { 927 solidAirTube -> SetZHalfLength(value); 928 G4cout<<"The z side of the brass tube is (mm)" 929 << ((Collimator -> GetZHalfLength())*2) << G4endl; 930 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 931 932 } 933 934 935 ///////////////////////////////////////////////////////////////////////////// 936 void TrentoPassiveProtonBeamLine::SetScattererMaterial(G4String materialChoice) 937 { 938 if (G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice, false) ) 939 { 940 if (pttoMaterial) 941 { 942 ScatteringFoilMaterial = pttoMaterial; 943 logicScatteringFoil -> SetMaterial(pttoMaterial); 944 G4cout << "The material of the Scatterer has been changed to " << materialChoice << G4endl; 945 } 946 } 947 else 948 { 949 G4cout << "WARNING: material \"" << materialChoice << "\" doesn't exist in NIST elements/materials" 950 " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl; 951 G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl; 952 } 953 } 954