ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PurgMagDetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PurgMagDetectorConstruction.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 // Code developed by:
27 // S.Larsson
28 //
29 // *****************************************
30 // * *
31 // * PurgMagDetectorConstruction.cc *
32 // * *
33 // *****************************************
34 //
35 //
38 #include "globals.hh"
39 #include "G4PhysicalConstants.hh"
40 #include "G4SystemOfUnits.hh"
41 #include "G4ThreeVector.hh"
42 #include "G4Material.hh"
43 #include "G4Box.hh"
44 #include "G4Trd.hh"
45 #include "G4Tubs.hh"
46 #include "G4LogicalVolume.hh"
47 #include "G4PVPlacement.hh"
48 #include "G4PVReplica.hh"
49 #include "G4PVParameterised.hh"
50 #include "G4Mag_UsualEqRhs.hh"
51 #include "G4FieldManager.hh"
53 #include "G4EqMagElectricField.hh"
54 
55 #include "G4ChordFinder.hh"
56 #include "G4UniformMagField.hh"
57 #include "G4ExplicitEuler.hh"
58 #include "G4ImplicitEuler.hh"
59 #include "G4SimpleRunge.hh"
60 #include "G4SimpleHeum.hh"
61 #include "G4ClassicalRK4.hh"
62 #include "G4HelixExplicitEuler.hh"
63 #include "G4HelixImplicitEuler.hh"
64 #include "G4HelixSimpleRunge.hh"
65 #include "G4CashKarpRKF45.hh"
66 #include "G4RKG3_Stepper.hh"
67 
68 #include "G4VisAttributes.hh"
69 #include "G4Colour.hh"
70 #include "G4UnitsTable.hh"
71 #include "G4ios.hh"
72 
73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
74 // Possibility to turn off (0) magnetic field and measurement volume.
75 #define GAP 1 // Magnet geometric volume
76 #define MAG 1 // Magnetic field grid
77 #define MEASUREVOL 1 // Volume for measurement
78 
79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
80 
82 
83  :physiWorld(NULL), logicWorld(NULL), solidWorld(NULL),
84  physiGap1(NULL), logicGap1(NULL), solidGap1(NULL),
85  physiGap2(NULL), logicGap2(NULL), solidGap2(NULL),
86  physiMeasureVolume(NULL), logicMeasureVolume(NULL),
87  solidMeasureVolume(NULL),
88  WorldMaterial(NULL),
89  GapMaterial(NULL)
90 
91 {
92  fField.Put(0);
96 }
97 
98 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
99 
101 {}
102 
103 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
104 
106 
107 {
108  DefineMaterials();
109  return ConstructCalorimeter();
110 }
111 
112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
113 
115 {
116  //This function illustrates the possible ways to define materials.
117  //Density and mass per mole taken from Physics Handbook for Science
118  //and engineering, sixth edition. This is a general material list
119  //with extra materials for other examples.
120 
121  G4String name, symbol;
122  G4double density;
123 
124  G4int ncomponents, natoms;
125  G4double fractionmass;
126  G4double temperature, pressure;
127 
128  // Define Elements
129  // Example: G4Element* Notation = new G4Element ("Element", "Notation", z, a);
130  G4Element* H = new G4Element ("Hydrogen", "H", 1. , 1.01*g/mole);
131  G4Element* N = new G4Element ("Nitrogen", "N", 7., 14.01*g/mole);
132  G4Element* O = new G4Element ("Oxygen" , "O", 8. , 16.00*g/mole);
133  G4Element* Ar = new G4Element ("Argon" , "Ar", 18., 39.948*g/mole );
134 
135 
136  // Define Material
137  // Example: G4Material* Notation = new G4Material("Material", z, a, density);
138  /* Not used in this setup, will be used in further development.
139  G4Material* He = new G4Material("Helium", 2., 4.00*g/mole, 0.178*mg/cm3);
140  G4Material* Be = new G4Material("Beryllium", 4., 9.01*g/mole, 1.848*g/cm3);
141  G4Material* W = new G4Material("Tungsten", 74., 183.85*g/mole, 19.30*g/cm3);
142  G4Material* Cu = new G4Material("Copper", 29., 63.55*g/mole, 8.96*g/cm3);
143  */
144  G4Material* Fe = new G4Material("Iron", 26., 55.84*g/mole, 7.87*g/cm3);
145 
146  // Define materials from elements.
147 
148  // Case 1: chemical molecule
149  // Water
150  density = 1.000*g/cm3;
151  G4Material* H2O = new G4Material(name="H2O" , density, ncomponents=2);
152  H2O->AddElement(H, natoms=2);
153  H2O->AddElement(O, natoms=1);
154 
155  // Case 2: mixture by fractional mass.
156  // Air
157  density = 1.290*mg/cm3;
158  G4Material* Air = new G4Material(name="Air" , density, ncomponents=2);
159  Air->AddElement(N, fractionmass=0.7);
160  Air->AddElement(O, fractionmass=0.3);
161 
162  // Vacuum
163  density = 1.e-5*g/cm3;
164  pressure = 2.e-2*bar;
165  temperature = STP_Temperature; //from PhysicalConstants.h
166  G4Material* vacuum = new G4Material(name="vacuum", density, ncomponents=1,
167  kStateGas,temperature,pressure);
168  vacuum->AddMaterial(Air, fractionmass=1.);
169 
170 
171  // Laboratory vacuum: Dry air (average composition)
172  density = 1.7836*mg/cm3 ; // STP
173  G4Material* Argon = new G4Material(name="Argon", density, ncomponents=1);
174  Argon->AddElement(Ar, 1);
175 
176  density = 1.25053*mg/cm3 ; // STP
177  G4Material* Nitrogen = new G4Material(name="N2", density, ncomponents=1);
178  Nitrogen->AddElement(N, 2);
179 
180  density = 1.4289*mg/cm3 ; // STP
181  G4Material* Oxygen = new G4Material(name="O2", density, ncomponents=1);
182  Oxygen->AddElement(O, 2);
183 
184 
185  density = 1.2928*mg/cm3 ; // STP
186  density *= 1.0e-8 ; // pumped vacuum
187 
188  temperature = STP_Temperature;
189  pressure = 1.0e-8*STP_Pressure;
190 
191  G4Material* LaboratoryVacuum = new G4Material(name="LaboratoryVacuum",
192  density,ncomponents=3,
193  kStateGas,temperature,pressure);
194  LaboratoryVacuum->AddMaterial( Nitrogen, fractionmass = 0.7557 ) ;
195  LaboratoryVacuum->AddMaterial( Oxygen, fractionmass = 0.2315 ) ;
196  LaboratoryVacuum->AddMaterial( Argon, fractionmass = 0.0128 ) ;
197 
198 
200 
201 
202  // Default materials in setup.
203  WorldMaterial = LaboratoryVacuum;
204  GapMaterial = Fe;
205 
206 
207  G4cout << "end material"<< G4endl;
208 }
209 
210 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
212 {
213  // Complete the parameters definition
214 
215  //The World
216  WorldSizeXY = 300.*cm; // Cube
217  WorldSizeZ = 300.*cm;
218 
219  //Measurement volume
220  MeasureVolumeSizeXY = 280.*cm; // Cubic slice
221  MeasureVolumeSizeZ = 1.*cm;
222 
223  // Position of measurement volume.
224  // SSD is Source to Surface Distance. Source in origo and measurements 50 cm
225  // below in the z-direction (symbolizin a patient at SSD = 50 cm)
226 
227  SSD = 50.*cm;
229 
230 
231  // Geometric definition of the gap of the purging magnet. Approximation of
232  // the shape of the pole gap.
233 
234  GapSizeY1 = 10.*cm; // length along x at the surface positioned at -dz
235  GapSizeY2 = 10.*cm; // length along x at the surface positioned at +dz
236  GapSizeX1 = 10.*cm; // length along y at the surface positioned at -dz
237  GapSizeX2 = 18.37*cm; // length along y at the surface positioned at +dz
238  GapSizeZ = 11.5*cm; // length along z axis
239 
240  Gap1PosY = 0.*cm;
241  Gap1PosX = -9.55*cm;
242  Gap1PosZ = -6.89*cm;
243 
244  Gap2PosY = 0.*cm;
245  Gap2PosX = 9.55*cm;
246  Gap2PosZ = -6.89*cm;
247 
248 
249  // Coordinate correction for field grif.
250  // Gap opening at z = -11.4 mm.
251  // In field grid coordonates gap at z = -0.007m in field from z = 0.0m to
252  // z = 0.087m.
253  // -> zOffset = -11.4-(-7) = 4.4 mm
254 
255  zOffset = 4.4*mm;
256 
257 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
258 //
259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
260 
261 // Some out prints of the setup.
262 
263  G4cout << "\n-----------------------------------------------------------"
264  << "\n Geometry and materials"
265  << "\n-----------------------------------------------------------"
266  << "\n ---> World:"
267  << "\n ---> " << WorldMaterial->GetName() << " in World"
268  << "\n ---> " << "WorldSizeXY: " << G4BestUnit(WorldSizeXY,"Length")
269  << "\n ---> " << "WorldSizeZ: " << G4BestUnit(WorldSizeZ,"Length");
270 
271 #if GAP
272  G4cout << "\n-----------------------------------------------------------"
273  << "\n ---> Purging Magnet:"
274  << "\n ---> " << "Gap made of "<< GapMaterial->GetName()
275  << "\n ---> " << "GapSizeY1: " << G4BestUnit(GapSizeY1,"Length")
276  << "\n ---> " << "GapSizeY2: " << G4BestUnit(GapSizeY2,"Length")
277  << "\n ---> " << "GapSizeX1: " << G4BestUnit(GapSizeX1,"Length")
278  << "\n ---> " << "GapSizeX2: " << G4BestUnit(GapSizeX2,"Length");
279 #endif
280 
281 #if MEASUREVOL
282  G4cout << "\n-----------------------------------------------------------"
283  << "\n ---> Measurement Volume:"
284  << "\n ---> " << WorldMaterial->GetName() << " in Measurement volume"
285  << "\n ---> " << "MeasureVolumeXY: " << G4BestUnit(MeasureVolumeSizeXY,"Length")
286  << "\n ---> " << "MeasureVolumeZ: " << G4BestUnit(MeasureVolumeSizeZ,"Length")
287  << "\n ---> " << "At SSD = " << G4BestUnit(MeasureVolumePosition,"Length");
288 #endif
289 
290  G4cout << "\n-----------------------------------------------------------\n";
291 
292 
293 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
294  //
295  // World
296  //
297 
298 
299  solidWorld = new G4Box("World", //its name
300  WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2); //its size
301 
302 
303  logicWorld = new G4LogicalVolume(solidWorld, //its solid
304  WorldMaterial, //its material
305  "World"); //its name
306 
307  physiWorld = new G4PVPlacement(0, //no rotation
308  G4ThreeVector(), //at (0,0,0)
309  "World", //its name
310  logicWorld, //its logical volume
311  NULL, //its mother volume
312  false, //no boolean operation
313  0); //copy number
314 
315  // Visualization attributes
316  G4VisAttributes* simpleWorldVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); //White
317  simpleWorldVisAtt->SetVisibility(true);
318  logicWorld->SetVisAttributes(simpleWorldVisAtt);
319 
320 
321 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
322  //
323  // Measurement Volume
324  //
325 
326 #if MEASUREVOL
327 
328  solidMeasureVolume = new G4Box("MeasureVolume", //its name
330 
332  WorldMaterial, //its material
333  "MeasureVolume"); //its name
334 
335  physiMeasureVolume = new G4PVPlacement(0, //no rotation
336  G4ThreeVector(0.,0.,MeasureVolumePosition), //at (0,0,0)
337  "MeasureVolume", //its name
338  logicMeasureVolume, //its logical volume
339  physiWorld, //its mother volume
340  false, //no boolean operation
341  0); //copy number
342 
343  // Visualization attributes
344  G4VisAttributes* simpleMeasureVolumeVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); //White
345  simpleMeasureVolumeVisAtt->SetVisibility(true);
346  simpleMeasureVolumeVisAtt->SetForceSolid(true);
347  logicMeasureVolume->SetVisAttributes(simpleMeasureVolumeVisAtt);
348 
349 #endif
350 
351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
352  //
353  //Gap cone. Opening 20 deg. Two separate trapezoids. Iron.
354  //
355 
356 #if GAP
357 
358  //Gap part 1, placed in negative x-direction.
359 
360  solidGap1 = new G4Trd("Gap1",
361  GapSizeX1/2, // Half-length along x at the surface positioned at -dz
362  GapSizeX2/2, // Half-length along x at the surface positioned at +dz
363  GapSizeY1/2, // Half-length along y at the surface positioned at -dz
364  GapSizeY2/2, // Half-length along y at the surface positioned at +dz
365  GapSizeZ/2 ); // Half-length along z axis
366 
367  logicGap1 = new G4LogicalVolume(solidGap1, //its solid
368  GapMaterial, //its material
369  "Gap1"); //its name
370 
371  physiGap1 = new G4PVPlacement(0, //90 deg rotation
373  "Gap1", //its name
374  logicGap1, //its logical volume
375  physiWorld, //its mother volume
376  false, //no boolean operation
377  0); //copy number
378 
379  //Gap part 2, placed in positive x-direction.
380 
381  solidGap2 = new G4Trd("Gap2",
382  GapSizeX1/2, // Half-length along x at the surface positioned at -dz
383  GapSizeX2/2, // Half-length along x at the surface positioned at +dz
384  GapSizeY1/2, // Half-length along y at the surface positioned at -dz
385  GapSizeY2/2, // Half-length along y at the surface positioned at +dz
386  GapSizeZ/2 ); // Half-length along z axis
387 
388  logicGap2 = new G4LogicalVolume(solidGap2, //its solid
389  GapMaterial, //its material
390  "Gap2"); //its name
391 
392  physiGap2 = new G4PVPlacement(0, //no rotation
394  "Gap2", //its name
395  logicGap2, //its logical volume
396  physiWorld, //its mother volume
397  false, //no boolean operation
398  0); //copy number
399 
400  // Visualization attributes
401  G4VisAttributes* simpleGap1VisAtt= new G4VisAttributes(G4Colour(0.0,0.0,1.0)); //yellow
402  simpleGap1VisAtt->SetVisibility(true);
403  simpleGap1VisAtt->SetForceSolid(true);
404  logicGap1->SetVisAttributes(simpleGap1VisAtt);
405 
406  G4VisAttributes* simpleGap2VisAtt= new G4VisAttributes(G4Colour(0.0,0.0,1.0)); //yellow
407  simpleGap2VisAtt->SetVisibility(true);
408  simpleGap2VisAtt->SetForceSolid(true);
409  logicGap2->SetVisAttributes(simpleGap2VisAtt);
410 
411 #endif
412 
413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
414 
415  return physiWorld;
416 }
417 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
418 
420 {
421 // Magnetic Field - Purging magnet
422 //
423 #if MAG
424 
425  if (fField.Get() == 0)
426  {
427  //Field grid in A9.TABLE. File must be in accessible from run urn directory.
428  G4MagneticField* PurgMagField= new PurgMagTabulatedField3D("PurgMag3D.TABLE", zOffset);
429  fField.Put(PurgMagField);
430 
431  //This is thread-local
432  G4FieldManager* pFieldMgr =
434 
435  G4cout<< "DeltaStep "<<pFieldMgr->GetDeltaOneStep()/mm <<"mm" <<G4endl;
436  //G4ChordFinder *pChordFinder = new G4ChordFinder(PurgMagField);
437 
438  pFieldMgr->SetDetectorField(fField.Get());
439  pFieldMgr->CreateChordFinder(fField.Get());
440 
441  }
442 #endif
443 }