ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PassiveCarbonBeamLine.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PassiveCarbonBeamLine.cc
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 // Hadrontherapy advanced example for Geant4
27 // See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
28 // Simulation of the "Zero degree" experimental beamline of INFN-LNS (Catania, Italy).
29 
30 #include "G4Box.hh"
31 #include "G4Tubs.hh"
32 #include "G4VisAttributes.hh"
33 #include "G4Colour.hh"
34 #include "globals.hh"
35 #include "G4RunManager.hh"
36 #include "G4LogicalVolume.hh"
37 #include "G4PVPlacement.hh"
38 #include "G4RotationMatrix.hh"
39 #include "G4NistManager.hh"
40 #include "G4NistElementBuilder.hh"
43 #include "PassiveCarbonBeamLine.hh"
44 #include "G4SystemOfUnits.hh"
45 #include "G4Trd.hh"
47 
48 //G4bool PassiveCarbonBeamLine::doCalculation = false;
51 physicalTreatmentRoom(0),hadrontherapyDetectorConstruction(0),
52 physiBeamLineSupport(0), physiBeamLineCover(0), physiBeamLineCover2(0),
53 physiKaptonWindow(0),PhysiRippleFilter(0),PhysiRippleFilterBase(0),PhysiRippleFilterTrd(0),
54 physiFirstMonitorLayer1(0), physiFirstMonitorLayer2(0),
55 physiFirstMonitorLayer3(0), physiFirstMonitorLayer4(0),
56 physiNozzleSupport(0), physiHoleNozzleSupport(0)
57 {
58 
59  // Messenger to change parameters of the passiveCarbonBeamLine geometry
61 
62  //***************************** PW ***************************************
63 
64  static G4String ROGeometryName = "DetectorROGeometry";
65  RO = new HadrontherapyDetectorROGeometry(ROGeometryName);
66 
67 
68  G4cout << "Going to register Parallel world...";
70  G4cout << "... done" << G4endl;
71  //***************************** PW ***************************************
72 }
73 
76 {
79 }
80 
83 {
84  // Sets default geometry and materials
86 
87  // Construct the whole CarbonPassive Beam Line
89 
90 
91  //***************************** PW ***************************************
93 
94  //***************************** PW ***************************************
95  // HadrontherapyDetectorConstruction builds ONLY the phantom and the detector with its associated ROGeometry
97 
98  //***************************** PW ***************************************
99 
101 
102  //***************************** PW ***************************************
103  return physicalTreatmentRoom;
104 }
105 
106 // In the following method the DEFAULTS used in the geometry of
107 // passive beam line are provided
108 // HERE THE USER CAN CHANGE THE GEOMETRY CHARACTERISTICS OF BEAM
109 // LINE ELEMENTS, ALTERNATIVELY HE/SHE CAN USE THE MACRO FILE (IF A
110 // MESSENGER IS PROVIDED)
111 //
112 // DEFAULT MATERIAL ARE ALSO PROVIDED
113 // and COLOURS ARE ALSO DEFINED
114 // ----------------------------------------------------------
117 {
118  // Set of coulors that can be used
119  white = new G4VisAttributes( G4Colour());
120  white -> SetVisibility(true);
121  white -> SetForceSolid(true);
122 
123  black = new G4VisAttributes( G4Colour(1., 1., 1.));
124  black -> SetVisibility(true);
125  black -> SetForceSolid(true);
126 
127 
128  blue = new G4VisAttributes(G4Colour(0. ,0. ,1.));
129  blue -> SetVisibility(true);
130  blue -> SetForceSolid(true);
131 
132  gray = new G4VisAttributes( G4Colour(0.5, 0.5, 0.5 ));
133  gray-> SetVisibility(true);
134  gray-> SetForceSolid(true);
135 
136  red = new G4VisAttributes(G4Colour(1. ,0. ,0.));
137  red-> SetVisibility(true);
138  red-> SetForceSolid(true);
139 
140  yellow = new G4VisAttributes(G4Colour(1., 1., 0. ));
141  yellow-> SetVisibility(true);
142  yellow-> SetForceSolid(true);
143 
144  green = new G4VisAttributes( G4Colour(25/255. , 255/255. , 25/255. ));
145  green -> SetVisibility(true);
146  green -> SetForceSolid(true);
147 
148  darkGreen = new G4VisAttributes( G4Colour(0/255. , 100/255. , 0/255. ));
149  darkGreen -> SetVisibility(true);
150  darkGreen -> SetForceSolid(true);
151 
152  darkOrange3 = new G4VisAttributes( G4Colour(205/255. , 102/255. , 000/255. ));
153  darkOrange3 -> SetVisibility(true);
154  darkOrange3 -> SetForceSolid(true);
155 
156  skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
157  skyBlue -> SetVisibility(true);
158  skyBlue -> SetForceSolid(true);
159 
160 
161  // FINAL COLLIMATOR: is the collimator giving the final transversal shape
162  // of the beam
163 
164  G4double defaultinnerRadiusFinalCollimator = 12.5 *mm;
165  innerRadiusFinalCollimator = defaultinnerRadiusFinalCollimator;
166 
167  // DEFAULT DEFINITION OF THE MATERIALS
168  // All elements and compound definition follows the NIST database
169 
170  // ELEMENTS
171  G4bool isotopes = false;
175 
176  // MATERIAL (Including compounds)
178  airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes);
179  kaptonNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_KAPTON", isotopes);
180  galacticNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic", isotopes);
181  PMMANist = G4NistManager::Instance()->FindOrBuildMaterial("G4_PLEXIGLASS", isotopes);
183 
184  G4double d; // Density
185  G4int nComponents;// Number of components
186  G4double fractionmass; // Fraction in mass of an element in a material
187 
188  d = 8.40*g/cm3;
189  nComponents = 2;
190  brass = new G4Material("Brass", d, nComponents);
191  brass -> AddElement(zincNist, fractionmass = 30 *perCent);
192  brass -> AddElement(copperNist, fractionmass = 70 *perCent);
193 
194  //***************************** PW ***************************************
195 
196  // DetectorROGeometry Material
197  new G4Material("dummyMat", 1., 1.*g/mole, 1.*g/cm3);
198 
199  //***************************** PW ***************************************
200 
201  // MATERIAL ASSIGNMENT
202  // Support of the beam line
204 
205  // Vacuum pipe
208 
209  // Material of kapton window
211 
212  // Material of ripple filter
215 
216  // Materials of the monitor chamber
221 
222  // Material of the final nozzle
226 
227  // Material of the final collimator
229 
230  // Material of the final collimator
232 
233  // Material of the PMMA collimator
235 }
236 
239 {
240  // -----------------------------
241  // Treatment room - World volume
242  //------------------------------
243  // Treatment room sizes
244 
245  const G4double worldX = 400.0 *cm;
246  const G4double worldY = 400.0 *cm;
247  const G4double worldZ = 400.0 *cm;
248  G4bool isotopes = false;
249 
250  airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes);
251  treatmentRoom = new G4Box("TreatmentRoom",worldX,worldY,worldZ);
253  airNist,
254  "logicTreatmentRoom",
255  0,0,0);
257  G4ThreeVector(),
258  "physicalTreatmentRoom",
260  0,false,0);
261 
262 
263  // The treatment room is invisible in the Visualisation
264  logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::GetInvisible());
265 
266  // Components of the Passive Carbon Beam Line
274 }
275 
278 {
279  // ------------------//
280  // BEAM LINE SUPPORT //
281  //-------------------//
282 
283  beamLineSupportXSize = 1.5*m;
284  beamLineSupportYSize = 20.*mm;
285  beamLineSupportZSize = 600.*mm;
286 
287  beamLineSupportXPosition = -1745.09 *mm;
288  beamLineSupportYPosition = -230. *mm;
290 
291  beamLineSupport = new G4Box("BeamLineSupport",
295 
298  "BeamLineSupport");
302  "BeamLineSupport",
304  physicalTreatmentRoom, false, 0);
305 
306  // Visualisation attributes of the beam line support
307  logicBeamLineSupport -> SetVisAttributes(gray);
308 
309  //---------------------------------//
310  // Beam line cover 1 (left panel) //
311  //---------------------------------//
312  beamLineCoverXSize = 1.5*m;
313  beamLineCoverYSize = 750.*mm;
314  beamLineCoverZSize = 10.*mm;
315 
316  beamLineCoverXPosition = -1745.09 *mm;
317  beamLineCoverYPosition = -1000.*mm;
318  beamLineCoverZPosition = 610.*mm;
319 
320  beamLineCover = new G4Box("BeamLineCover",
324 
327  "BeamLineCover");
328 
332  "BeamLineCover",
335  false,
336  0);
337 
338  // ---------------------------------//
339  // Beam line cover 2 (rigth panel) //
340  // ---------------------------------//
341  // It has the same characteristic of beam line cover 1 but set in a different position
345  "BeamLineCover2",
348  false,
349  0);
350 
351 
352  logicBeamLineCover -> SetVisAttributes(blue);
353 }
354 
357 {
358  // ------------//
359  // VACUUM PIPE //
360  //-------------//
361  //
362  // First track of the beam line is inside vacuum;
363 
364  vacuumZoneXSize = 100 *mm;
365  vacuumZoneYSize = 52.5 *mm;
366  vacuumZoneZSize = 52.5 *mm;
367  vacuumPipeXPosition = -1708.0 *mm;
368 
369 
370  vacuumZone = new G4Box("VacuumZone",
371  vacuumZoneXSize/2,
372  vacuumZoneYSize/2,
373  vacuumZoneZSize/2);
374 
376 
378  "VacuumZone",
381  false,
382  0);
383 
384  // --------------------------//
385  // THE FIRST SCATTERING FOIL //
386  // --------------------------//
387  // A thin foil performing a first scattering
388  // of the original beam
389 
390  firstScatteringFoilXSize = 0.015 *mm;
394 
395  firstScatteringFoil = new G4Box("FirstScatteringFoil",
399 
402  "FirstScatteringFoil");
403 
405  "FirstScatteringFoil", logicFirstScatteringFoil, physiVacuumZone,
406  false, 0);
407 
408  logicFirstScatteringFoil -> SetVisAttributes(skyBlue);
409 
410  // -------------------//
411  // THE KAPTON WINDOWS //
412  //--------------------//
413  //It permits the passage of the beam from vacuum to air
414 
415  // KAPTON WINDOW: it permits the passage of the beam from vacuum to air
416  kaptonWindowXSize = 0.050 *mm;
417  kaptonWindowYSize = 52.5 *mm;
418  kaptonWindowZSize = 52.5 *mm;
420 
421  solidKaptonWindow = new G4Box("KaptonWindow",
425 
428  "KaptonWindow");
429 
431  "KaptonWindow", logicKaptonWindow,
432  physiVacuumZone, false, 0);
433 
434  logicKaptonWindow -> SetVisAttributes(darkOrange3);
435 
436 
437 
438 
439 
440 
441 }
444 {
445 
446 
447  G4double defaultRippleFilterXPosition = -1638.0*mm;
448  G4double ripple_position=(defaultRippleFilterXPosition);
449  G4double RF_x = 200.0 * mm;
450  G4double RF_y = 200.0 * mm;
451  G4double RF_z = 1.4 * mm;
452  G4double RFbase_z = 0.2 * mm;
453  G4double RFtrd_z = RF_z - RFbase_z;
454  G4double RFtrd_top = 1e-4 * mm;
455  G4double RFtrd_bottom = 1.5 * mm;
456  G4double distanceBetweenTrd = 0.1*mm;
457 
458 
459 
460 
461  G4double theta = -90. *deg;
462  // Matrix definition for a "theta" deg rotation with respect to Y axis
463  G4RotationMatrix rot;
464  rot.rotateY(theta);
465 
466 
467  SolidRippleFilter= new G4Box("RippleFilter",
468  RF_x/2 + 1*mm,
469  RF_y/2 + 1*mm,
470  RF_z/2 + 1*mm);
471 
474  "LogicRippleFilter",
475  0,0,0);
476 
477  PhysiRippleFilter = new G4PVPlacement(G4Transform3D(rot,G4ThreeVector(ripple_position,0,0)),
478  "PhysiRippleFilter",
481  false,
482  1,
483  true);
484 
485  PhysiRippleFilter = new G4PVPlacement(G4Transform3D(rot,G4ThreeVector(ripple_position + 10*cm,0,0)),
486  "PhysiRippleFilter",
489  false,
490  2,
491  true);
492 
493  LogicRippleFilter -> SetVisAttributes(G4VisAttributes::GetInvisible());
494 
495  SolidRippleFilterBase = new G4Box("RippleFilterBase",
496  RF_x/2,
497  RF_y/2,
498  RFbase_z/2);
499 
502  "LogicRippleFilterBase",
503  0,0,0);
504 
505  LogicRippleFilterBase -> SetVisAttributes(green);
506 
508  G4ThreeVector(0, 0, -RF_z/2 + RFbase_z/2),
509  "PhysiRippleFilter",
512  false,
513  0,
514  false);
515 
516  SolidRippleFilterTrd = new G4Trd("SolidRippleFilterTrd",
517  RF_x/2,
518  RF_x/2,
519  RFtrd_bottom/2,
520  RFtrd_top/2,
521  RFtrd_z/2);
522 
525  "LogicRippleFilterTrd",
526  0,0,0);
527 
528  LogicRippleFilterTrd -> SetVisAttributes(green);
529 
530  G4int numberOfTrd = static_cast<int>(std::floor( RF_y / (RFtrd_bottom+distanceBetweenTrd) ));
531 
532  G4int N = static_cast<int>( std::floor(numberOfTrd-1)/2 );
533 
534  G4int copyNumber = 0;
535 
536  for( int i = -N; i <= N; i++ )
537  {
539  G4ThreeVector(0,
540  i*(RFtrd_bottom+distanceBetweenTrd),
541  -RF_z/2+RFbase_z+RFtrd_z/2),
542  "PhysiRippleFilterTrd",
545  false,
546  copyNumber,
547  false);
548 
549  copyNumber++;
550  }
551 
552  }
553 
554 
557 {
558 
559  // ----------------------//
560  // PMMA COLLIMATOR //
561  // ----------------------//
565 
566  PMMACollimatorXPosition = -1082.00 *mm;
567 
568  G4double phi = 90. *deg;
569  G4RotationMatrix rm;
570  rm.rotateY(phi);
571 
572  solidPMMACollimatorSupport = new G4Box("PMMACollimatorSupport",
576 
579  "PMMACollimatorSupport");
580 
582  "PMMACollimatorSupport",
585  false,
586  0);
587 
588 
589  yellow = new G4VisAttributes(G4Colour(1., 1., 0. ));
590  yellow-> SetVisibility(true);
591  yellow-> SetForceWireframe(true);
592 
593  logicPMMACollimatorSupport -> SetVisAttributes(yellow);
594 
595  // ----------------------//
596  // PMMA COLLIMATOR //
597  //-----------------------//
603 
604 
605  solidPMMACollimator = new G4Tubs("PMMACollimator",
611 
614  "PMMACollimator",
615  0,
616  0,
617  0);
618 
620  G4ThreeVector(0,0.,0.)),
621  "PMMACollimator",
624  false,
625  0);
626 
627  logicPMMACollimator -> SetVisAttributes(yellow);
628 
629 
630 
631 
632 }
635 {
636 
637  // ----------------------------
638  // MONITOR CHAMBER
639  // ----------------------------
640  // A monitor chamber is a free-air ionisation chamber
641  // able to measure do carbon fluence during the treatment.
642  // Here its responce is not simulated in terms of produced
643  // charge but only the energy losses are taked into account.
644  // Each chamber consist of 9 mm of air in a box
645  // that has two layers one of kapton and one
646  // of copper
647 
648  monitor1XSize = 4.525022*mm;
649  monitor2XSize = 0.000011*mm;
650  monitor3XSize = 4.5*mm;
651  monitorYSize = 10.*cm;
652  monitorZSize = 10.*cm;
653  monitor1XPosition = -1059.0 *mm;
654  monitor2XPosition = -4.500011*mm;
655  monitor4XPosition = 4.500011*mm;
656 
657  solidFirstMonitorLayer1 = new G4Box("FirstMonitorLayer1",
659  monitorYSize,
660  monitorZSize);
661 
664  "FirstMonitorLayer1");
665 
668  "FirstMonitorLayer1",
671  false,
672  0);
673 
674  solidFirstMonitorLayer2 = new G4Box("FirstMonitorLayer2",
676  monitorYSize,
677  monitorZSize);
678 
681  "FirstMonitorLayer2");
682 
684  "FirstMonitorLayer2",
687  false,
688  0);
689 
690  solidFirstMonitorLayer3 = new G4Box("FirstMonitorLayer3",
692  monitorYSize,
693  monitorZSize);
694 
697  "FirstMonitorLayer3");
698 
700  G4ThreeVector(0.*mm,0.*cm,0.*cm),
701  "MonitorLayer3",
704  false,
705  0);
706 
707  solidFirstMonitorLayer4 = new G4Box("FirstMonitorLayer4",
709  monitorYSize,
710  monitorZSize);
711 
714  "FirstMonitorLayer4");
715 
717  "FirstMonitorLayer4",
719  physiFirstMonitorLayer1, false, 0);
720 
721  logicFirstMonitorLayer3 -> SetVisAttributes(white);
722 
723 }
724 
728 {
729  // ------------------------------//
730  // THE FINAL TUBE AND COLLIMATOR //
731  //-------------------------------//
732  // The last part of the transport beam line consists of
733  // a 59 mm thick PMMA slab (to stop all the diffused radiation), a 370 mm brass tube
734  // (to well collimate the proton beam) and a final collimator with 25 mm diameter
735  // aperture (that provide the final trasversal shape of the beam)
736 
737  // -------------------//
738  // PMMA SUPPORT //
739  // -------------------//
740 
741  nozzleSupportXSize = 50 *mm;
742  nozzleSupportYSize = 360. *mm;
743  nozzleSupportZSize = 360. *mm;
744  nozzleSupportXPosition = -423.0 *mm;
745 
746  G4double phi = 90. *deg;
747  // Matrix definition for a 90 deg rotation. Also used for other volumes
748  G4RotationMatrix rm;
749  rm.rotateY(phi);
750 
751  solidNozzleSupport = new G4Box("NozzleSupport",
755 
758  "NozzleSupport");
759 
761  "NozzleSupport",
764  false,
765  0);
766 
767  yellow = new G4VisAttributes(G4Colour(1., 1., 0. ));
768  yellow-> SetVisibility(true);
769  yellow-> SetForceWireframe(true);
770 
771  //------------------------------------//
772  // HOLE IN THE SUPPORT //
773  //------------------------------------//
779 
780  solidHoleNozzleSupport = new G4Tubs("HoleNozzleSupport",
786 
789  "HoleNozzleSupport",
790  0,
791  0,
792  0);
793 
795  "HoleNozzleSupport",
798  false, 0);
799 
800 
801  // --------------------------------------//
802  // BRASS TUBE 3 (beam line side) //
803  // -------------------------------------//
804  innerRadiusBrassTube3 = 13.5 *mm;
805  outerRadiusBrassTube3 = 21.5 *mm;
806  hightBrassTube3 = 20.0 *mm;
809  brassTube3XPosition = -458.0 *mm;
810 
811  solidBrassTube3 = new G4Tubs("BrassTube3",
814  hightBrassTube3/2,
817 
820  "BrassTube3",
821  0, 0, 0);
822 
825  0.,
826  0.)),
827  "BrassTube3",
830  false,
831  0);
832 
833  logicBrassTube3 -> SetVisAttributes(darkOrange3);
834 
835  // ----------------------------------------------//
836  // BRASS TUBE 2 (inside the PMMA support) //
837  // ----------------------------------------------//
838 
839  innerRadiusBrassTube2 = 13.5 *mm;
840  outerRadiusBrassTube2 = 21.5 *mm;
844 
845 
846  solidBrassTube2 = new G4Tubs("BrassTube2",
849  hightBrassTube2/2,
852 
855  "BrassTube2",
856  0, 0, 0);
858  G4ThreeVector(0,0.,0.),
860  "BrassTube2",
862  false,
863  0);
864 
865  logicBrassTube2 -> SetVisAttributes(darkOrange3);
866 
867  // ---------------------------------//
868  // BRASS TUBE 1 (phantom side) //
869  // ---------------------------------//
871  outerRadiusBrassTube = 21.5 *mm;
872  hightBrassTube = 208.0 *mm;
875  brassTubeXPosition = -294 *mm;
876  solidBrassTube = new G4Tubs("BrassTube",
879  hightBrassTube/2,
882 
885  "BrassTube",
886  0, 0, 0);
887 
890  0.,
891  0.)),
892  "BrassTube",
895  false,
896  0);
897 
898  logicBrassTube -> SetVisAttributes(darkOrange3);
899 }
900 
903 {
904  // -----------------------//
905  // FINAL COLLIMATOR //
906  //------------------------//
908  hightFinalCollimator = 7.0 *mm;
911  finalCollimatorXPosition = -186.5 *mm;
912 
913  G4double phi = 90. *deg;
914 
915  // Matrix definition for a 90 deg rotation. Also used for other volumes
916  G4RotationMatrix rm;
917  rm.rotateY(phi);
918 
919  solidFinalCollimator = new G4Tubs("FinalCollimator",
925 
928  "FinalCollimator",
929  0,
930  0,
931  0);
932 
935  "FinalCollimator",
938  false,
939  0);
940 
941  logicFinalCollimator -> SetVisAttributes(yellow);
942 }
943 
944 
948 
950 {
951  PhysiRippleFilter -> SetTranslation(G4ThreeVector(value, 0., 0.));
953  G4cout << "The Ripple Filter is translated to"<< value/mm <<"mm along the X axis" <<G4endl;
954 }
955 
956 
959 {
960  solidFinalCollimator -> SetInnerRadius(value);
962  G4cout<<"Inner Radius of the final collimator is (mm):"
963  << solidFinalCollimator -> GetInnerRadius()/mm
964  << G4endl;
965 }
966 
969 {
970  if (G4Material* RFMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice, false) )
971  {
972  if (RFMaterial)
973  {
974  rippleFilterMaterial = RFMaterial;
975  LogicRippleFilter -> SetMaterial(RFMaterial);
976  LogicRippleFilterBase -> SetMaterial(RFMaterial);
977  LogicRippleFilterTrd -> SetMaterial(RFMaterial);
978  G4cout << "The material of the Ripple Filter has been changed to " << materialChoice << G4endl;
979  }
980  }
981  else
982  {
983  G4cout << "WARNING: material \"" << materialChoice << "\" doesn't exist in NIST elements/materials"
984  " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
985  G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
986  }
987 }
988 
989 
990