Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:16:37

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 
0027 #include "G4SDManager.hh"
0028 #include "G4RunManager.hh"
0029 #include "G4Box.hh"
0030 #include "G4Tubs.hh"
0031 #include "G4Cons.hh"
0032 #include "G4Orb.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4ThreeVector.hh"
0035 #include "G4PVPlacement.hh"
0036 #include "globals.hh"
0037 #include "G4RotationMatrix.hh"
0038 #include "G4Colour.hh"
0039 #include "G4UserLimits.hh"
0040 #include "G4VisAttributes.hh"
0041 #include "G4NistManager.hh"
0042 
0043 #include "GammaKnifeDetectorMessenger.hh"
0044 #include "GammaKnifeDetectorConstruction.hh"
0045 
0046 #include "G4SystemOfUnits.hh"
0047 
0048 GammaKnifeDetectorConstruction::GammaKnifeDetectorConstruction()
0049   : physicalTreatmentRoom(0),
0050     patientPhysicalVolume(0), 
0051     patientLogicalVolume(0),
0052     solidColl_helmet(0),
0053     helmetSize(4)
0054 {
0055   // Messenger to change parameters of the geometry
0056   detectorMessenger = new GammaKnifeDetectorMessenger(this);
0057 }
0058 
0059 GammaKnifeDetectorConstruction::~GammaKnifeDetectorConstruction()
0060 {
0061   delete detectorMessenger;
0062 }
0063 
0064 G4VPhysicalVolume* GammaKnifeDetectorConstruction::Construct()
0065 {
0066   // Define the geometry components
0067   ConstructBeamLine();
0068  
0069   return physicalTreatmentRoom;
0070 }
0071 
0072 void GammaKnifeDetectorConstruction::ConstructBeamLine()
0073 {
0074     // NIST Materials
0075     G4Material* air = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR");
0076     G4Material* water = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER");
0077     G4Material* cobalt = G4NistManager::Instance()->FindOrBuildMaterial("G4_Co");
0078     G4Material* Pb = G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb");
0079     G4Material* tungsten = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
0080     G4Material* Al = G4NistManager::Instance()->FindOrBuildMaterial("G4_Al");
0081     G4Material* Fe = G4NistManager::Instance()->FindOrBuildMaterial("G4_Fe");
0082 
0083     // Steel as non-NIST material
0084     G4Element* elFe = G4NistManager::Instance()->FindOrBuildElement("Fe");
0085     G4Element* elNi = G4NistManager::Instance()->FindOrBuildElement("Ni");
0086     G4Element* elCr = G4NistManager::Instance()->FindOrBuildElement("Cr");
0087     G4Material* steel = new G4Material("StainlessSteel", 7.80 * g/cm3, 3 /* components */);
0088     steel -> AddElement(elFe, 70 * perCent);
0089     steel -> AddElement(elCr, 18 * perCent);
0090     steel -> AddElement(elNi, 12 * perCent);
0091 
0092   // -----------------------------
0093   // Treatment room - World volume
0094   // -----------------------------
0095 
0096   // Treatment room sizes
0097   const G4double worldX = 400.0 *cm;
0098   const G4double worldY = 400.0 *cm;
0099   const G4double worldZ = 400.0 *cm;
0100 
0101   G4Box* treatmentRoom = new G4Box("TreatmentRoom",worldX,worldY,worldZ);
0102 
0103   G4LogicalVolume* logicTreatmentRoom = new G4LogicalVolume(treatmentRoom, 
0104                                                             air, 
0105                                                             "logicTreatmentRoom", 
0106                                 0,0,0);
0107 
0108   physicalTreatmentRoom = new G4PVPlacement(0,
0109                         G4ThreeVector(),
0110                         "physicalTreatmentRoom", 
0111                         logicTreatmentRoom, 
0112                         0,false,0);
0113 
0114 
0115   // The treatment room is invisible in the Visualisation
0116   logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::GetInvisible());
0117 
0118 
0119   // Visualisation attributes of all elements colours 
0120   G4VisAttributes * grayFe = new G4VisAttributes(G4Colour(0.5 ,0.5 ,0.5));
0121   grayFe -> SetVisibility(true);
0122   grayFe -> SetForceSolid(true);
0123 
0124   G4VisAttributes * blueCobalt = new G4VisAttributes(G4Colour(0. ,0. ,0.7));
0125   blueCobalt -> SetVisibility(true);
0126   blueCobalt -> SetForceSolid(true);
0127 
0128   G4VisAttributes * graySS = new G4VisAttributes(G4Colour(0.9 ,0.9 ,0.9));
0129   graySS -> SetVisibility(true);
0130   graySS -> SetForceSolid(true);
0131 
0132   G4VisAttributes * grayAl = new G4VisAttributes(G4Colour(0.7 ,0.7 ,0.7));
0133   grayAl -> SetVisibility(true);
0134   grayAl -> SetForceSolid(true);
0135 
0136   G4VisAttributes * blackLead = new G4VisAttributes(G4Colour(0.2 ,0.2 ,0.2));
0137   blackLead -> SetVisibility(true);
0138   blackLead -> SetForceSolid(true);
0139  
0140 
0141   G4VisAttributes * colorTungsten = new G4VisAttributes(G4Colour(0.3 ,0.3 ,0.3));
0142   colorTungsten -> SetVisibility(true);
0143   colorTungsten -> SetForceSolid(true);
0144  
0145 
0146 
0147 
0148 
0149   //--------------------------------------------
0150   // Cylinder source "Tube_source"
0151   //--------------------------------------------
0152   G4double innerRadiusOfTheTube_source = 0.;
0153   G4double outerRadiusOfTheTube_source = 0.5*mm;
0154   G4double hightOfTheTube_source = 1*cm;
0155   G4double startAngleOfTheTube = 0.*deg;
0156   G4double spanningAngleOfTheTube = 360.*deg;
0157 
0158   G4ThreeVector positionTube_source = G4ThreeVector(0,0,-40.1*cm);
0159   
0160   solidTube_source = new G4Tubs("solidTube_source",    
0161                  innerRadiusOfTheTube_source,    
0162                  outerRadiusOfTheTube_source,   
0163                  hightOfTheTube_source,       
0164                  startAngleOfTheTube,             
0165                  spanningAngleOfTheTube);          
0166   logicTube_source = new G4LogicalVolume(solidTube_source,cobalt,"logicTube_source",0,0,0);
0167   physiTube_source = new G4PVPlacement(0,           
0168                 positionTube_source,
0169                 logicTube_source,
0170                 "Tube_source",
0171                 logicTreatmentRoom,
0172                 false,
0173                 0);
0174 
0175   logicTube_source -> SetVisAttributes(blueCobalt);
0176 
0177 
0178   //-------------------------------------
0179   // Cylinder covering source "Tube"
0180   //-------------------------------------
0181   G4double innerRadiusOfTheTube = 0.5*mm;
0182   G4double outerRadiusOfTheTube = 4.*mm;
0183   G4double hightOfTheTube = 1*cm;
0184   
0185 
0186   G4ThreeVector positionTube = G4ThreeVector(0,0,-40.1*cm);
0187   
0188   solidTube = new G4Tubs("solidTube",    
0189                  innerRadiusOfTheTube,    
0190                  outerRadiusOfTheTube,  
0191                  hightOfTheTube,          
0192                  startAngleOfTheTube,    
0193                  spanningAngleOfTheTube);
0194   logicTube = new G4LogicalVolume(solidTube,steel,"logicTube",0,0,0);
0195   physiTube = new G4PVPlacement(0,          
0196                 positionTube,
0197                 logicTube,
0198                 "Tube",
0199                 logicTreatmentRoom,
0200                 false,
0201                 0);
0202 
0203   logicTube -> SetVisAttributes(graySS);
0204 
0205   //---------------------------------------
0206   // Cylinder covering source "Tube_Al"
0207   //---------------------------------------
0208   G4double innerRadiusOfTheTube_Al = 4.*mm;
0209   G4double outerRadiusOfTheTube_Al = 15.*mm;
0210   G4double hightOfTheTube_Al = 1*cm;
0211  
0212   G4ThreeVector positionTube_Al = G4ThreeVector(0,0,-40.1*cm);
0213   
0214   solidTube_Al = new G4Tubs("solidTube_Al",    
0215                  innerRadiusOfTheTube_Al,   
0216                  outerRadiusOfTheTube_Al,    
0217                  hightOfTheTube_Al,         
0218                  startAngleOfTheTube,     
0219                  spanningAngleOfTheTube); 
0220   logicTube_Al = new G4LogicalVolume(solidTube_Al,Al,"logicTube_Al",0,0,0);
0221   physiTube_Al = new G4PVPlacement(0,          
0222                 positionTube_Al,
0223                 logicTube_Al,
0224                 "Tube_Al",
0225                 logicTreatmentRoom,
0226                 false,
0227                 0);
0228 
0229   logicTube_Al -> SetVisAttributes(grayAl);
0230 
0231   //----------------------------------------------
0232   // Cylinder covering external part of the source "Tube_Fe"
0233   //----------------------------------------------
0234   G4double innerRadiusOfTheTube_Fe = 15.*mm;
0235   G4double outerRadiusOfTheTube_Fe = 50.*mm;
0236   G4double hightOfTheTube_Fe = 1*cm;
0237   
0238 
0239   G4ThreeVector positionTube_Fe = G4ThreeVector(0,0,-40.1*cm);
0240   
0241   solidTube_Fe = new G4Tubs("solidTube_Fe",    
0242                  innerRadiusOfTheTube_Fe,    
0243                  outerRadiusOfTheTube_Fe,   
0244                  hightOfTheTube_Fe,          
0245                  startAngleOfTheTube,     
0246                  spanningAngleOfTheTube); 
0247   logicTube_Fe = new G4LogicalVolume(solidTube_Fe,Fe,"logicTube_Fe",0,0,0);
0248   physiTube_Fe = new G4PVPlacement(0,           
0249                 positionTube_Fe,
0250                 logicTube_Fe,
0251                 "Tube_Fe",
0252                 logicTreatmentRoom,
0253                 false,
0254                 0);
0255 
0256   logicTube_Fe -> SetVisAttributes(grayFe);
0257 
0258 
0259 
0260 
0261  //------------------------------------------------
0262  // Cylinder covering posterior part "Tube_post"
0263  //------------------------------------------------
0264 
0265   G4double innerRadiusOfTheTube_post = 0;
0266   G4double outerRadiusOfTheTube_post = 50*mm;
0267   G4double hightOfTheTube_post = 1*cm;
0268  
0269   G4ThreeVector positionTube_post = G4ThreeVector(0,0,-42.2*cm);
0270   
0271   solidTube_post = new G4Tubs("solidTube_post",    
0272                  innerRadiusOfTheTube_post,   
0273                  outerRadiusOfTheTube_post,   
0274                  hightOfTheTube_post,          
0275                  startAngleOfTheTube,     
0276                  spanningAngleOfTheTube); 
0277  logicTube_post = new G4LogicalVolume(solidTube_post,Fe,"logicTube_post",0,0,0);
0278  physiTube_post = new G4PVPlacement(0,           
0279                 positionTube_post,
0280                 logicTube_post,
0281                 "Tube_post",
0282                     logicTreatmentRoom,
0283                 false,
0284                 0);
0285 
0286  logicTube_post -> SetVisAttributes(grayFe);
0287 
0288 
0289  //------------------------------------------------
0290  // Fixed cylinder collimator "Tube_coll"
0291  //------------------------------------------------
0292 
0293   G4double innerRadiusOfTheTube_coll = 2.5*mm;
0294   G4double outerRadiusOfTheTube_coll = 15.*mm;
0295   G4double hightOfTheTube_coll = 3.25*cm;
0296  
0297   G4ThreeVector positionTube_coll = G4ThreeVector(0,0,-35.2*cm);
0298   
0299   solidTube_coll = new G4Tubs("solidTube_coll",    
0300                  innerRadiusOfTheTube_coll,    
0301                  outerRadiusOfTheTube_coll,    
0302                  hightOfTheTube_coll,         
0303                  startAngleOfTheTube,     
0304                  spanningAngleOfTheTube); 
0305  logicTube_coll = new G4LogicalVolume(solidTube_coll,tungsten,"logicTube_coll",0,0,0);
0306  physiTube_coll = new G4PVPlacement(0,           
0307                 positionTube_coll,
0308                 logicTube_coll,
0309                 "Tube_coll",
0310                 logicTreatmentRoom,
0311                 false,
0312                 0);
0313 
0314  logicTube_coll -> SetVisAttributes(colorTungsten);
0315 
0316 
0317  //------------------------------------------------
0318  // Cylinder covering fixed collimator "Tube_coll_Fe"
0319  //------------------------------------------------
0320 
0321   G4double innerRadiusOfTheTube_coll_Fe = 15.*mm;
0322   G4double outerRadiusOfTheTube_coll_Fe = 50.*mm;
0323   G4double hightOfTheTube_coll_Fe = 3.25*cm;
0324  
0325   G4ThreeVector positionTube_coll_Fe = G4ThreeVector(0,0,-35.2*cm);
0326   
0327   solidTube_coll_Fe = new G4Tubs("solidTube_coll_Fe",    
0328                  innerRadiusOfTheTube_coll_Fe,    
0329                  outerRadiusOfTheTube_coll_Fe,    
0330                  hightOfTheTube_coll_Fe,          
0331                  startAngleOfTheTube,     
0332                  spanningAngleOfTheTube); 
0333  logicTube_coll_Fe = new G4LogicalVolume(solidTube_coll_Fe,Fe,"logicTube_coll_Fe",0,0,0);
0334  physiTube_coll_Fe = new G4PVPlacement(0,          
0335                 positionTube_coll_Fe,
0336                 logicTube_coll_Fe,
0337                 "Tube_coll_Fe",
0338                 logicTreatmentRoom,
0339                 false,
0340                 0);
0341 
0342  logicTube_coll_Fe -> SetVisAttributes(grayFe);
0343 
0344 
0345  //------------------------------------------------
0346  // Fixed truncated cone collimator "Coll_fixed"
0347  //------------------------------------------------
0348 
0349   G4double Rmin1Coll_fixed = 2.5*mm;
0350   G4double Rmax1Coll_fixed = 15.*mm;
0351   G4double Rmin2Coll_fixed = 4.25*mm;
0352   G4double Rmax2Coll_fixed = 15.*mm;
0353   G4double hightColl_fixed = 4.625*cm;
0354  
0355 
0356   G4ThreeVector positionColl_fixed = G4ThreeVector(0,0,-27.325*cm);
0357 
0358   solidColl_fixed = new G4Cons("solidColl_fixed",
0359                    Rmin1Coll_fixed,  
0360                    Rmax1Coll_fixed, 
0361                    Rmin2Coll_fixed,  
0362                    Rmax2Coll_fixed, 
0363                    hightColl_fixed,  
0364                    startAngleOfTheTube,    
0365                    spanningAngleOfTheTube);
0366   logicColl_fixed = new G4LogicalVolume(solidColl_fixed,Pb,"logicColl_fixed",0,0,0);
0367   physiColl_fixed = new G4PVPlacement(0,
0368                       positionColl_fixed,
0369                       logicColl_fixed,
0370                       "Coll_fixed",
0371                       logicTreatmentRoom,
0372                       false,
0373                       0);
0374 
0375  logicColl_fixed -> SetVisAttributes(blackLead);
0376 
0377 
0378  //-----------------------------------------------------------
0379  // Cilinder covering fixed collimator "Coll_fixed_Fe"
0380  //-----------------------------------------------------------
0381 
0382   G4double Rmin1Coll_fixed_Fe = 15.*mm;
0383   G4double Rmax1Coll_fixed_Fe = 50.*mm;
0384   G4double Rmin2Coll_fixed_Fe = 15.*mm;
0385   G4double Rmax2Coll_fixed_Fe = 40.*mm;
0386   G4double hightColl_fixed_Fe = 4.625*cm;
0387  
0388 
0389   G4ThreeVector positionColl_fixed_Fe = G4ThreeVector(0,0,-27.325*cm);
0390 
0391   solidColl_fixed_Fe = new G4Cons("solidColl_fixed_Fe",
0392                    Rmin1Coll_fixed_Fe,  
0393                    Rmax1Coll_fixed_Fe,  
0394                    Rmin2Coll_fixed_Fe,  
0395                    Rmax2Coll_fixed_Fe,  
0396                    hightColl_fixed_Fe,  
0397                    startAngleOfTheTube,    // 
0398                    spanningAngleOfTheTube);
0399   logicColl_fixed_Fe = new G4LogicalVolume(solidColl_fixed_Fe,Fe,"logicColl_fixed_Fe",0,0,0);
0400   physiColl_fixed_Fe = new G4PVPlacement(0,
0401                       positionColl_fixed_Fe,
0402                       logicColl_fixed_Fe,
0403                       "Coll_fixed_Fe",
0404                       logicTreatmentRoom,
0405                       false,
0406                       0);
0407 
0408   logicColl_fixed_Fe -> SetVisAttributes(grayFe);
0409 
0410 
0411  //------------------------------------------------
0412  // Mobile truncate cone collimator "Coll_helmet"
0413  //------------------------------------------------
0414   G4double Rmax1Coll_helmet = 15.*mm;
0415   G4double Rmax2Coll_helmet = 15.*mm;
0416   G4double hightColl_helmet = 3.0*cm;
0417  
0418 
0419   G4ThreeVector positionColl_helmet = G4ThreeVector(0,0,-19.5*cm);
0420 
0421   solidColl_helmet = new G4Cons("solidColl_helmet",
0422                                0.0,  // will be set later
0423                                Rmax1Coll_helmet, 
0424                                0.0,  // will be set later
0425                    Rmax2Coll_helmet,  
0426                    hightColl_helmet, 
0427                    startAngleOfTheTube,   
0428                                spanningAngleOfTheTube);
0429   UpdateHelmet(); // Set the proper inner radii
0430 
0431   logicColl_helmet = new G4LogicalVolume(solidColl_helmet,tungsten,"logicColl_helmet",0,0,0);
0432   physiColl_helmet = new G4PVPlacement(0,
0433                       positionColl_helmet,
0434                       logicColl_helmet,
0435                       "Coll_helmet",
0436                       logicTreatmentRoom,
0437                       false,
0438                       0);
0439 
0440   logicColl_helmet -> SetVisAttributes(colorTungsten);
0441 
0442  //--------------------------------------------------------------
0443  // Truncated cone covering mobile collimator "Coll_helmet_Fe"
0444  //--------------------------------------------------------------
0445 
0446   G4double Rmin1Coll_helmet_Fe = 15.*mm;
0447   G4double Rmax1Coll_helmet_Fe = 40.*mm;
0448   G4double Rmin2Coll_helmet_Fe = 15.*mm;
0449   G4double Rmax2Coll_helmet_Fe = 30.*mm;
0450   G4double hightColl_helmet_Fe = 3.0*cm;
0451 
0452   G4ThreeVector positionColl_helmet_Fe = G4ThreeVector(0,0,-19.5*cm);
0453 
0454   solidColl_helmet_Fe = new G4Cons("solidColl_helmet_Fe",
0455                    Rmin1Coll_helmet_Fe, 
0456                    Rmax1Coll_helmet_Fe,  
0457                    Rmin2Coll_helmet_Fe,  
0458                    Rmax2Coll_helmet_Fe,  
0459                    hightColl_helmet_Fe, 
0460                    startAngleOfTheTube,   
0461                    spanningAngleOfTheTube);
0462   logicColl_helmet_Fe = new G4LogicalVolume(solidColl_helmet_Fe,Fe,"logicColl_helmet_Fe",0,0,0);
0463   physiColl_helmet_Fe = new G4PVPlacement(0,
0464                       positionColl_helmet_Fe,
0465                       logicColl_helmet_Fe,
0466                       "Coll_helmet_Fe",
0467                       logicTreatmentRoom,
0468                       false,
0469                       0);
0470 
0471   logicColl_helmet_Fe -> SetVisAttributes(grayFe);
0472 
0473   //-----------------------------------------
0474   // Patient --> water spherical phantom
0475   //-----------------------------------------
0476 
0477  
0478   G4Orb* patient = new G4Orb("patient",8.*cm);
0479   patientLogicalVolume = new G4LogicalVolume(patient,
0480                                   water, 
0481                                   "patientLog", 0, 0, 0);
0482   patientPhysicalVolume = new G4PVPlacement( new G4RotationMatrix(),
0483                                             G4ThreeVector(0., 0., 0.),
0484                         "patientPhys",
0485                         patientLogicalVolume,
0486                         physicalTreatmentRoom,
0487                         false,0);
0488 
0489   // Visualisation attributes of the patient 
0490   G4VisAttributes * redWire = new G4VisAttributes(G4Colour(0.8 ,0. ,0.));
0491   redWire -> SetVisibility(true);
0492   redWire -> SetForceWireframe(true);
0493   redWire -> SetForceAuxEdgeVisible(true);
0494   patientLogicalVolume -> SetVisAttributes(redWire); 
0495 
0496 }
0497 
0498 void GammaKnifeDetectorConstruction::UpdateHelmet()
0499 {
0500     if (solidColl_helmet)
0501     {
0502         switch( helmetSize )
0503         {
0504         case 18:
0505             solidColl_helmet->SetInnerRadiusMinusZ( 4.15 * mm );
0506             solidColl_helmet->SetInnerRadiusPlusZ( 5.3  * mm );
0507             break;
0508 
0509         case 14:
0510             solidColl_helmet->SetInnerRadiusMinusZ( 3.15 * mm );
0511             solidColl_helmet->SetInnerRadiusPlusZ( 4.25  * mm );
0512             break;
0513 
0514         case 8:
0515             solidColl_helmet->SetInnerRadiusMinusZ( 1.9 * mm );
0516             solidColl_helmet->SetInnerRadiusPlusZ( 2.5  * mm );
0517             break;
0518 
0519         case 4:
0520             solidColl_helmet->SetInnerRadiusMinusZ( 1. * mm );
0521             solidColl_helmet->SetInnerRadiusPlusZ( 1.25  * mm );
0522             break;
0523         }
0524         // Inform the run manager about change in the geometry
0525         G4RunManager::GetRunManager()->GeometryHasBeenModified();
0526     }
0527 }
0528 
0529 void GammaKnifeDetectorConstruction::SetHelmetSize(G4int size)
0530 {
0531     if (size != helmetSize) // Only if the size changes
0532     {
0533         // Allow only valid numbers
0534         switch( size )
0535         {
0536         case 18:
0537         case 14:
0538         case 8:
0539         case 4:
0540             helmetSize = size;
0541             G4cout << "Helmet size set to " << helmetSize << std::endl;
0542             UpdateHelmet();
0543             break;
0544         default:
0545       G4Exception("GammaKnifeDetectorConstruction::SetHelmetSize()", 
0546           "GammaKnife001", FatalException, 
0547           "Error: Invalid helmet size.");
0548             return;
0549         }
0550     }
0551 }
0552 
0553 
0554