Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
B4dDetectorConstruction.cc
Go to the documentation of this file.
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 // $Id$
27 //
30 
32 
33 #include "G4Material.hh"
34 #include "G4NistManager.hh"
35 
36 #include "G4Box.hh"
37 #include "G4LogicalVolume.hh"
38 #include "G4PVPlacement.hh"
39 #include "G4PVReplica.hh"
40 #include "G4UniformMagField.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 "G4FieldManager.hh"
54 #include "G4GenericMessenger.hh"
55 
56 #include "G4PhysicalConstants.hh"
57 #include "G4SystemOfUnits.hh"
58 
59 #include <stdio.h>
60 
61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
62 
65  fMessenger(0),
66  fMagField(0),
67  fCheckOverlaps(true)
68 {
69  // Define /B4/det commands using generic messenger class
70  fMessenger
71  = new G4GenericMessenger(this, "/B4/det/", "Detector construction control");
72 
73  // Define /B4/det/setMagField command
74  G4GenericMessenger::Command& setMagFieldCmd
75  = fMessenger->DeclareMethod("setMagField",
77  "Define magnetic field value (in X direction");
78  setMagFieldCmd.SetUnitCategory("Magnetic flux density");
79 }
80 
81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
82 
84 {
85  delete fMagField;
86  delete fMessenger;
87 }
88 
89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90 
92 {
93  // Define materials
94  DefineMaterials();
95 
96  // Define volumes
97  return DefineVolumes();
98 
99 }
100 
101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
102 
103 void B4dDetectorConstruction::DefineMaterials()
104 {
105  // Lead material defined using NIST Manager
106  G4NistManager* nistManager = G4NistManager::Instance();
107  G4bool fromIsotopes = false;
108  nistManager->FindOrBuildMaterial("G4_Pb", fromIsotopes);
109 
110  // Liquid argon material
111  G4double a; // mass of a mole;
112  G4double z; // z=mean number of protons;
113  G4double density;
114  new G4Material("liquidArgon", z=18., a= 39.95*g/mole, density= 1.390*g/cm3);
115  // The argon by NIST Manager is a gas with a different density
116 
117  // Vacuum
118  new G4Material("Galactic", z=1., a=1.01*g/mole,density= universe_mean_density,
119  kStateGas, 2.73*kelvin, 3.e-18*pascal);
120 
121  // Print materials
123 }
124 
125 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
126 
127 G4VPhysicalVolume* B4dDetectorConstruction::DefineVolumes()
128 {
129  // Geometry parameters
130  G4int nofLayers = 10;
131  G4double absoThickness = 10.*mm;
132  G4double gapThickness = 5.*mm;
133  G4double calorSizeXY = 10.*cm;
134 
135  G4double layerThickness = absoThickness + gapThickness;
136  G4double calorThickness = nofLayers * layerThickness;
137  G4double worldSizeXY = 1.2 * calorSizeXY;
138  G4double worldSizeZ = 1.2 * calorThickness;
139 
140  // Get materials
141  G4Material* defaultMaterial = G4Material::GetMaterial("Galactic");
142  G4Material* absorberMaterial = G4Material::GetMaterial("G4_Pb");
143  G4Material* gapMaterial = G4Material::GetMaterial("liquidArgon");
144 
145  if ( ! defaultMaterial || ! absorberMaterial || ! gapMaterial ) {
146  G4cerr << "Cannot retrieve materials already defined. " << G4endl;
147  G4cerr << "Exiting application " << G4endl;
148  exit(1);
149  }
150 
151  //
152  // World
153  //
154  G4VSolid* worldS
155  = new G4Box("World", // its name
156  worldSizeXY/2, worldSizeXY/2, worldSizeZ/2); // its size
157 
158  G4LogicalVolume* worldLV
159  = new G4LogicalVolume(
160  worldS, // its solid
161  defaultMaterial, // its material
162  "World"); // its name
163 
164  G4VPhysicalVolume* worldPV
165  = new G4PVPlacement(
166  0, // no rotation
167  G4ThreeVector(), // at (0,0,0)
168  worldLV, // its logical volume
169  "World", // its name
170  0, // its mother volume
171  false, // no boolean operation
172  0, // copy number
173  fCheckOverlaps); // checking overlaps
174 
175  //
176  // Calorimeter
177  //
178  G4VSolid* calorimeterS
179  = new G4Box("Calorimeter", // its name
180  calorSizeXY/2, calorSizeXY/2, calorThickness/2); // its size
181 
182  G4LogicalVolume* calorLV
183  = new G4LogicalVolume(
184  calorimeterS, // its solid
185  defaultMaterial, // its material
186  "Calorimeter"); // its name
187 
188  new G4PVPlacement(
189  0, // no rotation
190  G4ThreeVector(), // at (0,0,0)
191  calorLV, // its logical volume
192  "Calorimeter", // its name
193  worldLV, // its mother volume
194  false, // no boolean operation
195  0, // copy number
196  fCheckOverlaps); // checking overlaps
197 
198  //
199  // Layer
200  //
201  G4VSolid* layerS
202  = new G4Box("Layer", // its name
203  calorSizeXY/2, calorSizeXY/2, layerThickness/2); // its size
204 
205  G4LogicalVolume* layerLV
206  = new G4LogicalVolume(
207  layerS, // its solid
208  defaultMaterial, // its material
209  "Layer"); // its name
210 
211  new G4PVReplica(
212  "Layer", // its name
213  layerLV, // its logical volume
214  calorLV, // its mother
215  kZAxis, // axis of replication
216  nofLayers, // number of replica
217  layerThickness); // witdth of replica
218 
219  //
220  // Absorber
221  //
222  G4VSolid* absorberS
223  = new G4Box("Abso", // its name
224  calorSizeXY/2, calorSizeXY/2, absoThickness/2); // its size
225 
226  G4LogicalVolume* absorberLV
227  = new G4LogicalVolume(
228  absorberS, // its solid
229  absorberMaterial, // its material
230  "Abso"); // its name
231 
232  new G4PVPlacement(
233  0, // no rotation
234  G4ThreeVector(0., 0., -gapThickness/2), // its position
235  absorberLV, // its logical volume
236  "Abso", // its name
237  layerLV, // its mother volume
238  false, // no boolean operation
239  0, // copy number
240  fCheckOverlaps); // checking overlaps
241 
242  //
243  // Gap
244  //
245  G4VSolid* gapS
246  = new G4Box("Gap", // its name
247  calorSizeXY/2, calorSizeXY/2, gapThickness/2); // its size
248 
249  G4LogicalVolume* gapLV
250  = new G4LogicalVolume(
251  gapS, // its solid
252  gapMaterial, // its material
253  "Gap"); // its name
254 
255  new G4PVPlacement(
256  0, // no rotation
257  G4ThreeVector(0., 0., absoThickness/2), // its position
258  gapLV, // its logical volume
259  "Gap", // its name
260  layerLV, // its mother volume
261  false, // no boolean operation
262  0, // copy number
263  fCheckOverlaps); // checking overlaps
264 
265  //
266  // print parameters
267  //
268  G4cout << "\n------------------------------------------------------------"
269  << "\n---> The calorimeter is " << nofLayers << " layers of: [ "
270  << absoThickness/mm << "mm of " << absorberMaterial->GetName()
271  << " + "
272  << gapThickness/mm << "mm of " << gapMaterial->GetName() << " ] "
273  << "\n------------------------------------------------------------\n";
274 
275 
276  //
277  // Scorers
278  //
279 
280  // declare Absorber as a MultiFunctionalDetector scorer
281  //
282  G4MultiFunctionalDetector* absDetector
283  = new G4MultiFunctionalDetector("Absorber");
284 
285  G4VPrimitiveScorer* primitive;
286  G4SDChargedFilter* charged = new G4SDChargedFilter("chargedFilter");
287  primitive = new G4PSEnergyDeposit("Edep");
288  absDetector->RegisterPrimitive(primitive);
289 
290  primitive = new G4PSTrackLength("TrackLength");
291  primitive ->SetFilter(charged);
292  absDetector->RegisterPrimitive(primitive);
293 
295  absorberLV->SetSensitiveDetector(absDetector);
296 
297  // declare Gap as a MultiFunctionalDetector scorer
298  //
299  G4MultiFunctionalDetector* gapDetector
300  = new G4MultiFunctionalDetector("Gap");
301 
302  primitive = new G4PSEnergyDeposit("Edep");
303  gapDetector->RegisterPrimitive(primitive);
304 
305  primitive = new G4PSTrackLength("TrackLength");
306  primitive ->SetFilter(charged);
307  gapDetector->RegisterPrimitive(primitive);
308 
310  gapLV->SetSensitiveDetector(gapDetector);
311 
312  //
313  // Visualization attributes
314  //
316 
317  G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
318  simpleBoxVisAtt->SetVisibility(true);
319  calorLV->SetVisAttributes(simpleBoxVisAtt);
320 
321  //
322  // Always return the physical World
323  //
324  return worldPV;
325 }
326 
327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
328 
330 {
331  // Apply a global uniform magnetic field along X axis
332  G4FieldManager* fieldManager
334 
335  // Delete the existing magnetic field
336  if ( fMagField ) delete fMagField;
337 
338  if ( fieldValue != 0. ) {
339  // create a new one if not null
340  fMagField
341  = new G4UniformMagField(G4ThreeVector(fieldValue, 0., 0.));
342 
343  fieldManager->SetDetectorField(fMagField);
344  fieldManager->CreateChordFinder(fMagField);
345  }
346  else {
347  fMagField = 0;
348  fieldManager->SetDetectorField(fMagField);
349  }
350 }