ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DetectorConstruction.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 //
28 //
29 //
30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
32 
33 #include "DetectorConstruction.hh"
34 #include "DetectorMessenger.hh"
35 
36 #include "G4Material.hh"
37 #include "G4Box.hh"
38 #include "G4LogicalVolume.hh"
39 #include "G4PVPlacement.hh"
40 #include "G4UniformMagField.hh"
41 
42 #include "G4GeometryManager.hh"
43 #include "G4PhysicalVolumeStore.hh"
44 #include "G4LogicalVolumeStore.hh"
45 #include "G4SolidStore.hh"
46 
47 #include "G4NistManager.hh"
48 #include "G4UnitsTable.hh"
49 
50 #include "G4FieldManager.hh"
52 #include "G4RunManager.hh"
53 
54 #include "G4PhysicalConstants.hh"
55 #include "G4SystemOfUnits.hh"
56 
57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
58 
61  fMagField(nullptr),
62  fLAbsor(nullptr),
63  fLWorld(nullptr)
64 {
65  // default parameter values
68 
69  fTallyNumber = 0;
70  for (G4int j=0; j<kMaxTally; j++) {
71  fTallySize[j] = fTallyPosition[j] = G4ThreeVector(0.,0.,0.);
72  fTallyMass[j] = 0.;
73  fLTally[j] = nullptr;
74  }
75 
77 
78  // create commands for interactive definition of the detector
80 }
81 
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83 
85 {
86  delete fDetectorMessenger;
87 }
88 
89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90 
92 {
93  //
94  // define Elements
95  //
96  G4double z, a;
97 
98  G4Element* H = new G4Element("Hydrogen", "H", z= 1, a= 1.008*g/mole);
99  G4Element* N = new G4Element("Nitrogen", "N", z= 7, a= 14.01*g/mole);
100  G4Element* O = new G4Element("Oxygen" , "O", z= 8, a= 16.00*g/mole);
101 
102  //
103  // define Materials.
104  //
105  G4double density, temperature, pressure;
106  G4int ncomponents, natoms;
107  G4double fractionmass;
108 
109  G4Material* H2O =
110  new G4Material("Water", density= 1.0*g/cm3, ncomponents=2);
111  H2O->AddElement(H, natoms=2);
112  H2O->AddElement(O, natoms=1);
114 
115  // In this line both G4_WATER and Water_1.05 will be constructed
117  BuildMaterialWithNewDensity("Water_1.05","G4_WATER",1.05*g/cm3);
118 
119  G4Material* Air =
120  new G4Material("Air" , density= 1.290*mg/cm3, ncomponents=2);
121  Air->AddElement(N, fractionmass=0.7);
122  Air->AddElement(O, fractionmass=0.3);
123 
124  density = 1.e-5*g/cm3;
125  pressure = 2.e-2*bar;
126  temperature = STP_Temperature; // From PhysicalConstants.h .
127  G4Material* vac = new G4Material( "TechVacuum", density, 1,
128  kStateGas, temperature, pressure );
129  vac->AddMaterial( Air, 1. );
130 
131  density = universe_mean_density; //from PhysicalConstants.h
132  pressure = 3.e-18*pascal;
133  temperature = 2.73*kelvin;
134  G4Material* vacuum =
135  new G4Material("Galactic",z= 1,a= 1.008*g/mole,density,
136  kStateGas,temperature,pressure);
137 
138  //default materials
139  fAbsorMaterial = H2O;
140  fWorldMaterial = vacuum;
141 }
142 
143 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
144 
146 {
147  // World
148  //
149  G4Box*
150  sWorld = new G4Box("World", //name
151  fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //dimensions
152 
153  fLWorld = new G4LogicalVolume(sWorld, //shape
154  fWorldMaterial, //material
155  "World"); //name
156 
158  pWorld = new G4PVPlacement(0, //no rotation
159  G4ThreeVector(0.,0.,0.), //at (0,0,0)
160  fLWorld, //logical volume
161  "World", //name
162  0, //mother volume
163  false, //no boolean operation
164  0); //copy number
165  //
166  // Absorber
167  //
168  G4Box*
169  sAbsor = new G4Box("Absorber", //name
170  fAbsorSizeX/2,fAbsorSizeYZ/2,fAbsorSizeYZ/2); //dimensions
171 
172  fLAbsor = new G4LogicalVolume(sAbsor, //shape
173  fAbsorMaterial, //material
174  "Absorber"); //name
175 
176 
177  new G4PVPlacement(0, //no rotation
178  G4ThreeVector(0.,0.,0.), //at (0,0,0)
179  fLAbsor, //logical volume
180  "Absorber", //name
181  fLWorld, //mother volume
182  false, //no boolean operation
183  0); //copy number
184  //
185  // Tallies (optional)
186  //
187  if (fTallyNumber > 0) {
188  for (G4int j=0; j<fTallyNumber; ++j) {
189 
190  G4Box* sTally = new G4Box("Tally",
191  fTallySize[j].x()/2,fTallySize[j].y()/2,fTallySize[j].z()/2);
192 
193  fLTally[j] = new G4LogicalVolume(sTally,fAbsorMaterial,"Tally");
194 
195  new G4PVPlacement(0, //no rotation
196  fTallyPosition[j], //position
197  fLTally[j], //logical volume
198  "Tally", //name
199  fLAbsor, //mother volume
200  false, //no boolean operation
201  j+1); //copy number
202 
203  fTallyMass[j] = fTallySize[j].x()*fTallySize[j].y()*fTallySize[j].z()
205  }
206  }
207 
208  PrintParameters();
209 
210  //
211  //always return the World volume
212  //
213  return pWorld;
214 }
215 
216 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
217 
219 {
221  G4cout << "\n---------------------------------------------------------\n";
222  G4cout << "---> The Absorber is " << G4BestUnit(fAbsorSizeX,"Length")
223  << " of " << fAbsorMaterial->GetName() << G4endl;
224  G4cout << "\n---------------------------------------------------------\n";
225 
226  if (fTallyNumber > 0) {
227  G4cout << "---> There are " << fTallyNumber << " tallies : " << G4endl;
228  for (G4int j=0; j<fTallyNumber; ++j) {
229  G4cout << "fTally " << j << ": "
230  << fAbsorMaterial->GetName()
231  << ", mass = " << G4BestUnit(fTallyMass[j],"Mass")
232  << " size = " << G4BestUnit(fTallySize[j],"Length")
233  << " position = " << G4BestUnit(fTallyPosition[j],"Length")
234  << G4endl;
235  }
236  G4cout << "\n---------------------------------------------------------\n";
237  }
238 }
239 
240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
241 
243 {
244  fAbsorSizeX = value;
245  fWorldSizeX = 1.2*fAbsorSizeX;
246 }
247 
248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
249 
251 {
252  fAbsorSizeYZ = value;
254 }
255 
256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
257 
258 void DetectorConstruction::SetMaterial(const G4String& materialChoice)
259 {
260  // search the material by its name
261  G4Material* pttoMaterial =
262  G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
263  if (pttoMaterial && pttoMaterial != fAbsorMaterial) {
264  // change target material everywhere
265  fAbsorMaterial = pttoMaterial;
266  for (G4int j=0; j<fTallyNumber; ++j) {
267  if(fLTally[j]) {
268  fLTally[j]->SetMaterial(pttoMaterial);
269  fTallyMass[j] = fTallySize[j].x()*fTallySize[j].y()*fTallySize[j].z()
270  *(pttoMaterial->GetDensity());
271  }
272  }
273  if(fLAbsor) {
276  }
277  }
278 }
279 
280 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
281 
282 void DetectorConstruction::SetWorldMaterial(const G4String& materialChoice)
283 {
284  // search the material by its name
285  G4Material* pttoMaterial =
286  G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
287  if (pttoMaterial && pttoMaterial != fWorldMaterial) {
288  fWorldMaterial = pttoMaterial;
289  if(fLWorld) {
292  }
293  }
294 }
295 
296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
297 
299 {
300  //apply a global uniform magnetic field along Z axis
301  G4FieldManager* fieldMgr
303 
304  if (fMagField) delete fMagField; //delete the existing magn field
305 
306  if (fieldValue!=0.) // create a new one if non nul
307  {
308  fMagField = new G4UniformMagField(G4ThreeVector(0.,0.,fieldValue));
309  fieldMgr->SetDetectorField(fMagField);
310  fieldMgr->CreateChordFinder(fMagField);
311  }
312  else
313  {
314  fMagField = nullptr;
315  fieldMgr->SetDetectorField(fMagField);
316  }
317 }
318 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
319 
321 {
322  if(value >= 0 && value <kMaxTally) {
323  fTallyNumber = value;
324  } else {
325  G4cout << "### DetectorConstruction::SetTallyNumber WARNING: wrong tally "
326  << "number " << value << " is ignored" << G4endl;
327  }
328 }
329 
330 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
331 
333 {
334  if(j >= 0 && j < kMaxTally) {
335  fTallySize[j] = value;
336  } else {
337  G4cout << "### DetectorConstruction::SetTallyNumber WARNING: wrong tally "
338  << "number " << j << " is ignored" << G4endl;
339  }
340 }
341 
342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
343 
345 {
346  if(j >= 0 && j < kMaxTally) {
347  fTallyPosition[j] = value;
348  } else {
349  G4cout << "### DetectorConstruction::SetTallyPosition WARNING: wrong tally "
350  << "number " << j << " is ignored" << G4endl;
351  }
352 }
353 
355 {
356  if(j >= 0 && j < kMaxTally) {
357  return fTallyMass[j];
358  } else {
359  G4cout << "### DetectorConstruction::GetTallyMass WARNING: wrong tally "
360  << "number " << j << " is ignored" << G4endl;
361  return 0.0;
362  }
363 }
364 
366 {
367  if(j >= 0 && j < kMaxTally) {
368  return fLTally[j];
369  } else {
370  G4cout << "### DetectorConstruction::GetLOgicalTally WARNING: wrong tally "
371  << "number " << j << " is ignored" << G4endl;
372  return nullptr;
373  }
374 }
375 
376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......