ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
B4dDetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file B4dDetectorConstruction.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 //
29 
31 
32 #include "G4Material.hh"
33 #include "G4NistManager.hh"
34 
35 #include "G4Box.hh"
36 #include "G4LogicalVolume.hh"
37 #include "G4PVPlacement.hh"
38 #include "G4PVReplica.hh"
40 #include "G4AutoDelete.hh"
41 
42 #include "G4SDManager.hh"
43 #include "G4SDChargedFilter.hh"
45 #include "G4VPrimitiveScorer.hh"
46 #include "G4PSEnergyDeposit.hh"
47 #include "G4PSTrackLength.hh"
48 
49 #include "G4VisAttributes.hh"
50 #include "G4Colour.hh"
51 
52 #include "G4PhysicalConstants.hh"
53 #include "G4SystemOfUnits.hh"
54 
55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
56 
59 
60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
61 
64  fCheckOverlaps(true)
65 {
66 }
67 
68 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69 
71 {
72 }
73 
74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
75 
77 {
78  // Define materials
80 
81  // Define volumes
82  return DefineVolumes();
83 }
84 
85 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
86 
88 {
89  // Lead material defined using NIST Manager
90  auto nistManager = G4NistManager::Instance();
91  nistManager->FindOrBuildMaterial("G4_Pb");
92 
93  // Liquid argon material
94  G4double a; // mass of a mole;
95  G4double z; // z=mean number of protons;
96  G4double density;
97  new G4Material("liquidArgon", z=18., a= 39.95*g/mole, density= 1.390*g/cm3);
98  // The argon by NIST Manager is a gas with a different density
99 
100  // Vacuum
101  new G4Material("Galactic", z=1., a=1.01*g/mole,density= universe_mean_density,
102  kStateGas, 2.73*kelvin, 3.e-18*pascal);
103 
104  // Print materials
106 }
107 
108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
109 
111 {
112  // Geometry parameters
113  G4int nofLayers = 10;
114  G4double absoThickness = 10.*mm;
115  G4double gapThickness = 5.*mm;
116  G4double calorSizeXY = 10.*cm;
117 
118  auto layerThickness = absoThickness + gapThickness;
119  auto calorThickness = nofLayers * layerThickness;
120  auto worldSizeXY = 1.2 * calorSizeXY;
121  auto worldSizeZ = 1.2 * calorThickness;
122 
123  // Get materials
124  auto defaultMaterial = G4Material::GetMaterial("Galactic");
125  auto absorberMaterial = G4Material::GetMaterial("G4_Pb");
126  auto gapMaterial = G4Material::GetMaterial("liquidArgon");
127 
128  if ( ! defaultMaterial || ! absorberMaterial || ! gapMaterial ) {
130  msg << "Cannot retrieve materials already defined.";
131  G4Exception("B4DetectorConstruction::DefineVolumes()",
132  "MyCode0001", FatalException, msg);
133  }
134 
135  //
136  // World
137  //
138  auto worldS
139  = new G4Box("World", // its name
140  worldSizeXY/2, worldSizeXY/2, worldSizeZ/2); // its size
141 
142  auto worldLV
143  = new G4LogicalVolume(
144  worldS, // its solid
145  defaultMaterial, // its material
146  "World"); // its name
147 
148  auto worldPV
149  = new G4PVPlacement(
150  0, // no rotation
151  G4ThreeVector(), // at (0,0,0)
152  worldLV, // its logical volume
153  "World", // its name
154  0, // its mother volume
155  false, // no boolean operation
156  0, // copy number
157  fCheckOverlaps); // checking overlaps
158 
159  //
160  // Calorimeter
161  //
162  auto calorimeterS
163  = new G4Box("Calorimeter", // its name
164  calorSizeXY/2, calorSizeXY/2, calorThickness/2); // its size
165 
166  auto calorLV
167  = new G4LogicalVolume(
168  calorimeterS, // its solid
169  defaultMaterial, // its material
170  "Calorimeter"); // its name
171 
172  new G4PVPlacement(
173  0, // no rotation
174  G4ThreeVector(), // at (0,0,0)
175  calorLV, // its logical volume
176  "Calorimeter", // its name
177  worldLV, // its mother volume
178  false, // no boolean operation
179  0, // copy number
180  fCheckOverlaps); // checking overlaps
181 
182  //
183  // Layer
184  //
185  auto layerS
186  = new G4Box("Layer", // its name
187  calorSizeXY/2, calorSizeXY/2, layerThickness/2); // its size
188 
189  auto layerLV
190  = new G4LogicalVolume(
191  layerS, // its solid
192  defaultMaterial, // its material
193  "Layer"); // its name
194 
195  new G4PVReplica(
196  "Layer", // its name
197  layerLV, // its logical volume
198  calorLV, // its mother
199  kZAxis, // axis of replication
200  nofLayers, // number of replica
201  layerThickness); // witdth of replica
202 
203  //
204  // Absorber
205  //
206  auto absorberS
207  = new G4Box("Abso", // its name
208  calorSizeXY/2, calorSizeXY/2, absoThickness/2); // its size
209 
210  auto absorberLV
211  = new G4LogicalVolume(
212  absorberS, // its solid
213  absorberMaterial, // its material
214  "AbsoLV"); // its name
215 
216  new G4PVPlacement(
217  0, // no rotation
218  G4ThreeVector(0., 0., -gapThickness/2), // its position
219  absorberLV, // its logical volume
220  "Abso", // its name
221  layerLV, // its mother volume
222  false, // no boolean operation
223  0, // copy number
224  fCheckOverlaps); // checking overlaps
225 
226  //
227  // Gap
228  //
229  auto gapS
230  = new G4Box("Gap", // its name
231  calorSizeXY/2, calorSizeXY/2, gapThickness/2); // its size
232 
233  auto gapLV
234  = new G4LogicalVolume(
235  gapS, // its solid
236  gapMaterial, // its material
237  "GapLV"); // its name
238 
239  new G4PVPlacement(
240  0, // no rotation
241  G4ThreeVector(0., 0., absoThickness/2), // its position
242  gapLV, // its logical volume
243  "Gap", // its name
244  layerLV, // its mother volume
245  false, // no boolean operation
246  0, // copy number
247  fCheckOverlaps); // checking overlaps
248 
249  //
250  // print parameters
251  //
252  G4cout
253  << G4endl
254  << "------------------------------------------------------------" << G4endl
255  << "---> The calorimeter is " << nofLayers << " layers of: [ "
256  << absoThickness/mm << "mm of " << absorberMaterial->GetName()
257  << " + "
258  << gapThickness/mm << "mm of " << gapMaterial->GetName() << " ] " << G4endl
259  << "------------------------------------------------------------" << G4endl;
260 
261  //
262  // Visualization attributes
263  //
264  worldLV->SetVisAttributes (G4VisAttributes::GetInvisible());
265 
266  auto simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
267  simpleBoxVisAtt->SetVisibility(true);
268  calorLV->SetVisAttributes(simpleBoxVisAtt);
269 
270  //
271  // Always return the physical World
272  //
273  return worldPV;
274 }
275 
276 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
277 
279 {
281  //
282  // Scorers
283  //
284 
285  // declare Absorber as a MultiFunctionalDetector scorer
286  //
287  auto absDetector = new G4MultiFunctionalDetector("Absorber");
289 
290  G4VPrimitiveScorer* primitive;
291  primitive = new G4PSEnergyDeposit("Edep");
292  absDetector->RegisterPrimitive(primitive);
293 
294  primitive = new G4PSTrackLength("TrackLength");
295  auto charged = new G4SDChargedFilter("chargedFilter");
296  primitive ->SetFilter(charged);
297  absDetector->RegisterPrimitive(primitive);
298 
299  SetSensitiveDetector("AbsoLV",absDetector);
300 
301  // declare Gap as a MultiFunctionalDetector scorer
302  //
303  auto gapDetector = new G4MultiFunctionalDetector("Gap");
305 
306  primitive = new G4PSEnergyDeposit("Edep");
307  gapDetector->RegisterPrimitive(primitive);
308 
309  primitive = new G4PSTrackLength("TrackLength");
310  primitive ->SetFilter(charged);
311  gapDetector->RegisterPrimitive(primitive);
312 
313  SetSensitiveDetector("GapLV",gapDetector);
314 
315  //
316  // Magnetic field
317  //
318  // Create global magnetic field messenger.
319  // Uniform magnetic field is then created automatically if
320  // the field value is not zero.
321  G4ThreeVector fieldValue;
324 
325  // Register the field messenger for deleting
327 }
328 
329 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......