- Timestamp:
- Jun 14, 2010, 3:54:58 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/examples/advanced/hadrontherapy/src/HadrontherapyDetectorConstruction.cc
r1230 r1313 28 28 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 29 29 30 30 31 #include "G4SDManager.hh" 31 32 #include "G4RunManager.hh" 33 #include "G4GeometryManager.hh" 34 #include "G4SolidStore.hh" 35 #include "G4PhysicalVolumeStore.hh" 36 #include "G4LogicalVolumeStore.hh" 32 37 #include "G4Box.hh" 33 38 #include "G4LogicalVolume.hh" … … 42 47 #include "G4VisAttributes.hh" 43 48 #include "G4NistManager.hh" 49 50 #include "HadrontherapyDetectorConstruction.hh" 44 51 #include "HadrontherapyDetectorROGeometry.hh" 45 52 #include "HadrontherapyDetectorMessenger.hh" 46 53 #include "HadrontherapyDetectorSD.hh" 47 #include "HadrontherapyDetectorConstruction.hh"48 54 #include "HadrontherapyMatrix.hh" 55 #include "HadrontherapyAnalysisManager.hh" 56 57 #include <cmath> 49 58 50 59 ///////////////////////////////////////////////////////////////////////////// 51 60 HadrontherapyDetectorConstruction::HadrontherapyDetectorConstruction(G4VPhysicalVolume* physicalTreatmentRoom) 52 : motherPhys(physicalTreatmentRoom), 61 : motherPhys(physicalTreatmentRoom), // pointer to WORLD volume 53 62 detectorSD(0), detectorROGeometry(0), matrix(0), 54 phantom PhysicalVolume(0),55 detectorLogicalVolume(0), detectorPhysicalVolume(0),56 phantom SizeX(20.*cm), phantomSizeY(20.*cm), phantomSizeZ(20.*cm), // Default half dimensions57 detectorSizeX(2.*cm), detectorSizeY(2.*cm), detectorSizeZ(2.*cm),58 phantomPosition(20.*cm, 0.*cm, 0.*cm), 59 detectorToPhantomPosition(0.*cm,18.*cm,18.*cm)// Default displacement of the detector respect to the phantom60 { 63 phantom(0), detector(0), 64 phantomLogicalVolume(0), detectorLogicalVolume(0), 65 phantomPhysicalVolume(0), detectorPhysicalVolume(0), 66 aRegion(0) 67 { 68 HadrontherapyAnalysisManager::GetInstance(); 69 61 70 // NOTE! that the HadrontherapyDetectorConstruction class 62 71 // does NOT inherit from G4VUserDetectorConstruction G4 class … … 69 78 // Default detector voxels size 70 79 // 200 slabs along the beam direction (X) 71 sizeOfVoxelAlongX = 200 *um; 72 sizeOfVoxelAlongY = 2 * detectorSizeY; 73 sizeOfVoxelAlongZ = 2 * detectorSizeZ; 74 75 // Calculate (and eventually set) detector position by displacement, phantom size and detector size 76 SetDetectorPosition(); 77 78 // Build phantom and associated detector 79 ConstructPhantom(); 80 ConstructDetector(); 81 // Set number of the detector voxels along X Y and Z directions. 82 // This will construct also the sensitive detector, the ROGeometry 83 // and the matrix where the energy deposited is collected! 84 SetNumberOfVoxelBySize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 80 sizeOfVoxelAlongX = 200 *um; 81 sizeOfVoxelAlongY = 4 *cm; 82 sizeOfVoxelAlongZ = 4 *cm; 83 84 // Define here the material of the water phantom and of the detector 85 SetPhantomMaterial("G4_WATER"); 86 // Construct geometry (messenger commands) 87 SetDetectorSize(4.*cm, 4.*cm, 4.*cm); 88 SetPhantomSize(40. *cm, 40. *cm, 40. *cm); 89 SetPhantomPosition(G4ThreeVector(20. *cm, 0. *cm, 0. *cm)); 90 SetDetectorToPhantomPosition(G4ThreeVector(0. *cm, 18. *cm, 18. *cm)); 91 92 93 // Write virtual parameters to the real ones and check for consistency 94 UpdateGeometry(); 85 95 } 86 96 … … 88 98 HadrontherapyDetectorConstruction::~HadrontherapyDetectorConstruction() 89 99 { 90 delete detectorROGeometry; // This should be safe in C++ even if the argument is a NULL pointer100 delete detectorROGeometry; 91 101 delete matrix; 92 102 delete detectorMessenger; 93 103 } 94 104 105 ///////////////////////////////////////////////////////////////////////////// 106 // ConstructPhantom() is the method that reconstuct a water box (called phantom 107 // (or water phantom) in the usual Medical physicists slang). 108 // A water phantom can be considered a good 109 // approximation of a an human body. 95 110 void HadrontherapyDetectorConstruction::ConstructPhantom() 96 111 { 97 //---------------------------------------- 98 // Phantom: 99 // A box used to approximate tissues 100 //---------------------------------------- 101 102 G4bool isotopes = false; 103 G4Material* waterNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER", isotopes); 104 phantom = new G4Box("Phantom",phantomSizeX, phantomSizeY, phantomSizeZ); 112 // Definition of the solid volume of the Phantom 113 phantom = new G4Box("Phantom", 114 phantomSizeX/2, 115 phantomSizeY/2, 116 phantomSizeZ/2); 117 118 // Definition of the logical volume of the Phantom 105 119 phantomLogicalVolume = new G4LogicalVolume(phantom, 106 waterNist,120 phantomMaterial, 107 121 "phantomLog", 0, 0, 0); 108 122 123 // Definition of the physics volume of the Phantom 109 124 phantomPhysicalVolume = new G4PVPlacement(0, 110 125 phantomPosition, … … 119 134 red -> SetVisibility(true); 120 135 red -> SetForceSolid(true); 121 //red -> SetForceWireframe(true);136 //red -> SetForceWireframe(true); 122 137 phantomLogicalVolume -> SetVisAttributes(red); 123 138 } 124 139 125 140 ///////////////////////////////////////////////////////////////////////////// 141 // ConstructDetector() it the method the reconstruct a detector region 142 // inside the water phantom. It is a volume, located inside the water phantom 143 // and with two coincident faces: 144 // 145 // ************************** 146 // * water phantom * 147 // * * 148 // * * 149 // *--------------- * 150 // Beam * - * 151 // -----> * detector - * 152 // * - * 153 // *--------------- * 154 // * * 155 // * * 156 // * * 157 // ************************** 158 // 159 // The detector is the volume that can be dived in slices or voxelized 160 // and in it we can collect a number of usefull information: 161 // dose distribution, fluence distribution, LET and so on 126 162 void HadrontherapyDetectorConstruction::ConstructDetector() 127 163 { 128 //----------- 129 // Detector 130 //----------- 131 G4bool isotopes = false; 132 G4Material* waterNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER", isotopes); 133 detector = new G4Box("Detector",detectorSizeX,detectorSizeY,detectorSizeZ); 164 165 // Definition of the solid volume of the Detector 166 detector = new G4Box("Detector", 167 detectorSizeX/2, 168 detectorSizeY/2, 169 detectorSizeZ/2); 170 171 // Definition of the logic volume of the Phantom 134 172 detectorLogicalVolume = new G4LogicalVolume(detector, 135 waterNist,173 detectorMaterial, 136 174 "DetectorLog", 137 175 0,0,0); 138 // De tector is attached by default to the phantom face directly exposed to the beam139 detectorPhysicalVolume = new G4PVPlacement(0, 140 detectorPosition, // Setted by displacement141 "DetectorPhys",142 detectorLogicalVolume,143 phantomPhysicalVolume,144 false,0);145 176 // Definition of the physical volume of the Phantom 177 detectorPhysicalVolume = new G4PVPlacement(0, 178 detectorPosition, // Setted by displacement 179 "DetectorPhys", 180 detectorLogicalVolume, 181 phantomPhysicalVolume, 182 false,0); 183 146 184 // Visualisation attributes of the detector 147 185 skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. )); 148 186 skyBlue -> SetVisibility(true); 149 187 skyBlue -> SetForceSolid(true); 150 //skyBlue -> SetForceWireframe(true);188 //skyBlue -> SetForceWireframe(true); 151 189 detectorLogicalVolume -> SetVisAttributes(skyBlue); 190 191 // ************** 192 // Cut per Region 193 // ************** 152 194 153 } 154 ///////////////////////////////////////////////////////////////////////////// 195 // A smaller cut is fixed in the phantom to calculate the energy deposit with the 196 // required accuracy 197 if (!aRegion) 198 { 199 aRegion = new G4Region("DetectorLog"); 200 detectorLogicalVolume -> SetRegion(aRegion); 201 aRegion -> AddRootLogicalVolume(detectorLogicalVolume); 202 } 203 204 } 205 206 ///////////////////////////////////////////////////////////////////////////// 207 155 208 void HadrontherapyDetectorConstruction::ConstructSensitiveDetector(G4ThreeVector detectorToWorldPosition) 156 209 { 157 210 // Install new Sensitive Detector and ROGeometry 158 211 delete detectorROGeometry; // this should be safe in C++ also if we have a NULL pointer 159 212 //if (detectorSD) detectorSD->PrintAll(); 213 //delete detectorSD; 160 214 // Sensitive Detector and ReadOut geometry definition 161 215 G4SDManager* sensitiveDetectorManager = G4SDManager::GetSDMpointer(); 162 216 163 G4String sensitiveDetectorName = "Detector";217 static G4String sensitiveDetectorName = "Detector"; 164 218 if (!detectorSD) 165 219 { … … 168 222 } 169 223 // The Read Out Geometry is instantiated 170 G4String ROGeometryName = "DetectorROGeometry";224 static G4String ROGeometryName = "DetectorROGeometry"; 171 225 detectorROGeometry = new HadrontherapyDetectorROGeometry(ROGeometryName, 172 226 detectorToWorldPosition, 173 detectorSizeX ,174 detectorSizeY ,175 detectorSizeZ ,227 detectorSizeX/2, 228 detectorSizeY/2, 229 detectorSizeZ/2, 176 230 numberOfVoxelsAlongX, 177 231 numberOfVoxelsAlongY, … … 193 247 } 194 248 } 195 249 void HadrontherapyDetectorConstruction::ParametersCheck() 250 { 251 // Check phantom/detector sizes & relative position 252 if (!IsInside(detectorSizeX, 253 detectorSizeY, 254 detectorSizeZ, 255 phantomSizeX, 256 phantomSizeY, 257 phantomSizeZ, 258 detectorToPhantomPosition 259 )) 260 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector is not fully inside Phantom!"); 261 262 // Check Detector sizes respect to the voxel ones 263 264 if ( detectorSizeX < sizeOfVoxelAlongX) { 265 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector X size must be bigger or equal than that of Voxel X"); 266 } 267 if ( detectorSizeY < sizeOfVoxelAlongY) { 268 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector Y size must be bigger or equal than that of Voxel Y"); 269 } 270 if ( detectorSizeZ < sizeOfVoxelAlongZ) { 271 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector Z size must be bigger or equal than that of Voxel Z"); 272 } 273 274 } 196 275 ///////////////// 197 276 // MESSENGERS // 198 277 //////////////// 199 G4bool HadrontherapyDetectorConstruction::SetNumberOfVoxelBySize(G4double sizeX, G4double sizeY, G4double sizeZ) 200 { 201 // Only change positive dimensions 202 // XXX numberOfVoxels must be an integer, warn the user 203 204 if (sizeX > 0) 278 279 G4bool HadrontherapyDetectorConstruction::SetPhantomMaterial(G4String material) 280 { 281 282 if (G4Material* pMat = G4NistManager::Instance()->FindOrBuildMaterial(material, false) ) 205 283 { 206 if (sizeX > 2*detectorSizeX) 284 phantomMaterial = pMat; 285 detectorMaterial = pMat; 286 if (detectorLogicalVolume && phantomLogicalVolume) 207 287 { 208 G4cout << "WARNING: Voxel X size must be smaller or equal than that of detector X" << G4endl; 209 return false; 288 detectorLogicalVolume -> SetMaterial(pMat); 289 phantomLogicalVolume -> SetMaterial(pMat); 290 291 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 292 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 293 G4cout << "The material of Phantom/Detector has been changed to " << material << G4endl; 210 294 } 211 // Round to the nearest integer 212 numberOfVoxelsAlongX = lrint(2 * detectorSizeX / sizeX); 213 sizeOfVoxelAlongX = (2 * detectorSizeX / numberOfVoxelsAlongX ); 214 if(sizeOfVoxelAlongX!=sizeX) G4cout << "Rounding " << 215 G4BestUnit(sizeX, "Length") << " to " << 216 G4BestUnit(sizeOfVoxelAlongX, "Length") << G4endl; 217 } 218 219 if (sizeY > 0) 295 } 296 else 220 297 { 221 if (sizeY > 2*detectorSizeY) 222 { 223 G4cout << "WARNING: Voxel Y size must be smaller or equal than that of detector Y" << G4endl; 224 return false; 225 } 226 numberOfVoxelsAlongY = lrint(2 * detectorSizeY / sizeY); 227 sizeOfVoxelAlongY = (2 * detectorSizeY / numberOfVoxelsAlongY ); 228 if(sizeOfVoxelAlongY!=sizeY) G4cout << "Rounding " << 229 G4BestUnit(sizeY, "Length") << " to " << 230 G4BestUnit(sizeOfVoxelAlongY, "Length") << G4endl; 231 } 232 if (sizeZ > 0) 298 G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials" 299 " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl; 300 G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl; 301 return false; 302 } 303 304 return true; 305 } 306 ///////////////////////////////////////////////////////////////////////////// 307 void HadrontherapyDetectorConstruction::SetPhantomSize(G4double sizeX, G4double sizeY, G4double sizeZ) 308 { 309 if (sizeX > 0.) phantomSizeX = sizeX; 310 if (sizeY > 0.) phantomSizeY = sizeY; 311 if (sizeZ > 0.) phantomSizeZ = sizeZ; 312 } 313 ///////////////////////////////////////////////////////////////////////////// 314 ///////////////////////////////////////////////////////////////////////////// 315 void HadrontherapyDetectorConstruction::SetDetectorSize(G4double sizeX, G4double sizeY, G4double sizeZ) 316 { 317 if (sizeX > 0.) {detectorSizeX = sizeX;} 318 if (sizeY > 0.) {detectorSizeY = sizeY;} 319 if (sizeZ > 0.) {detectorSizeZ = sizeZ;} 320 SetVoxelSize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 321 } 322 ///////////////////////////////////////////////////////////////////////////// 323 324 void HadrontherapyDetectorConstruction::SetVoxelSize(G4double sizeX, G4double sizeY, G4double sizeZ) 325 { 326 if (sizeX > 0.) {sizeOfVoxelAlongX = sizeX;} 327 if (sizeY > 0.) {sizeOfVoxelAlongY = sizeY;} 328 if (sizeZ > 0.) {sizeOfVoxelAlongZ = sizeZ;} 329 } 330 void HadrontherapyDetectorConstruction::SetPhantomPosition(G4ThreeVector pos) 331 { 332 phantomPosition = pos; 333 } 334 335 ///////////////////////////////////////////////////////////////////////////// 336 void HadrontherapyDetectorConstruction::SetDetectorToPhantomPosition(G4ThreeVector displ) 337 { 338 detectorToPhantomPosition = displ; 339 } 340 ///////////////////////////////////////////////////////////////////////////// 341 void HadrontherapyDetectorConstruction::UpdateGeometry() 342 { 343 ParametersCheck(); 344 345 //G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 346 G4GeometryManager::GetInstance() -> OpenGeometry(); 347 if (phantom) 233 348 { 234 if (sizeZ > 2*detectorSizeZ) 235 { 236 G4cout << "WARNING: Voxel Z size must be smaller or equal than that of detector Z" << G4endl; 237 return false; 238 } 239 numberOfVoxelsAlongZ = lrint(2 * detectorSizeZ / sizeZ); 240 sizeOfVoxelAlongZ = (2 * detectorSizeZ / numberOfVoxelsAlongZ ); 241 if(sizeOfVoxelAlongZ!=sizeZ) G4cout << "Rounding " << 242 G4BestUnit(sizeZ, "Length") << " to " << 243 G4BestUnit(sizeOfVoxelAlongZ, "Length") << G4endl; 244 } 245 246 G4cout << "The (X, Y, Z) sizes of the Voxels are: (" << 247 G4BestUnit(sizeOfVoxelAlongX, "Length") << ", " << 248 G4BestUnit(sizeOfVoxelAlongY, "Length") << ", " << 249 G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl; 349 phantom -> SetXHalfLength(phantomSizeX/2); 350 phantom -> SetYHalfLength(phantomSizeY/2); 351 phantom -> SetZHalfLength(phantomSizeZ/2); 352 phantomPhysicalVolume -> SetTranslation(phantomPosition); 353 } 354 else ConstructPhantom(); 355 356 // Get the center of the detector 357 SetDetectorPosition(); 358 if (detector) 359 { 360 detector -> SetXHalfLength(detectorSizeX/2); 361 detector -> SetYHalfLength(detectorSizeY/2); 362 detector -> SetZHalfLength(detectorSizeZ/2); 363 detectorPhysicalVolume -> SetTranslation(detectorPosition); 364 } 365 else ConstructDetector(); 366 367 // Round to nearest integer number of voxel 368 numberOfVoxelsAlongX = lrint(detectorSizeX / sizeOfVoxelAlongX); 369 sizeOfVoxelAlongX = ( detectorSizeX / numberOfVoxelsAlongX ); 370 371 numberOfVoxelsAlongY = lrint(detectorSizeY / sizeOfVoxelAlongY); 372 sizeOfVoxelAlongY = ( detectorSizeY / numberOfVoxelsAlongY ); 373 374 numberOfVoxelsAlongZ = lrint(detectorSizeZ / sizeOfVoxelAlongZ); 375 sizeOfVoxelAlongZ = ( detectorSizeZ / numberOfVoxelsAlongZ ); 376 377 //G4cout << "*************** DetectorToWorldPosition " << GetDetectorToWorldPosition()/cm << "\n"; 378 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 379 380 volumeOfVoxel = sizeOfVoxelAlongX * sizeOfVoxelAlongY * sizeOfVoxelAlongZ; 381 massOfVoxel = detectorMaterial -> GetDensity() * volumeOfVoxel; 382 // This will clear the existing matrix (together with all data inside it)! 383 matrix = HadrontherapyMatrix::GetInstance(numberOfVoxelsAlongX, 384 numberOfVoxelsAlongY, 385 numberOfVoxelsAlongZ, 386 massOfVoxel); 387 388 // Inform the kernel about the new geometry 389 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 390 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 391 392 PrintParameters(); 393 } 394 395 void HadrontherapyDetectorConstruction::PrintParameters() 396 { 397 398 G4cout << "The (X,Y,Z) dimensions of the phantom are : (" << 399 G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ',' << 400 G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ',' << 401 G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl; 402 403 G4cout << "The (X,Y,Z) dimensions of the detector are : (" << 404 G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ',' << 405 G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ',' << 406 G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl; 407 408 G4cout << "Displacement between Phantom and World is: "; 409 G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") << 410 "DY= "<< G4BestUnit(phantomPosition.getY(),"Length") << 411 "DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl; 412 413 G4cout << "The (X,Y,Z) sizes of the Voxels are: (" << 414 G4BestUnit(sizeOfVoxelAlongX, "Length") << ',' << 415 G4BestUnit(sizeOfVoxelAlongY, "Length") << ',' << 416 G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl; 250 417 251 418 G4cout << "The number of Voxels along (X,Y,Z) is: (" << 252 numberOfVoxelsAlongX << ", " << 253 numberOfVoxelsAlongY << ", " << 254 numberOfVoxelsAlongZ << ')' << G4endl; 255 256 // This will clear the existing matrix (together with data inside it)! 257 matrix = HadrontherapyMatrix::getInstance(numberOfVoxelsAlongX, 258 numberOfVoxelsAlongY, 259 numberOfVoxelsAlongZ); 260 261 // Here construct the Sensitive Detector and Read Out Geometry 262 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 263 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 264 return true; 265 } 266 ///////////////////////////////////////////////////////////////////////////// 267 G4bool HadrontherapyDetectorConstruction::SetDetectorSize(G4double sizeX, G4double sizeY, G4double sizeZ) 268 { 269 // Check that the detector stay inside the phantom 270 if (sizeX > 0 && sizeX < sizeOfVoxelAlongX) {G4cout << "WARNING: Detector X size must be bigger than that of Voxel X" << G4endl; return false;} 271 if (sizeY > 0 && sizeY < sizeOfVoxelAlongY) {G4cout << "WARNING: Detector Y size must be bigger than that of Voxel Y" << G4endl; return false;} 272 if (sizeZ > 0 && sizeZ < sizeOfVoxelAlongZ) {G4cout << "WARNING: Detector Z size must be bigger than that of Voxel Z" << G4endl; return false;} 273 274 if (!IsInside(sizeX/2, 275 sizeY/2, 276 sizeZ/2, 277 phantomSizeX, 278 phantomSizeY, 279 phantomSizeZ, 280 detectorToPhantomPosition)) 281 {return false;} 282 // Negative or null values mean don't change it! 283 if (sizeX > 0) { 284 detectorSizeX = sizeX/2; 285 detector -> SetXHalfLength(detectorSizeX); 286 } 287 288 if (sizeY > 0) { 289 detectorSizeY = sizeY/2; 290 detector -> SetYHalfLength(detectorSizeY); 291 } 292 293 if (sizeZ > 0) { 294 detectorSizeZ = sizeZ/2; 295 detector -> SetZHalfLength(detectorSizeZ); 296 } 297 298 299 G4cout << "The (X, Y, Z) dimensions of the detector are : (" << 300 G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ", " << 301 G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ", " << 302 G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl; 303 // Adjust detector position 304 SetDetectorPosition(); 305 // Adjust voxels number accordingly to new detector geometry 306 // Matrix will be re-instantiated! 307 // Voxels and ROGeometry must follow the detector! 308 SetNumberOfVoxelBySize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 309 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 310 return true; 311 } 312 313 ///////////////////////////////////////////////////////////////////////////// 314 G4bool HadrontherapyDetectorConstruction::SetPhantomSize(G4double sizeX, G4double sizeY, G4double sizeZ) 315 { 316 317 if (!IsInside(detectorSizeX, 318 detectorSizeY, 319 detectorSizeZ, 320 sizeX/2,//method parameters 321 sizeY/2, 322 sizeZ/2, 323 detectorToPhantomPosition 324 )) 325 return false; 326 327 // Only change positive dimensions 328 if (sizeX > 0) { 329 phantomSizeX = sizeX/2; 330 phantom -> SetXHalfLength(phantomSizeX); 331 } 332 if (sizeY > 0) { 333 phantomSizeY = sizeY/2; 334 phantom -> SetYHalfLength(phantomSizeY); 335 } 336 337 if (sizeZ > 0) { 338 phantomSizeZ = sizeZ/2; 339 phantom -> SetZHalfLength(phantomSizeZ); 340 } 341 342 343 G4cout << "The (X, Y, Z) dimensions of the phantom are : (" << 344 G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ", " << 345 G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ", " << 346 G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl; 347 //G4cout << '\n' << "Coordinate volume: " << phantomPhysicalVolume -> GetTranslation() << G4endl; 348 // Adjust detector position inside phantom 349 SetDetectorPosition(); 350 351 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 352 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 353 return true; 354 } 355 ///////////////////////////////////////////////////////////////////////////// 356 G4bool HadrontherapyDetectorConstruction::SetPhantomPosition(G4ThreeVector displacement) 357 { 358 // Set Phantom position respect to the World 359 // TODO check for overlap! 360 phantomPosition = displacement; 361 if (phantomPhysicalVolume) 362 { 363 phantomPhysicalVolume -> SetTranslation(phantomPosition); 364 G4cout << "Displacement between Phantom and World is: "; 365 G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") << ", " << 366 "DY= "<< G4BestUnit(phantomPosition.getY(),"Length") << ", " << 367 "DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl; 368 369 // Redraw ROGeometry! 370 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 371 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 372 } 373 return true; 374 } 375 376 ///////////////////////////////////////////////////////////////////////////// 377 G4bool HadrontherapyDetectorConstruction::SetDetectorToPhantomPosition(G4ThreeVector displacement) 378 { 379 // Ignore negative values 380 if (displacement[0] < 0.) displacement[0] = detectorToPhantomPosition[0]; 381 if (displacement[1] < 0.) displacement[1] = detectorToPhantomPosition[1]; 382 if (displacement[2] < 0.) displacement[2] = detectorToPhantomPosition[2]; 383 384 if (!IsInside(detectorSizeX, 385 detectorSizeY, 386 detectorSizeZ, 387 phantomSizeX, 388 phantomSizeY, 389 phantomSizeZ, 390 displacement // method parameter! 391 )) 392 {return false;} 393 detectorToPhantomPosition = displacement; 394 395 // Adjust detector position inside phantom 396 SetDetectorPosition(); 397 398 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 399 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 400 return true; 401 } 419 numberOfVoxelsAlongX << ',' << 420 numberOfVoxelsAlongY <<',' << 421 numberOfVoxelsAlongZ << ')' << G4endl; 422 423 }
Note: See TracChangeset
for help on using the changeset viewer.