ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G02DetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G02DetectorConstruction.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 //g
28 //
29 //
30 //
31 // Class G02DetectorConstruction implementation
32 //
33 // ----------------------------------------------------------------------------
34 
36 
37 // Geant4 includes
38 //
39 #include "globals.hh"
40 #include "G4GeometryManager.hh"
41 #include "G4VisAttributes.hh"
42 
43 // Materials
44 //
45 #include "G4Material.hh"
46 
47 // Geometry includes
48 //
49 #include "G4LogicalVolume.hh"
50 #include "G4VPhysicalVolume.hh"
51 #include "G4PVParameterised.hh"
52 #include "G4PVPlacement.hh"
53 #include "G4Box.hh"
54 #include "G4Tubs.hh"
55 
56 // Reflected solids
57 //
58 #include "G4ReflectedSolid.hh"
59 #include "G4DisplacedSolid.hh"
60 #include "G4ReflectionFactory.hh"
61 #include "G4RotationMatrix.hh"
62 #include "G4AffineTransform.hh"
63 #include "G4Transform3D.hh"
64 
65 // Assembly volumes
66 //
67 #include "G4AssemblyVolume.hh"
68 
69 // Volume parameterisations
70 //
72 
73 // Messenger
74 //
75 #include "G02DetectorMessenger.hh"
76 
77 // GDML parser include
78 //
79 #include "G4GDMLParser.hh"
80 
81 #include "G4PhysicalConstants.hh"
82 #include "G4SystemOfUnits.hh"
83 
84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
85 //
86 // Constructor
87 //
90  fAir(0), fAluminum(0), fPb(0), fXenon(0),
91  fDetectorMessenger(0)
92 {
93  fExpHall_x=5.*m;
94 
95  fReadFile ="test.gdml";
96  fWriteFile="wtest.gdml";
97  fStepFile ="mbb";
99 
101 }
102 
103 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
104 //
105 // Destructor
106 //
108 {
110 }
111 
112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
113 //
114 // Constructs geometries and materials
115 //
117 {
118  // Writing or Reading of Geometry using G4GDML
119 
120  G4VPhysicalVolume* fWorldPhysVol;
121 
122  if(fWritingChoice==0)
123  {
124  // **** LOOK HERE*** FOR READING GDML FILES
125  //
126 
127  // ACTIVATING OVERLAP CHECK when read volumes are placed.
128  // Can take long time in case of complex geometries
129  //
130  // fParser.SetOverlapCheck(true);
131 
133 
134  // READING GDML FILES OPTION: 2nd Boolean argument "Validate".
135  // Flag to "false" disables check with the Schema when reading GDML file.
136  // See the GDML Documentation for more information.
137  //
138  // fParser.Read(fReadFile,false);
139 
140  // Prints the material information
141  //
143 
144  // Giving World Physical Volume from GDML Parser
145  //
146  fWorldPhysVol = fParser.GetWorldVolume();
147  }
148  else if(fWritingChoice==1)
149  {
150  // **** LOOK HERE*** FOR WRITING GDML FILES
151  // Detector Construction and WRITING to GDML
152  //
153  ListOfMaterials();
154  fWorldPhysVol = ConstructDetector();
155 
156  // OPTION: TO ADD MODULE AT DEPTH LEVEL ...
157  //
158  // Can be a integer or a pointer to the top Physical Volume:
159  //
160  // G4int depth=1;
161  // fParser.AddModule(depth);
162 
163  // OPTION: SETTING ADDITION OF POINTER TO NAME TO FALSE
164  //
165  // By default, written names in GDML consist of the given name with
166  // appended the pointer reference to it, in order to make it unique.
167  // Naming policy can be changed by using the following method, or
168  // calling Write with additional Boolean argument to "false".
169  // NOTE: you have to be sure not to have duplication of names in your
170  // Geometry Setup.
171  //
172  // fParser.SetAddPointerToName(false);
173  //
174  // or
175  //
176  // fParser.Write(fWriteFile, fWorldPhysVol, false);
177 
178  // OPTION: SET MAXIMUM LEVEL TO EXPORT (REDUCED TREE)...
179  //
180  // Can be a integer greater than zero:
181  //
182  // G4int maxlevel=3;
183  // fParser.SetMaxExportLevel(maxlevel);
184 
185  // Writing Geometry to GDML File
186  //
187  fParser.Write(fWriteFile, fWorldPhysVol);
188 
189  // OPTION: SPECIFYING THE SCHEMA LOCATION
190  //
191  // When writing GDML file the default the Schema Location from the
192  // GDML web site will be used:
193  // "http://cern.ch/service-spi/app/releases/GDML/GDML_2_10_0/src/GDMLSchema/gdml.xsd"
194  //
195  // NOTE: GDML Schema is distributed in Geant4 in the directory:
196  // $G4INSTALL/source/persistency/gdml/schema
197  //
198  // You can change the Schema path by adding a parameter to the Write
199  // command, as follows:
200  //
201  // fParser.Write(fWriteFile, fWorldPhysVol, "your-path-to-schema/gdml.xsd");
202  }
203  else // Demonstration how to Read STEP files using GDML
204  {
205  // Some printout...
206  //
207  ListOfMaterials();
208 
209  // Arbitrary values that should enclose any reasonable geometry
210  //
211  const G4double expHall_y = fExpHall_x/50.;
212  const G4double expHall_z = fExpHall_x/50.;
213 
214  // Create the hall
215  //
216  G4Box * experimentalHallBox
217  = new G4Box("ExpHallBox",fExpHall_x/50.,expHall_y,expHall_z);
218  G4LogicalVolume * experimentalHallLV
219  = new G4LogicalVolume(experimentalHallBox, fAir,"ExpHallLV");
220  fWorldPhysVol
221  = new G4PVPlacement(0, G4ThreeVector(0.0,0.0,0.0),
222  experimentalHallLV, "ExpHallPhys", 0, false, 0);
223 
224  // G02DetectorConstruction via reading STEP File
225  //
226  G4LogicalVolume* LogicalVolST
228 
229  // Placement inside of the hall
230  //
231  new G4PVPlacement(0, G4ThreeVector(10.0,0.0,0.0), LogicalVolST,
232  "StepPhys", experimentalHallLV, false, 0);
233  }
234 
235  // Set Visualization attributes to world
236  //
237  G4VisAttributes* BoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
238  fWorldPhysVol->GetLogicalVolume()->SetVisAttributes(BoxVisAtt);
239 
240  return fWorldPhysVol;
241 }
242 
243 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
244 //
245 // Utility to build and list necessary materials
246 //
248 {
249  G4double a; // atomic mass
250  G4double z; // atomic number
251  G4double density,temperature,pressure;
252  G4double fractionmass;
253  G4String name, symbol;
254  G4int ncomponents;
255 
256  // Elements needed for the materials
257 
258  a = 14.01*g/mole;
259  G4Element* elN = new G4Element(name="Nitrogen", symbol="N", z=7., a);
260 
261  a = 16.00*g/mole;
262  G4Element* elO = new G4Element(name="Oxygen", symbol="O", z=8., a);
263 
264  a = 26.98*g/mole;
265  G4Element* elAl = new G4Element(name="Aluminum", symbol="Al", z=13., a);
266 
267  // Print the Element information
268  //
270 
271  // Air
272  //
273  density = 1.29*mg/cm3;
274  fAir = new G4Material(name="Air", density, ncomponents=2);
275  fAir->AddElement(elN, fractionmass=0.7);
276  fAir->AddElement(elO, fractionmass=0.3);
277 
278  // Aluminum
279  //
280  density = 2.70*g/cm3;
281  fAluminum = new G4Material(name="Aluminum", density, ncomponents=1);
282  fAluminum->AddElement(elAl, fractionmass=1.0);
283 
284  // Lead
285  //
286  fPb = new G4Material("Lead", z=82., a= 207.19*g/mole, density= 11.35*g/cm3);
287 
288  // Xenon gas
289  //
290  fXenon = new G4Material("XenonGas", z=54., a=131.29*g/mole,
291  density= 5.458*mg/cm3, kStateGas,
292  temperature= 293.15*kelvin, pressure= 1*atmosphere);
293 
294  // Prints the material information
295  //
297 }
298 
299 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
300 //
301 // Detector Construction
302 //
303 // Detector consist from DetectorBox, Conrol Room and 4 SubDetectors
304 // SubDetectors1 and 2 show how to use Reflection Factory and Assembly
305 // SubDetectors 3 and 4 show how to use Parameterisation
306 //
308 {
309  // Arbitary values that should enclose any reasonable geometry
310  //
311  const G4double expHall_y = fExpHall_x;
312  const G4double expHall_z = fExpHall_x;
313 
314  // Create the hall
315  //
316  G4Box * experimentalHallBox =
317  new G4Box("ExpHallBox", fExpHall_x, expHall_y, expHall_z);
318  G4LogicalVolume * experimentalHallLV =
319  new G4LogicalVolume(experimentalHallBox, fAir, "ExpHallLV");
320  G4PVPlacement * experimentalHallPhys =
321  new G4PVPlacement(0, G4ThreeVector(0.0,0.0,0.0), experimentalHallLV,
322  "ExpHallPhys", 0, false, 0);
323 
324  // G02DetectorConstruction
325 
326  const G4double det_x = fExpHall_x*0.8;
327  const G4double det_y = fExpHall_x*0.7;
328  const G4double det_z = det_y;
329 
330  // Create the detector box
331  //
332  G4Box * detectorBox =
333  new G4Box("detectorBox", det_x, det_y, det_z);
334  G4LogicalVolume * detectorLV =
335  new G4LogicalVolume(detectorBox, fAir, "detLV");
336  // G4PVPlacement * detectorPhys =
337  new G4PVPlacement(0, G4ThreeVector(0.0,0.0,0.0), detectorLV,
338  "detPhys", experimentalHallLV, false, 0);
339 
340  // Create the Control room box
341  //
342  const G4double room_x = fExpHall_x/20.;
343  const G4double room_y = room_x;
344  const G4double room_z = room_x;
345 
346  G4Box * roomBox =
347  new G4Box("roomBox", room_x, room_y, room_z);
348  G4LogicalVolume * roomLV =
349  new G4LogicalVolume(roomBox, fAir, "roomLV");
350  // G4PVPlacement * roomPhys =
351  new G4PVPlacement(0, G4ThreeVector(fExpHall_x-room_x-10.,0.0,0.0), roomLV,
352  "roomPhys", experimentalHallLV, false, 0);
353 
354  // SubDetector1
355  //
356  const G4double bigL=fExpHall_x/5.+50.;
357  G4LogicalVolume* subDetectorLV1 = ConstructSubDetector1();
358  // G4PVPlacement * detPhys1 =
359  new G4PVPlacement(0, G4ThreeVector(bigL,0.0,0.0), subDetectorLV1,
360  "PhysSubDetector1", detectorLV, false, 0);
361 
362  //
363  // LOOK HERE FOR REFLECTIONS
364  //
365 
366  // SubDetector2
367  //
368  G4Translate3D translation(-bigL, 0., 0.);
369  G4RotationMatrix* rotD3 = new G4RotationMatrix();
370  G4Transform3D rotation = G4Rotate3D(*rotD3);
371  G4ReflectX3D reflection;
372  G4Transform3D transform = translation*rotation*reflection;
373 
374  // Place the reflected part using G4ReflectionFactory
375  //
376  G4ReflectionFactory::Instance()->Place(transform, "reflSubDetector",
377  subDetectorLV1, detectorLV, false, 0);
378 
379  // SubDetector3
380  //
381  G4LogicalVolume* subDetectorLV3 = ConstructSubDetector2();
382  // G4PVPlacement * detPhys3 =
383  new G4PVPlacement(0, G4ThreeVector(0.0,bigL,0.0), subDetectorLV3,
384  "PhysSubDetectorFirst3", detectorLV, false, 0);
385 
386  // SubDetector4, placement of parameterised chambers
387  //
388  G4LogicalVolume* subDetectorLV4 = ConstructSubDetector2();
390  // G4PVPlacement * detChamb =
391  new G4PVPlacement(0, G4ThreeVector(0,0.0,0.0), subChamberLV,
392  "AssemblyPhys", subDetectorLV4, false, 0);
393  // G4PVPlacement * detPhys4 =
394  new G4PVPlacement(0, G4ThreeVector(0.0,-bigL,0.0), subDetectorLV4,
395  "PhysSubDetectorSecond3", detectorLV, false, 0);
396 
397  return experimentalHallPhys;
398 }
399 
400 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
401 //
402 // SubDetector1
403 //
405 {
406  const G4double sub_x = fExpHall_x/5.;
407  const G4double sub_y = sub_x;
408 
409  // Create the hall
410  //
411  G4Tubs * subTub =
412  new G4Tubs("subTub", 0., sub_x, sub_y, -90.*deg, 180*deg);
413  G4LogicalVolume * subTubLV =
414  new G4LogicalVolume(subTub, fPb, "tubLV");
415  G4LogicalVolume *AssemblyLV = ConstructAssembly();
416  // G4PVPlacement * detAss =
417  new G4PVPlacement(0, G4ThreeVector(sub_x/3,0.0,0.0), AssemblyLV,
418  "AssemblyPhys", subTubLV, false, 0);
419  return subTubLV;
420 }
421 
422 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
423 //
424 // SubDetector2
425 //
427 {
428  const G4double sub_x = fExpHall_x/10.;
429  const G4double sub_y = sub_x*2.;
430  const G4double sub_z = sub_x;
431 
432  // Create the hall
433  //
434  G4Box * detHallBox =
435  new G4Box("detHallBox", sub_x, sub_y, sub_z);
436  G4LogicalVolume * detHallLV =
437  new G4LogicalVolume(detHallBox, fAluminum, "detHallLV");
438 
439  return detHallLV;
440 }
441 
442 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
443 //
444 // Assembly
445 //
447 {
448  const G4double big_x = fExpHall_x/17;
449  const G4double big_y = big_x;
450  const G4double big_z = big_x;
451 
452  // Create the Box
453  //
454  G4Box * OuterBox =
455  new G4Box("OuterBox", big_x, big_y, big_z);
456  G4LogicalVolume * OuterBoxLV =
457  new G4LogicalVolume(OuterBox, fAir, "OuterBoxLV");
458  // G4PVPlacement * OuterBoxPhys =
459  new G4PVPlacement(0, G4ThreeVector(0.0,0.0,0.0), OuterBoxLV,
460  "OuterBoxPhys", 0, false, 0);
461 
462  // The aluminum object's logical volume
463  //
464  const G4double bigL=big_x/2.5;
465  const G4double medL=big_x/8;
466  const G4double smalL=big_x/12;
467 
468  G4Box * BigBox =
469  new G4Box("BBox", bigL, bigL, bigL);
470  G4LogicalVolume * BigBoxLV =
471  new G4LogicalVolume(BigBox, fAluminum, "AlBigBoxLV");
472  G4Box * MedBox =
473  new G4Box("MBox", medL, medL, medL);
474  G4LogicalVolume * MedBoxLV1 =
475  new G4LogicalVolume(MedBox, fAluminum, "AlMedBoxLV1");
476  G4Box * SmallBox =
477  new G4Box("SBox", smalL, smalL, smalL);
478  G4LogicalVolume * SmallBoxLV =
479  new G4LogicalVolume(SmallBox, fAluminum, "AlSmaBoxLV");
480 
481  const G4double bigPlace=bigL+10.;
482  const G4double medPlace=medL+10.;
483  // G4PVPlacement * BigBoxPhys =
484  new G4PVPlacement(0, G4ThreeVector(bigPlace,0.0,0.0), BigBoxLV,
485  "AlPhysBig", OuterBoxLV, false, 0);
486 
487  // Construction of Tub
488  //
489  G4Tubs * BigTube =
490  new G4Tubs("BTube",0,smalL,smalL,-pi/2.,pi);
491 
492  // Construction of Reflection of Tub
493  //
494  G4ReflectX3D Xreflection;
495  G4Translate3D translation(-bigPlace, 0., 0.);
496  G4Transform3D transform =Xreflection;
497 
498  G4ReflectedSolid * ReflBig =
499  new G4ReflectedSolid("Refll_Big", BigTube, transform);
500  G4LogicalVolume * ReflBigLV =
501  new G4LogicalVolume(ReflBig, fXenon, "ReflBigAl");
502  new G4PVPlacement(0, G4ThreeVector(0.,0.0,0.0), ReflBigLV,
503  "AlPhysBigTube", SmallBoxLV, false, 0);
504  //
505  // LOOK HERE FOR ASSEMBLY
506  //
507 
508  // create Assembly of Boxes and Tubs
509  //
510  G4AssemblyVolume* assembly = new G4AssemblyVolume();
511  G4RotationMatrix* rot = new G4RotationMatrix();
512  G4ThreeVector posBig(-bigPlace, 0, 0);
513  G4ThreeVector posBig0(bigPlace/4, 0, 0);
514  G4ThreeVector posMed(-medPlace, 0, 0);
515  G4ThreeVector posMed0(medPlace, 0, 0);
516  G4ThreeVector position(0., 0., 0.);
517 
518  // Add to Assembly the MediumBox1
519  //
520  assembly->AddPlacedVolume(MedBoxLV1, posMed0, rot);
521 
522  // Add to Assembly the Small Box
523  //
524  assembly->AddPlacedVolume(SmallBoxLV, posMed, rot);
525 
526  // Place the Assembly
527  //
528  assembly->MakeImprint(BigBoxLV, posBig0, rot, 0);
529 
530  //
531  // LOOK HERE FOR ASSEMBLY with REFLECTION
532  //
533 
534  G4Translate3D translation1(-bigPlace, 0., 0.);
535  G4RotationMatrix* rotD3 = new G4RotationMatrix();
536  G4Transform3D rotation = G4Rotate3D(*rotD3);
537  G4ReflectX3D reflection;
538  G4Transform3D transform1 = translation1*rotation*reflection;
539 
540  assembly->MakeImprint(OuterBoxLV, transform1, 0, 0);
541 
542  return OuterBoxLV;
543 }
544 
545 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
546 //
547 // Parameterised Chamber
548 //
550 {
551  const G4double chamber_x = fExpHall_x/12.;
552  const G4double chamber_y = chamber_x;
553  const G4double chamber_z = chamber_x;
554 
555  // Create the hall
556  //
557  G4Box * paramChamberBox =
558  new G4Box("ChamberBox", chamber_x, chamber_y, chamber_z);
559  G4LogicalVolume * paramChamberLV =
560  new G4LogicalVolume(paramChamberBox, fAir, "ChamberLV");
561 
562  // Parametrisation Chamber (taken from N02 novice example)
563  //
564  G4int NbOfChambers = 5;
565  G4double ChamberWidth = 2*cm;
566  G4double ChamberSpacing = 8*cm;
567  G4double fTrackerLength = (NbOfChambers+1)*ChamberSpacing; // Full length
568  G4double trackerSize = 0.5*fTrackerLength;
569 
570  // An example of parameterised volume
571  // dummy values for G4Box -- modified by parameterised volume
572  //
573  G4Box *solidChamber =
574  new G4Box("chamber", 10*cm, 10*cm, 1*cm);
575  G4LogicalVolume* logicChamber =
576  new G4LogicalVolume(solidChamber, fAluminum, "Chamber", 0, 0, 0);
577 
578  G4double firstPosition = -trackerSize + 0.5*ChamberWidth;
579  G4double firstLength = fTrackerLength/10;
580  G4double lastLength = fTrackerLength;
581 
582  G4VPVParameterisation* chamberParam =
583  new G02ChamberParameterisation( NbOfChambers, // NoChambers
584  firstPosition, // Z of center of first
585  ChamberSpacing, // Z spacing of centers
586  ChamberWidth, // Width Chamber
587  firstLength, // lengthInitial
588  lastLength); // lengthFinal
589  // G4VPhysicalVolume* physiChamber =
590  new G4PVParameterised( "Chamber", // their name
591  logicChamber, // their logical volume
592  paramChamberLV, // mother logical volume
593  kZAxis, // Are placed along this axis
594  NbOfChambers, // Number of chambers
595  chamberParam); // The parametrisation
596  return paramChamberLV;
597 }
598 
599 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
600 //
601 // SetReadFile
602 //
604 {
605  fReadFile=File;
606  fWritingChoice=0;
607 }
608 
609 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
610 //
611 // SetWriteFile
612 //
614 {
615  fWriteFile=File;
616  fWritingChoice=1;
617 }
618 
619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
620 //
621 // SetStepFile
622 //
624 {
625  fStepFile=File;
626  fWritingChoice=3;
627 }