Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:22:17

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 // Hadrontherapy advanced example for Geant4
0027 // See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
0028 
0029 #include "G4UnitsTable.hh"
0030 #include "G4SystemOfUnits.hh"
0031 #include "G4LogicalVolume.hh"
0032 #include "G4VPhysicalVolume.hh"
0033 #include "G4PVPlacement.hh"
0034 #include "G4PVReplica.hh"
0035 #include "G4Box.hh"
0036 #include "G4ThreeVector.hh"
0037 #include "G4Material.hh"
0038 #include "G4NistManager.hh"
0039 #include "G4GeometryManager.hh"
0040 #include "G4SolidStore.hh"
0041 #include "G4LogicalVolumeStore.hh"
0042 
0043 
0044 
0045 #include "G4SDManager.hh"
0046 #include "G4RunManager.hh"
0047 
0048 #include "G4PhysicalVolumeStore.hh"
0049 
0050 #include "G4ThreeVector.hh"
0051 
0052 #include "globals.hh"
0053 #include "G4Transform3D.hh"
0054 #include "G4RotationMatrix.hh"
0055 #include "G4Colour.hh"
0056 #include "G4UserLimits.hh"
0057 
0058 #include "G4VisAttributes.hh"
0059 
0060 #include "HadrontherapyDetectorROGeometry.hh"
0061 #include "HadrontherapyDummySD.hh"
0062 #include "HadrontherapyDetectorSD.hh"
0063 
0064 /////////////////////////////////////////////////////////////////////////////
0065 HadrontherapyDetectorROGeometry::HadrontherapyDetectorROGeometry(G4String aString)
0066   : G4VUserParallelWorld(aString),RODetector(0),RODetectorXDivision(0),
0067     RODetectorYDivision(0),RODetectorZDivision(0),worldLogical(0),RODetectorLog(0),
0068     RODetectorXDivisionLog(0),RODetectorYDivisionLog(0),RODetectorZDivisionLog(0),
0069     sensitiveLogicalVolume(0)
0070 {
0071   isBuilt = false;
0072   isInitialized = false;
0073 }
0074 
0075 /////////////////////////////////////////////////////////////////////////////
0076 
0077 void HadrontherapyDetectorROGeometry::Initialize(G4ThreeVector pos,
0078                          G4double detectorDimX,
0079                          G4double detectorDimY,
0080                          G4double detectorDimZ,
0081                          G4int numberOfVoxelsX,
0082                          G4int numberOfVoxelsY,
0083                          G4int numberOfVoxelsZ)
0084 {  
0085   detectorToWorldPosition = pos;
0086   detectorSizeX = detectorDimX;
0087   detectorSizeY= detectorDimY;
0088   detectorSizeZ=detectorDimZ;
0089   numberOfVoxelsAlongX=numberOfVoxelsX;
0090   numberOfVoxelsAlongY=numberOfVoxelsY;
0091   numberOfVoxelsAlongZ=numberOfVoxelsZ;
0092 
0093   isInitialized = true;
0094 
0095 
0096   
0097 }
0098 
0099 void HadrontherapyDetectorROGeometry::UpdateROGeometry()
0100 {
0101   //Nothing happens if the RO geometry is not built. But parameters are properly set.
0102   if (!isBuilt)
0103     {
0104       //G4Exception("HadrontherapyDetectorROGeometry::UpdateROGeometry","had001",
0105       //          JustWarning,"Cannot update geometry before it is built");
0106       return;
0107     }
0108  
0109   //1) Update the dimensions of the G4Boxes
0110   G4double halfDetectorSizeX = detectorSizeX;
0111   G4double halfDetectorSizeY = detectorSizeY;
0112   G4double halfDetectorSizeZ = detectorSizeZ;
0113 
0114   RODetector->SetXHalfLength(halfDetectorSizeX);
0115   RODetector->SetYHalfLength(halfDetectorSizeY);
0116   RODetector->SetZHalfLength(halfDetectorSizeZ);
0117 
0118   G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX;
0119   G4double halfXVoxelSizeY = halfDetectorSizeY;
0120   G4double halfXVoxelSizeZ = halfDetectorSizeZ;
0121   G4double voxelXThickness = 2*halfXVoxelSizeX;
0122   
0123   RODetectorXDivision->SetXHalfLength(halfXVoxelSizeX);
0124   RODetectorXDivision->SetYHalfLength(halfXVoxelSizeY);
0125   RODetectorXDivision->SetZHalfLength(halfXVoxelSizeZ);
0126 
0127   G4double halfYVoxelSizeX = halfXVoxelSizeX;
0128   G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY;
0129   G4double halfYVoxelSizeZ = halfDetectorSizeZ;
0130   G4double voxelYThickness = 2*halfYVoxelSizeY;
0131 
0132   RODetectorYDivision->SetXHalfLength(halfYVoxelSizeX);
0133   RODetectorYDivision->SetYHalfLength(halfYVoxelSizeY);
0134   RODetectorYDivision->SetZHalfLength(halfYVoxelSizeZ);
0135 
0136   G4double halfZVoxelSizeX = halfXVoxelSizeX;
0137   G4double halfZVoxelSizeY = halfYVoxelSizeY;
0138   G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ;
0139   G4double voxelZThickness = 2*halfZVoxelSizeZ;
0140 
0141   RODetectorZDivision->SetXHalfLength(halfZVoxelSizeX);
0142   RODetectorZDivision->SetYHalfLength(halfZVoxelSizeY);
0143   RODetectorZDivision->SetZHalfLength(halfZVoxelSizeZ);
0144 
0145   //Delete and re-build the relevant physical volumes
0146   G4PhysicalVolumeStore* store =
0147     G4PhysicalVolumeStore::GetInstance();
0148 
0149   //Delete...
0150   G4VPhysicalVolume* myVol = store->GetVolume("RODetectorPhys");
0151   store->DeRegister(myVol);
0152   //..and rebuild
0153   G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0,
0154                             detectorToWorldPosition,
0155                             RODetectorLog,
0156                             "RODetectorPhys",
0157                             worldLogical,                           
0158                             false,0);
0159 
0160   myVol = store->GetVolume("RODetectorXDivisionPhys");
0161   store->DeRegister(myVol);
0162   G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys",
0163                                    RODetectorXDivisionLog,
0164                                    RODetectorPhys,
0165                                    kXAxis,
0166                                    numberOfVoxelsAlongX,
0167                                    voxelXThickness);
0168   myVol = store->GetVolume("RODetectorYDivisionPhys");
0169   store->DeRegister(myVol);
0170   G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys",
0171                                    RODetectorYDivisionLog,
0172                                    RODetectorXDivisionPhys,
0173                                    kYAxis,
0174                                    numberOfVoxelsAlongY,
0175                                    voxelYThickness);
0176   
0177   myVol = store->GetVolume("RODetectorZDivisionPhys");
0178   store->DeRegister(myVol);
0179   new G4PVReplica("RODetectorZDivisionPhys",
0180           RODetectorZDivisionLog,
0181           RODetectorYDivisionPhys,
0182           kZAxis,
0183           numberOfVoxelsAlongZ,
0184           voxelZThickness);
0185 
0186   return;
0187 
0188 }
0189 
0190 /////////////////////////////////////////////////////////////////////////////
0191 HadrontherapyDetectorROGeometry::~HadrontherapyDetectorROGeometry()
0192 {;}
0193 
0194 /////////////////////////////////////////////////////////////////////////////
0195 void HadrontherapyDetectorROGeometry::Construct()
0196 {
0197   // A dummy material is used to fill the volumes of the readout geometry.
0198   // (It will be allowed to set a NULL pointer in volumes of such virtual
0199   // division in future, since this material is irrelevant for tracking.)
0200   
0201 
0202   //
0203   // World
0204   //
0205   G4VPhysicalVolume* ghostWorld = GetWorld();
0206   worldLogical = ghostWorld->GetLogicalVolume();
0207   
0208   if (!isInitialized)
0209     {
0210       G4Exception("HadrontherapyDetectorROGeometry::Construct","had001",
0211           FatalException,"Parameters of the RO geometry are not initialized");
0212       return;
0213     }
0214 
0215   
0216   G4double halfDetectorSizeX = detectorSizeX;
0217   G4double halfDetectorSizeY = detectorSizeY;
0218   G4double halfDetectorSizeZ = detectorSizeZ;
0219     
0220     // World volume of ROGeometry ... SERVE SOLO PER LA ROG
0221 
0222   // Detector ROGeometry 
0223   RODetector = new G4Box("RODetector", 
0224              halfDetectorSizeX, 
0225              halfDetectorSizeY, 
0226              halfDetectorSizeZ);
0227   
0228   RODetectorLog = new G4LogicalVolume(RODetector,
0229                       0,
0230                       "RODetectorLog",
0231                       0,0,0);
0232   
0233   
0234   
0235   G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0,
0236                             detectorToWorldPosition,RODetectorLog,
0237                             "RODetectorPhys",
0238                             worldLogical,                           
0239                             false,0);
0240 
0241 
0242 
0243   
0244   // Division along X axis: the detector is divided in slices along the X axis
0245   
0246   G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX;
0247   G4double halfXVoxelSizeY = halfDetectorSizeY;
0248   G4double halfXVoxelSizeZ = halfDetectorSizeZ;
0249   G4double voxelXThickness = 2*halfXVoxelSizeX;
0250   
0251 
0252   RODetectorXDivision = new G4Box("RODetectorXDivision",
0253                   halfXVoxelSizeX,
0254                   halfXVoxelSizeY,
0255                   halfXVoxelSizeZ);
0256   
0257   RODetectorXDivisionLog = new G4LogicalVolume(RODetectorXDivision,
0258                            0,
0259                            "RODetectorXDivisionLog",
0260                            0,0,0);
0261 
0262   G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys",
0263                                                               RODetectorXDivisionLog,
0264                                                               RODetectorPhys,
0265                                                               kXAxis,
0266                                                               numberOfVoxelsAlongX,
0267                                                               voxelXThickness);
0268 
0269   // Division along Y axis: the slices along the X axis are divided along the Y axis
0270 
0271   G4double halfYVoxelSizeX = halfXVoxelSizeX;
0272   G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY;
0273   G4double halfYVoxelSizeZ = halfDetectorSizeZ;
0274   G4double voxelYThickness = 2*halfYVoxelSizeY;
0275 
0276   RODetectorYDivision = new G4Box("RODetectorYDivision",
0277                   halfYVoxelSizeX, 
0278                   halfYVoxelSizeY,
0279                   halfYVoxelSizeZ);
0280 
0281   RODetectorYDivisionLog = new G4LogicalVolume(RODetectorYDivision,
0282                            0,
0283                            "RODetectorYDivisionLog",
0284                            0,0,0);
0285  
0286   G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys",
0287                                   RODetectorYDivisionLog,
0288                                   RODetectorXDivisionPhys,
0289                                   kYAxis,
0290                                   numberOfVoxelsAlongY,
0291                                   voxelYThickness);
0292   
0293   // Division along Z axis: the slices along the Y axis are divided along the Z axis
0294 
0295   G4double halfZVoxelSizeX = halfXVoxelSizeX;
0296   G4double halfZVoxelSizeY = halfYVoxelSizeY;
0297   G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ;
0298   G4double voxelZThickness = 2*halfZVoxelSizeZ;
0299  
0300   RODetectorZDivision = new G4Box("RODetectorZDivision",
0301                   halfZVoxelSizeX,
0302                   halfZVoxelSizeY, 
0303                   halfZVoxelSizeZ);
0304  
0305   RODetectorZDivisionLog = new G4LogicalVolume(RODetectorZDivision,
0306                            0,
0307                            "RODetectorZDivisionLog",
0308                            0,0,0);
0309  
0310   new G4PVReplica("RODetectorZDivisionPhys",
0311           RODetectorZDivisionLog,
0312           RODetectorYDivisionPhys,
0313           kZAxis,
0314           numberOfVoxelsAlongZ,
0315           voxelZThickness);
0316 
0317   sensitiveLogicalVolume = RODetectorZDivisionLog;
0318   isBuilt = true;
0319 }
0320 
0321 void HadrontherapyDetectorROGeometry::ConstructSD()
0322 {
0323  G4String sensitiveDetectorName = "RODetector";
0324  
0325  HadrontherapyDetectorSD* detectorSD = new HadrontherapyDetectorSD(sensitiveDetectorName);
0326  G4SDManager::GetSDMpointer()->AddNewDetector(detectorSD);
0327  sensitiveLogicalVolume->SetSensitiveDetector(detectorSD);
0328 
0329  // SetSensitiveDetector(sensitiveLogicalVolume,detectorSD);
0330 
0331 
0332 }
0333