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 // This is the *BASIC* version of Hadrontherapy, a Geant4-based application 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 28 // 29 // Visit the Hadrontherapy web site (http://www.lns.infn.it/link/Hadrontherapy) to request 30 // the *COMPLETE* version of this program, together with its documentation; 31 // Hadrontherapy (both basic and full version) are supported by the Italian INFN 32 // Institute in the framework of the MC-INFN Group 33 // 34 35 #include <fstream> 36 37 #include "globals.hh" 38 #include "G4SystemOfUnits.hh" 39 #include "G4Material.hh" 40 #include "G4Tubs.hh" 41 #include "G4Box.hh" 42 #include "G4LogicalVolume.hh" 43 #include "G4VPhysicalVolume.hh" 44 #include "G4ThreeVector.hh" 45 #include "G4PVPlacement.hh" 46 #include "G4Transform3D.hh" 47 #include "G4RotationMatrix.hh" 48 #include "G4VisAttributes.hh" 49 #include "G4Colour.hh" 50 #include "HadrontherapyModulator.hh" 51 #include "G4Transform3D.hh" 52 #include "G4ios.hh" 53 #include "G4RunManager.hh" 54 #include "G4NistManager.hh" 55 #include <iostream> 56 57 HadrontherapyModulator::HadrontherapyModulator(): physiMotherMod(0), 58 solidMod1(0), logicMod1(0), physiMod1(0), 59 solidMod2(0), logicMod2(0), physiMod2(0), 60 solidMod3(0), logicMod3(0), physiMod3(0), 61 solidMod4(0), logicMod4(0), physiMod4(0), 62 FileName("Modulators/Modulator010.txt") 63 { 64 pi=4*std::atan(1.); 65 StepNumbers=22; 66 Weight=new G4double[StepNumbers]; 67 StepThickness=new G4double[StepNumbers]; 68 StartingAngle=new G4double[StepNumbers]; 69 SpanningAngle=new G4double[StepNumbers]; 70 PositionMod=new G4ThreeVector[StepNumbers]; 71 72 73 solidMod=new G4Tubs *[StepNumbers]; 74 logicMod=new G4LogicalVolume *[StepNumbers]; 75 physiMod=new G4VPhysicalVolume *[(4*(StepNumbers-1)+1)]; 76 77 for (G4int i=0;i<StepNumbers;i++) 78 { 79 Weight[i]=0; 80 StepThickness[i]=0; 81 StartingAngle[i]=0; 82 SpanningAngle[i]=0; 83 PositionMod[i]=G4ThreeVector(0,0,0); 84 solidMod[i]=0; 85 logicMod[i]=0; 86 87 } 88 89 for (G4int i=0;i<4*(StepNumbers-1)+1;i++) 90 { 91 physiMod[i]=0; 92 } 93 94 95 ModulatorMessenger = new HadrontherapyModulatorMessenger(this); 96 ModulatorDefaultProperties(); 97 rm = new G4RotationMatrix(); 98 G4double phi = 270. *deg; 99 rm -> rotateY(phi); 100 } 101 ///////////////////////////////////////////////////////////////////////////// 102 HadrontherapyModulator::~HadrontherapyModulator() 103 { 104 delete rm; 105 delete [] Weight; 106 delete [] StepThickness; 107 delete [] StartingAngle; 108 delete [] SpanningAngle; 109 delete [] PositionMod; 110 delete [] solidMod; 111 delete [] logicMod; 112 delete [] physiMod; 113 delete ModulatorMessenger; 114 } 115 116 ///////////////////////////////////////////////////////////////////////////// 117 void HadrontherapyModulator::ModulatorDefaultProperties() 118 { 119 /* Here we initialize the step properties of Modulator wheel, you can create your 120 specific modulator by changing the values in this class or writing them in an external 121 file and activate reading from file via a macrofile. */ 122 123 StepThickness[0]=0; Weight[0]=.14445; 124 StepThickness[1]=.8; Weight[1]=.05665; 125 StepThickness[2]=1.6; Weight[2]=.05049; 126 StepThickness[3]=2.4; Weight[3]=.04239; 127 StepThickness[4]=3.2; Weight[4]=.04313; 128 StepThickness[5]=4.0; Weight[5]=.03879; 129 StepThickness[6]=4.8; Weight[6]=.04182; 130 StepThickness[7]=5.6; Weight[7]=.03422; 131 StepThickness[8]=6.4; Weight[8]=.03469; 132 StepThickness[9]=7.2; Weight[9]=.03589; 133 StepThickness[10]=8.0; Weight[10]=.03633; 134 StepThickness[11]=8.8; Weight[11]=.03842; 135 StepThickness[12]=9.6; Weight[12]=.03688; 136 StepThickness[13]=10.4; Weight[13]=.03705; 137 StepThickness[14]=11.2; Weight[14]=.03773; 138 StepThickness[15]=12.0; Weight[15]=.03968; 139 StepThickness[16]=12.8; Weight[16]=.04058; 140 StepThickness[17]=13.6; Weight[17]=.03903; 141 StepThickness[18]=14.4; Weight[18]=.04370; 142 StepThickness[19]=15.2; Weight[19]=.03981; 143 StepThickness[20]=16.0; Weight[20]=.05226; 144 StepThickness[21]=16.8; Weight[21]=.03603; 145 GetStepInformation(); 146 147 } 148 ///////////////////////////////////////////////////////////////////////////// 149 void HadrontherapyModulator:: ModulatorPropertiesFromFile(G4String Name) 150 { 151 delete [] Weight; 152 delete [] StepThickness; 153 delete [] StartingAngle; 154 delete [] SpanningAngle; 155 delete [] PositionMod; 156 delete [] solidMod; 157 delete [] logicMod; 158 delete [] physiMod; 159 delete solidMod1; 160 delete logicMod1; 161 delete physiMod1; 162 delete solidMod2; 163 delete logicMod2; 164 delete physiMod2; 165 delete solidMod3; 166 delete logicMod3; 167 delete physiMod3; 168 delete solidMod4; 169 delete logicMod4; 170 delete physiMod4; 171 // The Modulator wheel properties is getting form an external file "ModoulWeight.txt" 172 File.open(Name, std::ios::in); 173 if(!File.is_open()) 174 { 175 G4cout<<" WARNING: The File with name of "<<Name<< 176 " doesn't exist to get modulator step properties. please modify it and try again"<<G4endl; 177 178 G4Exception("HadrontherapyModulator::ModulatorPropertiesFromFile( )", "Hadrontherapy0009" 179 , FatalException, "Error: No available external file for reading from"); 180 } 181 182 G4String string; 183 File >>string>> StepNumbers; 184 File >>string>>string>>string; 185 186 187 Weight=new G4double[StepNumbers]; 188 StepThickness=new G4double[StepNumbers]; 189 StartingAngle=new G4double[StepNumbers]; 190 SpanningAngle=new G4double[StepNumbers]; 191 PositionMod=new G4ThreeVector[StepNumbers]; 192 193 194 solidMod=new G4Tubs *[StepNumbers]; 195 logicMod=new G4LogicalVolume *[StepNumbers]; 196 physiMod=new G4VPhysicalVolume *[(4*(StepNumbers-1)+1)]; 197 198 for(G4int i=0;i<StepNumbers;i++) 199 { 200 G4String stringX; 201 File>>stringX>> StepThickness[i]>>Weight[i]; 202 } 203 204 GetStepInformation(); 205 BuildSteps(); 206 207 208 209 } 210 //////////////////////////////////////////////////////////////////////////////// 211 void HadrontherapyModulator::GetStepInformation() 212 { 213 214 G4double TotalWeight=0; 215 // convert the absolute weight values to relative ones 216 for(G4int i=0;i<StepNumbers;i++) 217 { 218 TotalWeight+=Weight[i]; 219 } 220 221 for(G4int i=0;i<StepNumbers;i++) 222 { 223 Weight[i]=Weight[i]/TotalWeight; 224 } 225 226 // To build the RMW step layers will be put one after another 227 228 StartingAngle[0]=0 *deg; 229 SpanningAngle[0]=90 *deg; 230 G4double PositionModx; 231 G4double WholeStartingAngle=0 *deg; 232 G4double WholeThickness=0; 233 for(G4int i=1;i<StepNumbers;i++) 234 { 235 StartingAngle[i]=WholeStartingAngle+(Weight[i-1]*(2*pi))/8; 236 SpanningAngle[i]=90* deg -2*StartingAngle[i]; 237 StepThickness[i]=StepThickness[i]-WholeThickness; 238 PositionModx=WholeThickness+StepThickness[i]/2.; 239 PositionMod[i]=G4ThreeVector(0,0,PositionModx); 240 WholeThickness+=StepThickness[i]; 241 WholeStartingAngle=StartingAngle[i]; 242 } 243 244 245 } 246 ///////////////////////////////////////////////////////////////////////////////// 247 void HadrontherapyModulator::BuildModulator(G4VPhysicalVolume* motherVolume) 248 { 249 G4bool isotopes = false; 250 G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes); 251 252 253 Mod0Mater = airNist; 254 ModMater = airNist; // You have to change modulator material via a macrofile (default is air) 255 256 innerRadiusOfTheTube = 2.5 *cm; 257 outerRadiusOfTheTube = 9.5 *cm; 258 259 // Mother of the modulator wheel 260 G4ThreeVector positionMotherMod = G4ThreeVector(-2160.50 *mm, 30 *mm, 50 *mm); 261 262 G4Box* solidMotherMod = new G4Box("MotherMod", 12 *cm, 12 *cm, 12 *cm); 263 264 logicMotherMod = new G4LogicalVolume(solidMotherMod, Mod0Mater,"MotherMod",0,0,0); 265 266 physiMotherMod = new G4PVPlacement(rm,positionMotherMod, "MotherMod", 267 logicMotherMod, 268 motherVolume, 269 false, 270 0); 271 BuildSteps(); 272 273 274 275 } 276 /////////////////////////////////////////////////////////////////////////////////////// 277 void HadrontherapyModulator::BuildSteps() 278 { 279 //---------------------------------------------------------- 280 // Mother volume of first quarter of the modulator 281 //---------------------------------------------------------- 282 283 G4double hightOfTheTube0 = 10.0 *cm; 284 G4double startAngleOfTheTube0 = 0 *deg; 285 G4double spanningAngleOfTheTube0 = 90 *deg; 286 287 G4RotationMatrix rm1; 288 rm1.rotateZ(0 *deg); 289 290 G4ThreeVector positionMod1 = G4ThreeVector(0*cm,0*cm,0*cm); 291 292 solidMod1 = new G4Tubs("Mod1", 293 innerRadiusOfTheTube, 294 outerRadiusOfTheTube, 295 hightOfTheTube0/2., 296 startAngleOfTheTube0, 297 spanningAngleOfTheTube0); 298 299 logicMod1 = new G4LogicalVolume(solidMod1, Mod0Mater, "Mod1",0,0,0); 300 301 physiMod1 = new G4PVPlacement(G4Transform3D(rm1, positionMod1), 302 logicMod1, 303 "Mod1", 304 logicMotherMod, 305 false, 306 0); 307 308 309 //---------------------------------------------------------- 310 // modulator steps 311 //---------------------------------------------------------- 312 for (G4int i=1;i<StepNumbers;i++) 313 { 314 315 solidMod[i] = new G4Tubs("Modstep", 316 innerRadiusOfTheTube, 317 outerRadiusOfTheTube, 318 StepThickness[i]/2., 319 StartingAngle[i], 320 SpanningAngle[i]); 321 322 logicMod[i] = new G4LogicalVolume(solidMod[i], 323 ModMater, "Modstep",0,0,0); 324 325 physiMod[i] = new G4PVPlacement(0, 326 PositionMod[i], 327 logicMod[i], 328 "Modstep", 329 logicMod1, 330 false, 331 0); 332 333 334 } 335 336 ///////////////////////////////////////////////////////////////////////////////////////////////// 337 //---------------------------------------------------------- 338 // Mother volume of the second modulator quarter 339 //---------------------------------------------------------- 340 341 342 G4RotationMatrix rm2; 343 rm2.rotateZ(90 *deg); 344 345 G4ThreeVector positionMod2 = G4ThreeVector(0*cm,0*cm,0*cm); 346 347 solidMod2 = new G4Tubs("Mod2", 348 innerRadiusOfTheTube, 349 outerRadiusOfTheTube, 350 hightOfTheTube0/2., 351 startAngleOfTheTube0, 352 spanningAngleOfTheTube0); 353 354 logicMod2 = new G4LogicalVolume(solidMod2, 355 Mod0Mater, "Mod2",0,0,0); 356 357 358 physiMod2 = new G4PVPlacement(G4Transform3D(rm2, positionMod2), 359 logicMod2, 360 "Mod2", 361 logicMotherMod, 362 false, 363 0); 364 365 366 for (G4int i=1;i<StepNumbers;i++) 367 { 368 369 physiMod[StepNumbers+i-1] = new G4PVPlacement(0, 370 PositionMod[i], 371 logicMod[i], 372 "Modstep", 373 logicMod2, 374 false, 375 0); 376 377 } 378 379 380 381 //---------------------------------------------------------- 382 // Mother volume of the third modulator quarter 383 //---------------------------------------------------------- 384 385 386 G4RotationMatrix rm3; 387 rm3.rotateZ(180 *deg); 388 389 G4ThreeVector positionMod3 = G4ThreeVector(0*cm,0*cm,0*cm); 390 391 solidMod3 = new G4Tubs("Mod3", 392 innerRadiusOfTheTube, 393 outerRadiusOfTheTube, 394 hightOfTheTube0, 395 startAngleOfTheTube0/2., 396 spanningAngleOfTheTube0); 397 398 logicMod3 = new G4LogicalVolume(solidMod3, 399 Mod0Mater, "Mod3",0,0,0); 400 401 402 physiMod3 = new G4PVPlacement(G4Transform3D(rm3, positionMod3), 403 logicMod3, // its logical volume 404 "Mod3", // its name 405 logicMotherMod, // its mother volume 406 false, // no boolean operations 407 0); // no particular field 408 409 410 411 412 for (G4int i=1;i<StepNumbers;i++) 413 { 414 415 physiMod[2*(StepNumbers-1)+i] = new G4PVPlacement(0, 416 PositionMod[i], 417 logicMod[i], 418 "Modstep", 419 logicMod3, 420 false, 421 0); 422 423 } 424 425 //---------------------------------------------------------- 426 // Mother volume of the fourth modulator quarter 427 //---------------------------------------------------------- 428 429 430 G4RotationMatrix rm4; 431 rm4.rotateZ(270 *deg); 432 433 G4ThreeVector positionMod4 = G4ThreeVector(0*cm,0*cm,0*cm); 434 435 solidMod4 = new G4Tubs("Mod4", 436 innerRadiusOfTheTube, 437 outerRadiusOfTheTube, 438 hightOfTheTube0, 439 startAngleOfTheTube0/2., 440 spanningAngleOfTheTube0); 441 442 logicMod4 = new G4LogicalVolume(solidMod4, 443 Mod0Mater, "Mod4",0,0,0); 444 445 446 physiMod4 = new G4PVPlacement(G4Transform3D(rm4, positionMod4), 447 logicMod4, 448 "Mod4", 449 logicMotherMod, 450 false, 451 0); 452 453 454 for (G4int i=1;i<StepNumbers;i++) 455 { 456 physiMod[3*(StepNumbers-1)+i] = new G4PVPlacement(0, 457 PositionMod[i], 458 logicMod[i], 459 "Modstep", 460 logicMod4, 461 false, 462 0); 463 } 464 // Inform the kernel about the new geometry 465 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 466 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 467 G4VisAttributes * red = new G4VisAttributes( G4Colour(1. ,0. ,0.)); 468 red-> SetVisibility(true); 469 red-> SetForceSolid(true); 470 logicMotherMod -> SetVisAttributes(G4VisAttributes::GetInvisible()); 471 472 logicMod1 ->SetVisAttributes(G4VisAttributes::GetInvisible()); 473 logicMod2 ->SetVisAttributes(G4VisAttributes::GetInvisible()); 474 logicMod3 ->SetVisAttributes(G4VisAttributes::GetInvisible()); 475 logicMod4 ->SetVisAttributes(G4VisAttributes::GetInvisible()); 476 477 for (G4int i=1;i<StepNumbers;i++) 478 { 479 logicMod[i] -> SetVisAttributes(red); 480 } 481 482 } 483 484 ///////////////////////////////////////////////////////////////////////////// 485 // Messenger values 486 ///////////////////////////////////////////////////////////////////////////// 487 void HadrontherapyModulator::SetModulatorAngle(G4double angle) 488 { 489 G4double rotationAngle = angle; 490 rm -> rotateZ(rotationAngle); 491 physiMotherMod -> SetRotation(rm); 492 G4cout << "MODULATOR HAS BEEN ROTATED OF " << rotationAngle/deg 493 << " deg" << G4endl; 494 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 495 } 496 ///////////////////////////////////////////////////////////////////////// 497 // Change modulator material 498 void HadrontherapyModulator::SetModulatorMaterial(G4String Material) 499 { 500 if (G4Material* NewMaterial = G4NistManager::Instance()->FindOrBuildMaterial(Material, false) ) 501 { 502 if (NewMaterial) 503 { 504 for(G4int i=1;i<StepNumbers;i++) 505 { 506 logicMod[i] -> SetMaterial(NewMaterial); 507 // G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 508 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 509 510 // G4cout<<(logicMod[i]->GetMaterial()->GetName())<<G4endl; 511 } 512 G4cout << "The material of the Modulator wheel has been changed to " << Material << G4endl; 513 } 514 } 515 else 516 { 517 G4cout << "WARNING: material \"" << Material << "\" doesn't exist in NIST elements/materials" 518 " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl; 519 G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl; 520 521 522 } 523 } 524 525 //////////////////////////////////////////////////////////////////////////////// 526 // Change modulator position in the beam line 527 void HadrontherapyModulator::SetModulatorPosition(G4ThreeVector Pos) 528 { 529 G4ThreeVector NewModulatorPos=Pos; 530 physiMotherMod -> SetTranslation( NewModulatorPos); 531 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 532 G4cout << "The modulator wheel is translated to"<< NewModulatorPos/mm <<"mm " <<G4endl; 533 534 } 535 ///////////////////////////////////////////////////////////////////////////////// 536 //change modulator inner raduis 537 void HadrontherapyModulator::SetModulatorInnerRadius(G4double newvalue) 538 { 539 solidMod1 -> SetInnerRadius(newvalue); 540 solidMod2 -> SetInnerRadius(newvalue); 541 solidMod3 -> SetInnerRadius(newvalue); 542 solidMod4 -> SetInnerRadius(newvalue); 543 for(G4int i=1;i<StepNumbers;i++) 544 { 545 solidMod[i] -> SetInnerRadius(newvalue);} 546 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 547 G4cout << "InnerRadius of the Modulator Wheel has been changed to :" 548 << newvalue/mm<<" mm"<< G4endl; 549 } 550 ///////////////////////////////////////////////////////////////////////////////// 551 //change modulator outer raduis 552 void HadrontherapyModulator::SetModulatorOuterRadius(G4double newvalue) 553 { 554 solidMod1 -> SetOuterRadius(newvalue); 555 solidMod2 -> SetOuterRadius(newvalue); 556 solidMod3 -> SetOuterRadius(newvalue); 557 solidMod4 -> SetOuterRadius(newvalue); 558 for(G4int i=1;i<StepNumbers;i++) 559 { 560 solidMod[i] -> SetOuterRadius(newvalue);} 561 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 562 G4cout << "OuterRadius of the Modulator Wheel has been changed to :" 563 << newvalue/mm<<" mm"<<G4endl; 564 } 565 ///////////////////////////////////////////////////////////////////////////////// 566 void HadrontherapyModulator:: GetDataFromFile(G4String value) 567 568 { 569 G4String Name=value; 570 if(value=="default" ) 571 { 572 Name=FileName; 573 } 574 G4cout<<" Step properties of modulator will be get out from the external file " 575 <<Name<<G4endl; 576 ModulatorPropertiesFromFile(Name); 577 } 578