Geant4  10.01
B5DetectorConstruction.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: B5DetectorConstruction.cc 77656 2013-11-27 08:52:57Z gcosmo $
27 //
30 
32 #include "B5MagneticField.hh"
34 #include "B5HodoscopeSD.hh"
35 #include "B5DriftChamberSD.hh"
36 #include "B5EmCalorimeterSD.hh"
37 #include "B5HadCalorimeterSD.hh"
38 
39 #include "G4FieldManager.hh"
41 #include "G4Mag_UsualEqRhs.hh"
42 #include "G4AutoDelete.hh"
43 
44 #include "G4Material.hh"
45 #include "G4Element.hh"
46 #include "G4MaterialTable.hh"
47 #include "G4NistManager.hh"
48 
49 #include "G4VSolid.hh"
50 #include "G4Box.hh"
51 #include "G4Tubs.hh"
52 #include "G4LogicalVolume.hh"
53 #include "G4VPhysicalVolume.hh"
54 #include "G4PVPlacement.hh"
55 #include "G4PVParameterised.hh"
56 #include "G4PVReplica.hh"
57 #include "G4UserLimits.hh"
58 
59 #include "G4SDManager.hh"
60 #include "G4VSensitiveDetector.hh"
61 #include "G4RunManager.hh"
62 #include "G4GenericMessenger.hh"
63 
64 #include "G4VisAttributes.hh"
65 #include "G4Colour.hh"
66 
67 #include "G4ios.hh"
68 #include "G4SystemOfUnits.hh"
69 
70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
71 
74 
75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76 
79  fMessenger(0),
80  fHodoscope1Logical(0), fHodoscope2Logical(0),
81  fWirePlane1Logical(0), fWirePlane2Logical(0),
82  fCellLogical(0), fHadCalScintiLogical(0),
83  fMagneticLogical(0),
84  fVisAttributes(),
85  fArmAngle(30.*deg), fArmRotation(0), fSecondArmPhys(0)
86 
87 {
89  fArmRotation->rotateY(fArmAngle);
90 
91  // define commands for this class
93 }
94 
95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
96 
98 {
99  delete fArmRotation;
100  delete fMessenger;
101 
102  for (G4int i=0; i<G4int(fVisAttributes.size()); ++i)
103  {
104  delete fVisAttributes[i];
105  }
106 }
107 
108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
109 
111 {
112  // Construct materials
114  G4Material* air = G4Material::GetMaterial("G4_AIR");
115  //G4Material* argonGas = G4Material::GetMaterial("B5_Ar");
116  G4Material* argonGas = G4Material::GetMaterial("G4_Ar");
117  G4Material* scintillator
118  = G4Material::GetMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
119  G4Material* csI = G4Material::GetMaterial("G4_CESIUM_IODIDE");
120  G4Material* lead = G4Material::GetMaterial("G4_Pb");
121 
122  // Option to switch on/off checking of volumes overlaps
123  //
124  G4bool checkOverlaps = true;
125 
126  // geometries --------------------------------------------------------------
127  // experimental hall (world volume)
128  G4VSolid* worldSolid
129  = new G4Box("worldBox",10.*m,3.*m,10.*m);
130  G4LogicalVolume* worldLogical
131  = new G4LogicalVolume(worldSolid,air,"worldLogical");
132  G4VPhysicalVolume* worldPhysical
133  = new G4PVPlacement(0,G4ThreeVector(),worldLogical,"worldPhysical",0,
134  false,0,checkOverlaps);
135 
136  // Tube with Local Magnetic field
137 
138  G4VSolid* magneticSolid
139  = new G4Tubs("magneticTubs",0.,1.*m,1.*m,0.,360.*deg);
140 
142  = new G4LogicalVolume(magneticSolid, air, "magneticLogical");
143 
144  // placement of Tube
145 
146  G4RotationMatrix* fieldRot = new G4RotationMatrix();
147  fieldRot->rotateX(90.*deg);
149  "magneticPhysical",worldLogical,
150  false,0,checkOverlaps);
151 
152  // set step limit in tube with magnetic field
153  G4UserLimits* userLimits = new G4UserLimits(1*m);
154  fMagneticLogical->SetUserLimits(userLimits);
155 
156  // first arm
157  G4VSolid* firstArmSolid
158  = new G4Box("firstArmBox",1.5*m,1.*m,3.*m);
159  G4LogicalVolume* firstArmLogical
160  = new G4LogicalVolume(firstArmSolid,air,"firstArmLogical");
161  new G4PVPlacement(0,G4ThreeVector(0.,0.,-5.*m),firstArmLogical,
162  "firstArmPhysical",worldLogical,
163  false,0,checkOverlaps);
164 
165  // second arm
166  G4VSolid* secondArmSolid
167  = new G4Box("secondArmBox",2.*m,2.*m,3.5*m);
168  G4LogicalVolume* secondArmLogical
169  = new G4LogicalVolume(secondArmSolid,air,"secondArmLogical");
170  G4double x = -5.*m * std::sin(fArmAngle);
171  G4double z = 5.*m * std::cos(fArmAngle);
173  = new G4PVPlacement(fArmRotation,G4ThreeVector(x,0.,z),secondArmLogical,
174  "fSecondArmPhys",worldLogical,
175  false,0,checkOverlaps);
176 
177  // hodoscopes in first arm
178  G4VSolid* hodoscope1Solid
179  = new G4Box("hodoscope1Box",5.*cm,20.*cm,0.5*cm);
181  = new G4LogicalVolume(hodoscope1Solid,scintillator,"hodoscope1Logical");
182  for (G4int i=0;i<15;i++)
183  {
184  G4double x1 = (i-7)*10.*cm;
186  "hodoscope1Physical",firstArmLogical,
187  false,i,checkOverlaps);
188  }
189 
190  // drift chambers in first arm
191  G4VSolid* chamber1Solid
192  = new G4Box("chamber1Box",1.*m,30.*cm,1.*cm);
193  G4LogicalVolume* chamber1Logical
194  = new G4LogicalVolume(chamber1Solid,argonGas,"chamber1Logical");
195  for (G4int i=0;i<5;i++)
196  {
197  G4double z1 = (i-2)*0.5*m;
198  new G4PVPlacement(0,G4ThreeVector(0.,0.,z1),chamber1Logical,
199  "chamber1Physical",firstArmLogical,
200  false,i,checkOverlaps);
201  }
202 
203  // "virtual" wire plane
204  G4VSolid* wirePlane1Solid
205  = new G4Box("wirePlane1Box",1.*m,30.*cm,0.1*mm);
207  = new G4LogicalVolume(wirePlane1Solid,argonGas,"wirePlane1Logical");
209  "wirePlane1Physical",chamber1Logical,
210  false,0,checkOverlaps);
211 
212  // hodoscopes in second arm
213  G4VSolid* hodoscope2Solid
214  = new G4Box("hodoscope2Box",5.*cm,20.*cm,0.5*cm);
216  = new G4LogicalVolume(hodoscope2Solid,scintillator,"hodoscope2Logical");
217  for (G4int i=0;i<25;i++)
218  {
219  G4double x2 = (i-12)*10.*cm;
221  "hodoscope2Physical",secondArmLogical,
222  false,i,checkOverlaps);
223  }
224 
225  // drift chambers in second arm
226  G4VSolid* chamber2Solid
227  = new G4Box("chamber2Box",1.5*m,30.*cm,1.*cm);
228  G4LogicalVolume* chamber2Logical
229  = new G4LogicalVolume(chamber2Solid,argonGas,"chamber2Logical");
230  for (G4int i=0;i<5;i++)
231  {
232  G4double z2 = (i-2)*0.5*m - 1.5*m;
233  new G4PVPlacement(0,G4ThreeVector(0.,0.,z2),chamber2Logical,
234  "chamber2Physical",secondArmLogical,
235  false,i,checkOverlaps);
236  }
237 
238  // "virtual" wire plane
239  G4VSolid* wirePlane2Solid
240  = new G4Box("wirePlane2Box",1.5*m,30.*cm,0.1*mm);
242  = new G4LogicalVolume(wirePlane2Solid,argonGas,"wirePlane2Logical");
244  "wirePlane2Physical",chamber2Logical,
245  false,0,checkOverlaps);
246 
247  // CsI calorimeter
248  G4VSolid* emCalorimeterSolid
249  = new G4Box("EMcalorimeterBox",1.5*m,30.*cm,15.*cm);
250  G4LogicalVolume* emCalorimeterLogical
251  = new G4LogicalVolume(emCalorimeterSolid,csI,"EMcalorimeterLogical");
252  new G4PVPlacement(0,G4ThreeVector(0.,0.,2.*m),emCalorimeterLogical,
253  "EMcalorimeterPhysical",secondArmLogical,
254  false,0,checkOverlaps);
255 
256  // EMcalorimeter cells
257  G4VSolid* cellSolid
258  = new G4Box("cellBox",7.5*cm,7.5*cm,15.*cm);
260  = new G4LogicalVolume(cellSolid,csI,"cellLogical");
262  new G4PVParameterised("cellPhysical",fCellLogical,emCalorimeterLogical,
263  kXAxis,80,cellParam);
264 
265  // hadron calorimeter
266  G4VSolid* hadCalorimeterSolid
267  = new G4Box("HadCalorimeterBox",1.5*m,30.*cm,50.*cm);
268  G4LogicalVolume* hadCalorimeterLogical
269  = new G4LogicalVolume(hadCalorimeterSolid,lead,"HadCalorimeterLogical");
270  new G4PVPlacement(0,G4ThreeVector(0.,0.,3.*m),hadCalorimeterLogical,
271  "HadCalorimeterPhysical",secondArmLogical,
272  false,0,checkOverlaps);
273 
274  // hadron calorimeter column
275  G4VSolid* HadCalColumnSolid
276  = new G4Box("HadCalColumnBox",15.*cm,30.*cm,50.*cm);
277  G4LogicalVolume* HadCalColumnLogical
278  = new G4LogicalVolume(HadCalColumnSolid,lead,"HadCalColumnLogical");
279  new G4PVReplica("HadCalColumnPhysical",HadCalColumnLogical,
280  hadCalorimeterLogical,kXAxis,10,30.*cm);
281 
282  // hadron calorimeter cell
283  G4VSolid* HadCalCellSolid
284  = new G4Box("HadCalCellBox",15.*cm,15.*cm,50.*cm);
285  G4LogicalVolume* HadCalCellLogical
286  = new G4LogicalVolume(HadCalCellSolid,lead,"HadCalCellLogical");
287  new G4PVReplica("HadCalCellPhysical",HadCalCellLogical,
288  HadCalColumnLogical,kYAxis,2,30.*cm);
289 
290  // hadron calorimeter layers
291  G4VSolid* HadCalLayerSolid
292  = new G4Box("HadCalLayerBox",15.*cm,15.*cm,2.5*cm);
293  G4LogicalVolume* HadCalLayerLogical
294  = new G4LogicalVolume(HadCalLayerSolid,lead,"HadCalLayerLogical");
295  new G4PVReplica("HadCalLayerPhysical",HadCalLayerLogical,
296  HadCalCellLogical,kZAxis,20,5.*cm);
297 
298  // scintillator plates
299  G4VSolid* HadCalScintiSolid
300  = new G4Box("HadCalScintiBox",15.*cm,15.*cm,0.5*cm);
302  = new G4LogicalVolume(HadCalScintiSolid,scintillator,
303  "HadCalScintiLogical");
305  "HadCalScintiPhysical",HadCalLayerLogical,
306  false,0,checkOverlaps);
307 
308  // visualization attributes ------------------------------------------------
309 
310  G4VisAttributes* visAttributes = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
311  visAttributes->SetVisibility(false);
312  worldLogical->SetVisAttributes(visAttributes);
313  fVisAttributes.push_back(visAttributes);
314 
315  visAttributes = new G4VisAttributes(G4Colour(0.9,0.9,0.9)); // LightGray
316  fMagneticLogical->SetVisAttributes(visAttributes);
317  fVisAttributes.push_back(visAttributes);
318 
319  visAttributes = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
320  visAttributes->SetVisibility(false);
321  firstArmLogical->SetVisAttributes(visAttributes);
322  secondArmLogical->SetVisAttributes(visAttributes);
323  fVisAttributes.push_back(visAttributes);
324 
325  visAttributes = new G4VisAttributes(G4Colour(0.8888,0.0,0.0));
326  fHodoscope1Logical->SetVisAttributes(visAttributes);
327  fHodoscope2Logical->SetVisAttributes(visAttributes);
328  fVisAttributes.push_back(visAttributes);
329 
330  visAttributes = new G4VisAttributes(G4Colour(0.0,1.0,0.0));
331  chamber1Logical->SetVisAttributes(visAttributes);
332  chamber2Logical->SetVisAttributes(visAttributes);
333  fVisAttributes.push_back(visAttributes);
334 
335  visAttributes = new G4VisAttributes(G4Colour(0.0,0.8888,0.0));
336  visAttributes->SetVisibility(false);
337  fWirePlane1Logical->SetVisAttributes(visAttributes);
338  fWirePlane2Logical->SetVisAttributes(visAttributes);
339  fVisAttributes.push_back(visAttributes);
340 
341  visAttributes = new G4VisAttributes(G4Colour(0.8888,0.8888,0.0));
342  visAttributes->SetVisibility(false);
343  emCalorimeterLogical->SetVisAttributes(visAttributes);
344  fVisAttributes.push_back(visAttributes);
345 
346  visAttributes = new G4VisAttributes(G4Colour(0.9,0.9,0.0));
347  fCellLogical->SetVisAttributes(visAttributes);
348  fVisAttributes.push_back(visAttributes);
349 
350  visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
351  hadCalorimeterLogical->SetVisAttributes(visAttributes);
352  fVisAttributes.push_back(visAttributes);
353 
354  visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
355  visAttributes->SetVisibility(false);
356  HadCalColumnLogical->SetVisAttributes(visAttributes);
357  HadCalCellLogical->SetVisAttributes(visAttributes);
358  HadCalLayerLogical->SetVisAttributes(visAttributes);
359  fHadCalScintiLogical->SetVisAttributes(visAttributes);
360  fVisAttributes.push_back(visAttributes);
361 
362  // return the world physical volume ----------------------------------------
363 
364  return worldPhysical;
365 }
366 
367 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
368 
370 {
371  // sensitive detectors -----------------------------------------------------
373  G4String SDname;
374 
375  G4VSensitiveDetector* hodoscope1
376  = new B5HodoscopeSD(SDname="/hodoscope1");
377  SDman->AddNewDetector(hodoscope1);
379 
380  G4VSensitiveDetector* hodoscope2
381  = new B5HodoscopeSD(SDname="/hodoscope2");
382  SDman->AddNewDetector(hodoscope2);
384 
385  G4VSensitiveDetector* chamber1
386  = new B5DriftChamberSD(SDname="/chamber1");
387  SDman->AddNewDetector(chamber1);
389 
390  G4VSensitiveDetector* chamber2
391  = new B5DriftChamberSD(SDname="/chamber2");
392  SDman->AddNewDetector(chamber2);
394 
395  G4VSensitiveDetector* emCalorimeter
396  = new B5EmCalorimeterSD(SDname="/EMcalorimeter");
397  SDman->AddNewDetector(emCalorimeter);
398  fCellLogical->SetSensitiveDetector(emCalorimeter);
399 
400  G4VSensitiveDetector* hadCalorimeter
401  = new B5HadCalorimeterSD(SDname="/HadCalorimeter");
402  SDman->AddNewDetector(hadCalorimeter);
404 
405  // magnetic field ----------------------------------------------------------
407  fFieldMgr = new G4FieldManager();
410  G4bool forceToAllDaughters = true;
411  fMagneticLogical->SetFieldManager(fFieldMgr, forceToAllDaughters);
412 
413  // Register the field and its manager for deleting
416 }
417 
418 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
419 
421 {
422  G4NistManager* nistManager = G4NistManager::Instance();
423 
424  // Air
425  nistManager->FindOrBuildMaterial("G4_AIR");
426 
427  // Argon gas
428  nistManager->FindOrBuildMaterial("G4_Ar");
429  // With a density different from the one defined in NIST
430  // G4double density = 1.782e-03*g/cm3;
431  // nistManager->BuildMaterialWithNewDensity("B5_Ar","G4_Ar",density);
432  // !! cases segmentation fault
433 
434  // Scintillator
435  // (PolyVinylToluene, C_9H_10)
436  nistManager->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
437 
438  // CsI
439  nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
440 
441  // Lead
442  nistManager->FindOrBuildMaterial("G4_Pb");
443 
444  // Vacuum "Galactic"
445  // nistManager->FindOrBuildMaterial("G4_Galactic");
446 
447  // Vacuum "Air with low density"
448  // G4Material* air = G4Material::GetMaterial("G4_AIR");
449  // G4double density = 1.0e-5*air->GetDensity();
450  // nistManager
451  // ->BuildMaterialWithNewDensity("Air_lowDensity", "G4_AIR", density);
452 
453  G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
454  G4cout << *(G4Material::GetMaterialTable()) << G4endl;
455 }
456 
457 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
458 
460 {
461  if (!fSecondArmPhys)
462  {
463  G4cerr << "Detector has not yet been constructed." << G4endl;
464  return;
465  }
466 
467  fArmAngle = val;
468  *fArmRotation = G4RotationMatrix(); // make it unit vector
469  fArmRotation->rotateY(fArmAngle);
470  G4double x = -5.*m * std::sin(fArmAngle);
471  G4double z = 5.*m * std::cos(fArmAngle);
473 
474  // tell G4RunManager that we change the geometry
476 }
477 
478 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
479 
481 {
482  // Define /B5/detector command directory using generic messenger class
483  fMessenger = new G4GenericMessenger(this,
484  "/B5/detector/",
485  "Detector control");
486 
487  // armAngle command
488  G4GenericMessenger::Command& armAngleCmd
489  = fMessenger->DeclareMethodWithUnit("armAngle","deg",
491  "Set rotation angle of the second arm.");
492  armAngleCmd.SetParameterName("angle", true);
493  armAngleCmd.SetRange("angle>=0. && angle<180.");
494  armAngleCmd.SetDefaultValue("30.");
495 }
496 
497 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void GeometryHasBeenModified(G4bool prop=true)
static const double cm
Definition: G4SIunits.hh:106
Definition of the B5HadCalorimeterSD class.
G4GenericMessenger * fMessenger
Definition of the B5CellParameterisation class.
G4Material * FindOrBuildMaterial(const G4String &name, G4bool isotopes=true, G4bool warning=false)
Definition of the B5DetectorConstruction class.
Definition of the B5DriftChamberSD class.
CLHEP::Hep3Vector G4ThreeVector
G4LogicalVolume * fWirePlane2Logical
CLHEP::HepRotation G4RotationMatrix
G4bool SetDetectorField(G4Field *detectorField)
This class is generic messenger.
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:603
G4double z
Definition: TRTMaterials.hh:39
Definition: G4Box.hh:64
G4LogicalVolume * fHodoscope1Logical
void SetVisibility(G4bool)
void SetUserLimits(G4UserLimits *pULimits)
Definition: G4Tubs.hh:85
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:588
Drift chamber sensitive detector.
Definition of the B5EmCalorimeterSD class.
G4LogicalVolume * fMagneticLogical
Command & DeclareMethodWithUnit(const G4String &name, const G4String &defaultUnit, const G4AnyMethod &fun, const G4String &doc="")
G4VPhysicalVolume * fSecondArmPhys
#define G4ThreadLocal
Definition: tls.hh:84
int G4int
Definition: G4Types.hh:78
static G4NistManager * Instance()
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
Command & SetDefaultValue(const G4String &)
void Register(T *inst)
Definition: G4AutoDelete.hh:65
virtual G4VPhysicalVolume * Construct()
G4GLOB_DLL std::ostream G4cout
static const double deg
Definition: G4SIunits.hh:133
bool G4bool
Definition: G4Types.hh:79
G4LogicalVolume * fHadCalScintiLogical
EM Calorimeter cell parameterisation.
static G4ThreadLocal B5MagneticField * fMagneticField
Magnetic field.
void SetTranslation(const G4ThreeVector &v)
G4RotationMatrix * fArmRotation
static G4ThreadLocal G4FieldManager * fFieldMgr
Command & SetRange(const G4String &range)
G4LogicalVolume * fWirePlane1Logical
void AddNewDetector(G4VSensitiveDetector *aSD)
Definition: G4SDManager.cc:67
static G4RunManager * GetRunManager()
Definition: G4RunManager.cc:79
Definition of the B5MagneticField class.
Definition of the B5HodoscopeSD class.
G4LogicalVolume * fHodoscope2Logical
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
Hodoscope sensitive detector.
Command & SetParameterName(const G4String &, G4bool, G4bool=false)
#define G4endl
Definition: G4ios.hh:61
static const double m
Definition: G4SIunits.hh:110
double G4double
Definition: G4Types.hh:76
void CreateChordFinder(G4MagneticField *detectorMagField)
EM calorimeter sensitive detector.
static const double mm
Definition: G4SIunits.hh:102
void SetVisAttributes(const G4VisAttributes *pVA)
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
Hadron calorimeter sensitive detector.
G4GLOB_DLL std::ostream G4cerr
std::vector< G4VisAttributes * > fVisAttributes