Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IORTDetectorConstruction.cc
Go to the documentation of this file.
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 IORT, a Geant4-based application
27 //
28 // Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
29 // Contributor Authors: S.Guatelli(e)
30 // Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
31 //
32 // (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
33 // (b) IBFM-CNR , Segrate (Milano), Italy
34 // (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
35 // (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
36 // (e) University of Wallongong, Australia
37 //
38 // *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
40 
41 #include <cmath>
43 
44 #include "globals.hh"
45 #include "G4SDManager.hh"
46 #include "G4RunManager.hh"
47 #include "G4GeometryManager.hh"
48 #include "G4SolidStore.hh"
49 #include "G4PhysicalVolumeStore.hh"
50 #include "G4LogicalVolumeStore.hh"
51 #include "G4Box.hh"
52 #include "G4LogicalVolume.hh"
53 #include "G4ThreeVector.hh"
54 #include "G4PVPlacement.hh"
55 #include "G4Transform3D.hh"
56 #include "G4RotationMatrix.hh"
57 #include "G4Colour.hh"
58 #include "G4UserLimits.hh"
59 #include "G4UnitsTable.hh"
60 #include "G4VisAttributes.hh"
61 #include "G4NistManager.hh"
64 #include "IORTDetectorMessenger.hh"
65 #include "IORTDetectorSD.hh"
66 #include "IORTMatrix.hh"
67 #include "IORTAnalysisManager.hh"
68 #include "G4Tubs.hh"
69 
72  : motherPhys(physicalTreatmentRoom), // pointer to WORLD volume
73  detectorSD(0), detectorROGeometry(0), matrix(0),
74  phantom(0), detector(0),
75  phantomLogicalVolume(0), detectorLogicalVolume(0),
76  phantomPhysicalVolume(0), detectorPhysicalVolume(0),
77  aRegion(0),
78 
79  solidDiscoIORT0(0),
80  logicDiscoIORT0(0),
81  physiDiscoIORT0(0),
82 
83  solidDiscoIORT(0),
84  logicDiscoIORT(0),
85  physiDiscoIORT(0),
86 
87  solidDiscoIORT1(0),
88  logicDiscoIORT1(0),
89  physiDiscoIORT1(0)
90 
91 {
93 
94  /* NOTE! that the IORTDetectorConstruction class
95  * does NOT inherit from G4VUserDetectorConstruction G4 class
96  * So the Construct() mandatory virtual method is inside another geometric class
97  * like the collimatorXXBeamLIne, ...
98  */
99 
100  // Messenger to change parameters of the phantom/detector geometry
101  detectorMessenger = new IORTDetectorMessenger(this);
102 
103  // Default detector voxels size
104  // 200 slabs along the beam direction (X)
105  sizeOfVoxelAlongX = 0.5 *CLHEP::mm; //
106  sizeOfVoxelAlongY = 0.5 *CLHEP::mm; //
107  sizeOfVoxelAlongZ = 0.5 *CLHEP::mm; //
108 
109  // Define here the material of the water phantom and of the detector
110  SetPhantomMaterial("G4_WATER");
111  // Construct geometry (messenger commands)
112  SetDetectorSize(7.*CLHEP::cm, 15.*CLHEP::cm, 15.*CLHEP::cm);
113  SetPhantomSize(20. *CLHEP::cm, 20. *CLHEP::cm, 20. *CLHEP::cm);
114  SetPhantomPosition(G4ThreeVector(4.5 *CLHEP::cm, 0. *CLHEP::cm, 0. *CLHEP::cm));
115  SetDetectorToPhantomPosition(G4ThreeVector(0. *CLHEP::cm, 2.5 *CLHEP::cm, 2.5 *CLHEP::cm));
116 
117  // Default protection disc geometry and materials
118  SetOuterRadiusDiscoIORT (40. *CLHEP::mm);
119  SetinnerRadiusDiscoIORT (0.*CLHEP::mm);
120  SetheightDiscoIORT (2.0*CLHEP::mm);
121  SetDiscoXPositionIORT (-11.0*CLHEP::mm);
122  SetDiscoYPositionIORT (0.0*CLHEP::mm);
123  SetDiscoZPositionIORT (0.0*CLHEP::mm);
124  SetDiscoMaterialIORT("G4_WATER");
125 
126  SetOuterRadiusDiscoIORT1 (40. *CLHEP::mm);
127  SetinnerRadiusDiscoIORT1 (0.*CLHEP::mm);
128  SetheightDiscoIORT1 (1.0*CLHEP::mm);
129  SetDiscoXPositionIORT1 (-8.0*CLHEP::mm);
130  SetDiscoMaterialIORT1("G4_WATER");
131 
132  SetAngleDiscoIORT0 (90.0 *CLHEP::deg);
133 
134  // Write virtual parameters to the real ones and check for consistency
135  UpdateGeometry();
136 }
137 
140 {
141  delete detectorROGeometry;
142  delete matrix;
143  delete detectorMessenger;
144 }
145 
147 // ConstructPhantom() is the method that reconstuct a water box (called phantom
148 // (or water phantom) in the usual Medical physicists slang).
149 // A water phantom can be considered a good
150 // approximation of a an human body.
151 void IORTDetectorConstruction::ConstructPhantom()
152 {
153  // Definition of the solid volume of the Phantom
154  phantom = new G4Box("Phantom",
155  phantomSizeX/2,
156  phantomSizeY/2,
157  phantomSizeZ/2);
158 
159 // Definition of the logical volume of the Phantom
160  phantomLogicalVolume = new G4LogicalVolume(phantom,
161  phantomMaterial,
162  "phantomLog", 0, 0, 0);
163 
164  // Definition of the physics volume of the Phantom
165  phantomPhysicalVolume = new G4PVPlacement(0,
166  phantomPosition,
167  "phantomPhys",
168  phantomLogicalVolume,
169  motherPhys,
170  false,
171  0);
172 
173 // Visualisation attributes of the phantom
174  red = new G4VisAttributes(G4Colour(255/255., 0/255. ,0/255.));
175  red -> SetVisibility(true);
176  //red -> SetForceSolid(true);
177  //red -> SetForceWireframe(true);
178  phantomLogicalVolume -> SetVisAttributes(red);
179  //phantomLogicalVolume -> SetVisAttributes(G4VisAttributes::Invisible);
180 }
181 
183 // ConstructDetector() it the method the reconstruct a detector region
184 // inside the water phantom. It is a volume, located inside the water phantom
185 // and with two coincident faces:
186 //
187 // **************************
188 // * water phantom *
189 // * *
190 // * *
191 // *--------------- *
192 // Beam * - *
193 // -----> * detector - *
194 // * - *
195 // *--------------- *
196 // * *
197 // * *
198 // * *
199 // **************************
200 //
201 // The detector is the volume that can be dived in slices or voxelized
202 // and in it we can collect a number of usefull information:
203 // dose distribution, fluence distribution, LET and so on
204 void IORTDetectorConstruction::ConstructDetector()
205 {
206 
207  // Definition of the solid volume of the Detector
208  detector = new G4Box("Detector",
209  detectorSizeX/2,
210  detectorSizeY/2,
211  detectorSizeZ/2);
212 
213  // Definition of the logic volume of the Phantom
214  detectorLogicalVolume = new G4LogicalVolume(detector,
215  detectorMaterial,
216  "DetectorLog",
217  0,0,0);
218 // Definition of the physical volume of the Phantom
219  detectorPhysicalVolume = new G4PVPlacement(0,
220  detectorPosition, // Setted by displacement
221  "DetectorPhys",
222  detectorLogicalVolume,
223  phantomPhysicalVolume,
224  false,0);
225 
226 // Visualisation attributes of the detector
227  //skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
228  G4VisAttributes * skyBlue1 = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
229  //skyBlue1 -> SetForceWireframe(true);
230  //skyBlue1 -> SetForceSolid(true);
231  //skyBlue -> SetVisibility(true);
232  //skyBlue -> SetForceSolid(true);
233  //skyBlue -> SetForceWireframe(false);
234  //detectorLogicalVolume -> SetVisAttributes(skyBlue);
235  detectorLogicalVolume -> SetVisAttributes(skyBlue1);
236 
237  // detectorLogicalVolume -> SetVisAttributes(G4VisAttributes::Invisible);
238 
239 
240  // **************
241  // Cut per Region
242  // **************
243 
244  // A smaller cut is fixed in the phantom to calculate the energy deposit with the
245  // required accuracy
246  if (!aRegion)
247  {
248  aRegion = new G4Region("DetectorLog");
249  detectorLogicalVolume -> SetRegion(aRegion);
250  aRegion -> AddRootLogicalVolume(detectorLogicalVolume);
251  }
252 
253 }
254 
256 {
257 // ---------------------------------------------------------------//
258  // 6.0 mm Protection Discs Volume //
259  // ---------------------------------------------------------------//
260  const G4double startAngleDiscoIORT0 = 0.*CLHEP::deg;
261  const G4double spanningAngleDiscoIORT0 = 360.*CLHEP::deg;
262 
263  //G4double phi0 = 180. *CLHEP::deg; // messenger
264 
265  // Matrix definition for a rotation (deg).
266  G4RotationMatrix rm0;
267  rm0.rotateY(AngleDiscoIORT0);
268 
269 
270  solidDiscoIORT0 = new G4Tubs("DiscoIORT0", innerRadiusDiscoIORT,
271  OuterRadiusDiscoIORT,
272  (heightDiscoIORT + heightDiscoIORT1),
273  startAngleDiscoIORT0,
274  spanningAngleDiscoIORT0);
275 
276  G4LogicalVolume* logDiscoIORT0 = new G4LogicalVolume(solidDiscoIORT0,
277  detectorMaterial, "DiscoIORT0Log", 0, 0, 0);
278 
279  physiDiscoIORT0 = new G4PVPlacement(G4Transform3D(rm0, G4ThreeVector((DiscoXPositionIORT + heightDiscoIORT1),DiscoYPositionIORT,DiscoZPositionIORT)),
280  "DiscoIORT0Phys", logDiscoIORT0, detectorPhysicalVolume, false, 0);
281 
282  white = new G4VisAttributes( G4Colour());
283  white -> SetVisibility(true);
284  // white -> SetForceSolid(true);
285  logDiscoIORT0 -> SetVisAttributes(white);
286 
287 // ---------------------------------------------------------------//
288  // 4.0 mm Aluminium Protection Disc //
289  // ---------------------------------------------------------------//
290  //G4bool isotopes = false;
291  // G4Material* leadNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb", isotopes);
292  // DiscoMaterialIORT = leadNist; // messenger
293  gray = new G4VisAttributes( G4Colour(0.5, 0.5, 0.5 ));
294  gray-> SetVisibility(true);
295  //gray -> SetForceWireframe(true);
296  //gray-> SetForceSolid(true);
297 
298  gray1 = new G4VisAttributes( G4Colour(0.7, 0.7, 0.7 ));
299  gray1-> SetVisibility(true);
300  //gray1 -> SetForceWireframe(true);
301  //gray1-> SetForceSolid(true);
302  // const G4double OuterRadiusDiscoIORT = 35. *CLHEP::mm; // messenger
303  // const G4double innerRadiusDiscoIORT = 0.*CLHEP::mm; // messenger
304  // const G4double heightDiscoIORT = 3.0*CLHEP::mm; // messenger
305  const G4double startAngleDiscoIORT = 0.*CLHEP::deg;
306  const G4double spanningAngleDiscoIORT = 360.*CLHEP::deg;
307  // const G4double DiscoXPositionIORT = -14.0*CLHEP::mm; // messenger
308 
309 //G4Material* DiscoMaterialIORT = G4NistManager::Instance()->FindOrBuildMaterial("G4_PLEXIGLASS", isotopes);// messenger
310 
311 
312  G4double phi = 0. *CLHEP::deg;
313 
314  // Matrix definition for a 90 deg rotation. Also used for other volumes
315  G4RotationMatrix rm;
316  rm.rotateY(phi);
317 
318 
319  solidDiscoIORT = new G4Tubs("DiscoIORT", innerRadiusDiscoIORT,
320  OuterRadiusDiscoIORT,
321  heightDiscoIORT,
322  startAngleDiscoIORT,
323  spanningAngleDiscoIORT);
324 
325  G4LogicalVolume* logDiscoIORT = new G4LogicalVolume(solidDiscoIORT,
326  DiscoMaterialIORT, "DiscoIORTLog", 0, 0, 0);
327 
328  physiDiscoIORT = new G4PVPlacement(G4Transform3D(rm, G4ThreeVector(0.,0.,(- heightDiscoIORT1))),
329  "DiscoIORTPhys", logDiscoIORT, physiDiscoIORT0, false, 0);
330 
331  logDiscoIORT -> SetVisAttributes(gray1);
332 
333 
334  // ---------------------------------------------------------------//
335  // 2.0 mm Lead Protection Disc //
336  // ---------------------------------------------------------------//
337 
338  // const G4double OuterRadiusDiscoIORT1 = 35. *CLHEP::mm;
339  // const G4double innerRadiusDiscoIORT1 = 0.*CLHEP::mm;
340  // const G4double heightDiscoIORT1 = 0.5*CLHEP::mm;
341  const G4double startAngleDiscoIORT1 = 0.*CLHEP::deg;
342  const G4double spanningAngleDiscoIORT1 = 360.*CLHEP::deg;
343 // const G4double DiscoXPositionIORT1 = -10.5*CLHEP::mm; messenger
344 // G4Material* DiscoMaterialIORT1 = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu", isotopes);// messenger
345 
346 
347 
348  solidDiscoIORT1 = new G4Tubs("DiscoIORT1", innerRadiusDiscoIORT1,
349  OuterRadiusDiscoIORT1,
350  heightDiscoIORT1,
351  startAngleDiscoIORT1,
352  spanningAngleDiscoIORT1);
353 
354  G4LogicalVolume* logDiscoIORT1 = new G4LogicalVolume(solidDiscoIORT1,
355  DiscoMaterialIORT1, "DiscoIORTLog1", 0, 0, 0);
356 
357  physiDiscoIORT1 = new G4PVPlacement(G4Transform3D(rm, G4ThreeVector(0.,0.,heightDiscoIORT)),
358  "DiscoIORTPhys1", logDiscoIORT1, physiDiscoIORT0, false, 0);
359  white = new G4VisAttributes( G4Colour());
360  white -> SetVisibility(true);
361  white -> SetForceSolid(true);
362  logDiscoIORT1 -> SetVisAttributes(gray);
363 
364 }
366 
367 void IORTDetectorConstruction::ConstructSensitiveDetector(G4ThreeVector detectorToWorldPosition)
368 {
369  // Install new Sensitive Detector and ROGeometry
370  delete detectorROGeometry; // this should be safe in C++ also if we have a NULL pointer
371  //if (detectorSD) detectorSD->PrintAll();
372  //delete detectorSD;
373  // Sensitive Detector and ReadOut geometry definition
374  G4SDManager* sensitiveDetectorManager = G4SDManager::GetSDMpointer();
375 
376  static G4String sensitiveDetectorName = "Detector";
377  if (!detectorSD)
378  {
379  // The sensitive detector is instantiated
380  detectorSD = new IORTDetectorSD(sensitiveDetectorName);
381  }
382  // The Read Out Geometry is instantiated
383  static G4String ROGeometryName = "DetectorROGeometry";
384  detectorROGeometry = new IORTDetectorROGeometry(ROGeometryName,
385  detectorToWorldPosition,
386  detectorSizeX/2, // controllare che sia necessario /2
387  detectorSizeY/2, // CONFERMATO!!! ci vuole!!!
388  detectorSizeZ/2,
389  numberOfVoxelsAlongX,
390  numberOfVoxelsAlongY,
391  numberOfVoxelsAlongZ);
392 
393  G4cout << "Instantiating new Read Out Geometry \"" << ROGeometryName << "\""<< G4endl;
394  // This will invoke Build() IORTDetectorROGeometry virtual method
395  detectorROGeometry -> BuildROGeometry();
396  // Attach ROGeometry to SDetector
397  detectorSD -> SetROgeometry(detectorROGeometry);
398  //sensitiveDetectorManager -> Activate(sensitiveDetectorName, true);
399  if (!sensitiveDetectorManager -> FindSensitiveDetector(sensitiveDetectorName, false))
400  {
401  G4cout << "Registering new DetectorSD \"" << sensitiveDetectorName << "\""<< G4endl;
402  // Register user SD
403  sensitiveDetectorManager -> AddNewDetector(detectorSD);
404  // Attach SD to detector logical volume
405  detectorLogicalVolume -> SetSensitiveDetector(detectorSD);
406  }
407 }
408 void IORTDetectorConstruction::ParametersCheck()
409 {
410  // Check phantom/detector sizes & relative position
411  if (!IsInside(detectorSizeX,
412  detectorSizeY,
413  detectorSizeZ,
414  phantomSizeX,
415  phantomSizeY,
416  phantomSizeZ,
417  detectorToPhantomPosition
418  ))
419  G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0001", FatalException, "Error: Detector is not fully inside Phantom!");
420 
421  // Check Detector sizes respect to the voxel ones
422 
423  if ( detectorSizeX < sizeOfVoxelAlongX) {
424  G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0002", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel X");
425  }
426  if ( detectorSizeY < sizeOfVoxelAlongY) {
427  G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0003", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel Y");
428  }
429  if ( detectorSizeZ < sizeOfVoxelAlongZ) {
430  G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0004", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel Z");
431  }
432 
433 }
435 // MESSENGERS //
437 
439 {
440 
441  if (G4Material* pMat = G4NistManager::Instance()->FindOrBuildMaterial(material, false) )
442  {
443  phantomMaterial = pMat;
444  detectorMaterial = pMat;
445  if (detectorLogicalVolume && phantomLogicalVolume)
446  {
447  detectorLogicalVolume -> SetMaterial(pMat);
448  phantomLogicalVolume -> SetMaterial(pMat);
449 
450  G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
451  G4RunManager::GetRunManager() -> GeometryHasBeenModified();
452  G4cout << "The material of Phantom/Detector has been changed to " << material << G4endl;
453  }
454  }
455  else
456  {
457  G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials"
458  " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
459  G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
460  return false;
461  }
462 
463  return true;
464 }
465 
467 {
468 
469  if (G4Material* dMat = G4NistManager::Instance()->FindOrBuildMaterial(material, false) )
470  {
471  DiscoMaterialIORT = dMat;
472 
473  if (logicDiscoIORT)
474  {
475  logicDiscoIORT -> SetMaterial(dMat);
476 
477  G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
478  G4RunManager::GetRunManager() -> GeometryHasBeenModified();
479  G4cout << "The material of Protection disc 1 has been changed to " << material << G4endl;
480  }
481  }
482  else
483  {
484  G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials"
485  " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
486  G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
487  return false;
488  }
489 
490  return true;
491 }
492 
494 {
495 
496  if (G4Material* d1Mat = G4NistManager::Instance()->FindOrBuildMaterial(material, false) )
497  {
498  DiscoMaterialIORT1 = d1Mat;
499 
500  if (logicDiscoIORT1)
501  {
502  logicDiscoIORT1 -> SetMaterial(d1Mat);
503 
504  G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
505  G4RunManager::GetRunManager() -> GeometryHasBeenModified();
506  G4cout << "The material of Protection disc 2 has been changed to " << material << G4endl;
507  }
508  }
509  else
510  {
511  G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials"
512  " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
513  G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
514  return false;
515  }
516 
517  return true;
518 }
521 {
522  if (sizeX > 0.) phantomSizeX = sizeX;
523  if (sizeY > 0.) phantomSizeY = sizeY;
524  if (sizeZ > 0.) phantomSizeZ = sizeZ;
525 }
529 {
530  if (sizeX > 0.) {detectorSizeX = sizeX;}
531  if (sizeY > 0.) {detectorSizeY = sizeY;}
532  if (sizeZ > 0.) {detectorSizeZ = sizeZ;}
533  SetVoxelSize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ);
534 }
536 
538 {
539  if (sizeX > 0.) {sizeOfVoxelAlongX = sizeX;}
540  if (sizeY > 0.) {sizeOfVoxelAlongY = sizeY;}
541  if (sizeZ > 0.) {sizeOfVoxelAlongZ = sizeZ;}
542 }
544 {
545  phantomPosition = pos;
546 }
547 
550 {
551  detectorToPhantomPosition = displ;
552 }
554 
556 {
557  if (outerr > 0.) {OuterRadiusDiscoIORT = outerr;}
558 
559 }
560 
562 {
563  if (innerr > 0.) {innerRadiusDiscoIORT = innerr;}
564 
565 }
566 
568 {
569  if (height > 0.) {heightDiscoIORT = height;}
570 
571 }
572 
574 {
575 
576  DiscoXPositionIORT = xpos;
577 
578 }
579 
581 {
582 
583  DiscoYPositionIORT = ypos;
584 
585 }
586 
588 {
589 
590  DiscoZPositionIORT = zpos;
591 
592 }
593 
595 {
596  if (outerr > 0.) {OuterRadiusDiscoIORT1 = outerr;}
597 
598 }
599 
601 {
602  if (innerr > 0.) {innerRadiusDiscoIORT1 = innerr;}
603 
604 }
605 
607 {
608  if (height > 0.) {heightDiscoIORT1 = height;}
609 
610 }
611 
613 {
614 
615  DiscoXPositionIORT1 = xpos;
616 }
617 
619 {
620 
621  AngleDiscoIORT0 = phi0;
622 }
623 
625 
626 
629 {
630  /*
631  * Check parameters consistency
632  */
633  ParametersCheck();
634 
635  G4GeometryManager::GetInstance() -> OpenGeometry();
636  if (phantom)
637  {
638  phantom -> SetXHalfLength(phantomSizeX/2);
639  phantom -> SetYHalfLength(phantomSizeY/2);
640  phantom -> SetZHalfLength(phantomSizeZ/2);
641  phantomPhysicalVolume -> SetTranslation(phantomPosition);
642  }
643  else ConstructPhantom();
644 
645  // Get the center of the detector
647  if (detector)
648  {
649  detector -> SetXHalfLength(detectorSizeX/2);
650  detector -> SetYHalfLength(detectorSizeY/2);
651  detector -> SetZHalfLength(detectorSizeZ/2);
652  detectorPhysicalVolume -> SetTranslation(detectorPosition);
653  }
654  else ConstructDetector();
655 
656  // update disc function
657  delete solidDiscoIORT0;
658  delete logicDiscoIORT0;
659  delete physiDiscoIORT0;
660  delete solidDiscoIORT;
661  delete logicDiscoIORT;
662  delete physiDiscoIORT;
663  delete solidDiscoIORT1;
664  delete logicDiscoIORT1;
665  delete physiDiscoIORT1;
666  ConstructDisc();
667 
668 
669  // Round to nearest integer number of voxel
670  numberOfVoxelsAlongX = G4lrint(detectorSizeX / sizeOfVoxelAlongX);
671  sizeOfVoxelAlongX = ( detectorSizeX / numberOfVoxelsAlongX );
672 
673  numberOfVoxelsAlongY = G4lrint(detectorSizeY / sizeOfVoxelAlongY);
674  sizeOfVoxelAlongY = ( detectorSizeY / numberOfVoxelsAlongY );
675 
676  numberOfVoxelsAlongZ = G4lrint(detectorSizeZ / sizeOfVoxelAlongZ);
677  sizeOfVoxelAlongZ = ( detectorSizeZ / numberOfVoxelsAlongZ );
678 
679  //G4cout << "*************** DetectorToWorldPosition " << GetDetectorToWorldPosition()/cm << "\n";
680  ConstructSensitiveDetector(GetDetectorToWorldPosition());
681 
682  volumeOfVoxel = sizeOfVoxelAlongX * sizeOfVoxelAlongY * sizeOfVoxelAlongZ;
683  massOfVoxel = detectorMaterial -> GetDensity() * volumeOfVoxel;
684  // This will clear the existing matrix (together with all data inside it)!
685  matrix = IORTMatrix::GetInstance(numberOfVoxelsAlongX,
686  numberOfVoxelsAlongY,
687  numberOfVoxelsAlongZ,
688  massOfVoxel);
689 
690  // Initialize analysis
691 /*
692  IORTAnalysisManager* analysis = IORTAnalysisManager::GetInstance();
693 #ifdef G4ANALYSIS_USE_ROOT
694  analysis -> flush(); // Finalize the root file
695  analysis -> book();
696 #endif
697 */
698  // Inform the kernel about the new geometry
699  G4RunManager::GetRunManager() -> GeometryHasBeenModified();
700  G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
701 
702  PrintParameters();
703 }
704 
706 {
707  delete solidDiscoIORT0;
708  delete logicDiscoIORT0;
709  delete physiDiscoIORT0;
710  delete solidDiscoIORT;
711  delete logicDiscoIORT;
712  delete physiDiscoIORT;
713  delete solidDiscoIORT1;
714  delete logicDiscoIORT1;
715  delete physiDiscoIORT1;
716  G4RunManager::GetRunManager() -> GeometryHasBeenModified();
717  G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
718 }
719 
720 
722 {
723 
724  G4cout << "The (X,Y,Z) dimensions of the phantom are : (" <<
725  G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ',' <<
726  G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ',' <<
727  G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl;
728 
729  G4cout << "The (X,Y,Z) dimensions of the detector are : (" <<
730  G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ',' <<
731  G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ',' <<
732  G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl;
733 
734  G4cout << "Displacement between Phantom and World is: ";
735  G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") <<
736  "DY= "<< G4BestUnit(phantomPosition.getY(),"Length") <<
737  "DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl;
738 
739  G4cout << "The (X,Y,Z) sizes of the Voxels are: (" <<
740  G4BestUnit(sizeOfVoxelAlongX, "Length") << ',' <<
741  G4BestUnit(sizeOfVoxelAlongY, "Length") << ',' <<
742  G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl;
743 
744  G4cout << "The number of Voxels along (X,Y,Z) is: (" <<
745  numberOfVoxelsAlongX << ',' <<
746  numberOfVoxelsAlongY <<',' <<
747  numberOfVoxelsAlongZ << ')' << G4endl;
748 
749 }