Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
A01DetectorConstruction.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 //
28 //
29 // $Id$
30 // --------------------------------------------------------------
31 //
32 
34 
35 #include "G4FieldManager.hh"
37 #include "G4Mag_UsualEqRhs.hh"
38 
39 #include "G4Material.hh"
40 #include "G4Element.hh"
41 #include "G4MaterialTable.hh"
42 #include "G4NistManager.hh"
43 
44 #include "G4VSolid.hh"
45 #include "G4Box.hh"
46 #include "G4Tubs.hh"
47 #include "G4LogicalVolume.hh"
48 #include "G4VPhysicalVolume.hh"
49 #include "G4PVPlacement.hh"
50 #include "G4PVParameterised.hh"
51 #include "G4UserLimits.hh"
52 
53 #include "G4SDManager.hh"
54 #include "G4VSensitiveDetector.hh"
55 #include "G4RunManager.hh"
56 
57 #include "G4VisAttributes.hh"
58 #include "G4Colour.hh"
59 
60 #include "G4ios.hh"
61 #include "G4SystemOfUnits.hh"
62 
64 #include "A01MagneticField.hh"
66 #include "A01Hodoscope.hh"
67 #include "A01DriftChamber.hh"
68 #include "A01EmCalorimeter.hh"
69 
70 #include "G4PVReplica.hh"
71 #include "A01HadCalorimeter.hh"
72 
74  : fAir(0), fArgonGas(0), fScintillator(0), fCsI(0), fLead(0),
75  fWorldVisAtt(0), fMagneticVisAtt(0),
76  fArmVisAtt(0), fHodoscopeVisAtt(0), fChamberVisAtt(0),
77  fWirePlaneVisAtt(0), fEMcalorimeterVisAtt(0), fCellVisAtt(0),
78  fHadCalorimeterVisAtt(0), fHadCalorimeterCellVisAtt(0),
79  fArmAngle(30.*deg), fSecondArmPhys(0)
80 
81 {
82  fMessenger = new A01DetectorConstMessenger(this);
83  fMagneticField = new A01MagneticField();
84  fFieldMgr = new G4FieldManager();
85  fArmRotation = new G4RotationMatrix();
86  fArmRotation->rotateY(fArmAngle);
87 }
88 
90 {
91  delete fArmRotation;
92  delete fMagneticField;
93  delete fFieldMgr;
94  delete fMessenger;
95 
97 
98  delete fWorldVisAtt;
99  delete fMagneticVisAtt;
100  delete fArmVisAtt;
101  delete fHodoscopeVisAtt;
102  delete fChamberVisAtt;
103  delete fWirePlaneVisAtt;
104  delete fEMcalorimeterVisAtt;
105  delete fCellVisAtt;
106  delete fHadCalorimeterVisAtt;
107  delete fHadCalorimeterCellVisAtt;
108 }
109 
111 {
112  // All managed (deleted) by SDManager
113  G4VSensitiveDetector* hodoscope1;
114  G4VSensitiveDetector* hodoscope2;
115  G4VSensitiveDetector* chamber1;
116  G4VSensitiveDetector* chamber2;
117  G4VSensitiveDetector* EMcalorimeter;
118  G4VSensitiveDetector* HadCalorimeter;
120 
121  // Local Magnetic Field
122  static G4bool fieldIsInitialized = false;
123 
124  if(!fieldIsInitialized)
125  {
126  fFieldMgr->SetDetectorField(fMagneticField);
127  fFieldMgr->CreateChordFinder(fMagneticField);
128  fieldIsInitialized = true;
129  }
130 
131  // geometries --------------------------------------------------------------
132  // experimental hall (world volume)
133  G4VSolid* worldSolid = new G4Box("worldBox",10.*m,3.*m,10.*m);
134  G4LogicalVolume* worldLogical
135  = new G4LogicalVolume(worldSolid,fAir,"worldLogical",0,0,0);
136  G4VPhysicalVolume* worldPhysical
137  = new G4PVPlacement(0,G4ThreeVector(),worldLogical,"worldPhysical",0,0,0);
138 
139  // Tube with Local Magnetic field
140 
141  G4VSolid* magneticSolid = new G4Tubs("magneticTubs",0.,1.*m,1.*m,0.,360.*deg);
143  G4Material* G4_Galactic = man->FindOrBuildMaterial("G4_Galactic");
144 
145  G4LogicalVolume* magneticLogical
146  = new G4LogicalVolume(magneticSolid,G4_Galactic,"magneticLogical",fFieldMgr,0,0);
147 
148  // placement of Tube
149 
150  G4RotationMatrix* fieldRot = new G4RotationMatrix();
151  fieldRot->rotateX(90.*deg);
152  new G4PVPlacement(fieldRot,G4ThreeVector(),magneticLogical,
153  "magneticPhysical",worldLogical,0,0);
154 
155  // set "user limits" for drawing smooth curve
156  G4UserLimits* userLimits = new G4UserLimits(5.0*cm);
157  magneticLogical->SetUserLimits(userLimits);
158 
159  // first arm
160  G4VSolid* firstArmSolid = new G4Box("firstArmBox",1.5*m,1.*m,3.*m);
161  G4LogicalVolume* firstArmLogical
162  = new G4LogicalVolume(firstArmSolid,fAir,"firstArmLogical",0,0,0);
163  new G4PVPlacement(0,G4ThreeVector(0.,0.,-5.*m),firstArmLogical,
164  "firstArmPhysical",worldLogical,0,0);
165 
166  // second arm
167  G4VSolid* secondArmSolid = new G4Box("secondArmBox",2.*m,2.*m,3.5*m);
168  G4LogicalVolume* secondArmLogical
169  = new G4LogicalVolume(secondArmSolid,fAir,"secondArmLogical",0,0,0);
170  G4double x = -5.*m * std::sin(fArmAngle);
171  G4double z = 5.*m * std::cos(fArmAngle);
172  fSecondArmPhys
173  = new G4PVPlacement(fArmRotation,G4ThreeVector(x,0.,z),secondArmLogical,
174  "fSecondArmPhys",worldLogical,0,0);
175 
176  // hodoscopes in first arm
177  G4VSolid* hodoscope1Solid = new G4Box("hodoscope1Box",5.*cm,20.*cm,0.5*cm);
178  G4LogicalVolume* hodoscope1Logical
179  = new G4LogicalVolume(hodoscope1Solid,fScintillator,"hodoscope1Logical",0,0,0);
180  for(int i1=0;i1<15;i1++)
181  {
182  G4double x1 = (i1-7)*10.*cm;
183  new G4PVPlacement(0,G4ThreeVector(x1,0.,-1.5*m),hodoscope1Logical,
184  "hodoscope1Physical",firstArmLogical,0,i1);
185  }
186 
187  // drift chambers in first arm
188  G4VSolid* chamber1Solid = new G4Box("chamber1Box",1.*m,30.*cm,1.*cm);
189  G4LogicalVolume* chamber1Logical
190  = new G4LogicalVolume(chamber1Solid,fArgonGas,"chamber1Logical",0,0,0);
191  for(int j1=0;j1<5;j1++)
192  {
193  G4double z1 = (j1-2)*0.5*m;
194  new G4PVPlacement(0,G4ThreeVector(0.,0.,z1),chamber1Logical,
195  "chamber1Physical",firstArmLogical,0,j1);
196  }
197 
198  // "virtual" wire plane
199  G4VSolid* wirePlane1Solid = new G4Box("wirePlane1Box",1.*m,30.*cm,0.1*mm);
200  G4LogicalVolume* wirePlane1Logical
201  = new G4LogicalVolume(wirePlane1Solid,fArgonGas,"wirePlane1Logical",0,0,0);
202  new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),wirePlane1Logical,
203  "wirePlane1Physical",chamber1Logical,0,0);
204 
205  // hodoscopes in second arm
206  G4VSolid* hodoscope2Solid = new G4Box("hodoscope2Box",5.*cm,20.*cm,0.5*cm);
207  G4LogicalVolume* hodoscope2Logical
208  = new G4LogicalVolume(hodoscope2Solid,fScintillator,"hodoscope2Logical",0,0,0);
209  for(int i2=0;i2<25;i2++)
210  {
211  G4double x2 = (i2-12)*10.*cm;
212  new G4PVPlacement(0,G4ThreeVector(x2,0.,0.),hodoscope2Logical,
213  "hodoscope2Physical",secondArmLogical,0,i2);
214  }
215 
216  // drift chambers in second arm
217  G4VSolid* chamber2Solid = new G4Box("chamber2Box",1.5*m,30.*cm,1.*cm);
218  G4LogicalVolume* chamber2Logical
219  = new G4LogicalVolume(chamber2Solid,fArgonGas,"chamber2Logical",0,0,0);
220  for(int j2=0;j2<5;j2++)
221  {
222  G4double z2 = (j2-2)*0.5*m - 1.5*m;
223  new G4PVPlacement(0,G4ThreeVector(0.,0.,z2),chamber2Logical,
224  "chamber2Physical",secondArmLogical,0,j2);
225  }
226 
227  // "virtual" wire plane
228  G4VSolid* wirePlane2Solid = new G4Box("wirePlane2Box",1.5*m,30.*cm,0.1*mm);
229  G4LogicalVolume* wirePlane2Logical
230  = new G4LogicalVolume(wirePlane2Solid,fArgonGas,"wirePlane2Logical",0,0,0);
231  new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),wirePlane2Logical,
232  "wirePlane2Physical",chamber2Logical,0,0);
233 
234  // CsI calorimeter
235  G4VSolid* EMcalorimeterSolid = new G4Box("EMcalorimeterBox",1.5*m,30.*cm,15.*cm);
236  G4LogicalVolume* EMcalorimeterLogical
237  = new G4LogicalVolume(EMcalorimeterSolid,fCsI,"EMcalorimeterLogical",0,0,0);
238  new G4PVPlacement(0,G4ThreeVector(0.,0.,2.*m),EMcalorimeterLogical,
239  "EMcalorimeterPhysical",secondArmLogical,0,0);
240 
241  // EMcalorimeter cells
242  G4VSolid* cellSolid = new G4Box("cellBox",7.5*cm,7.5*cm,15.*cm);
243  G4LogicalVolume* cellLogical
244  = new G4LogicalVolume(cellSolid,fCsI,"cellLogical",0,0,0);
246  new G4PVParameterised("cellPhysical",cellLogical,EMcalorimeterLogical,
247  kXAxis,80,cellParam);
248 
249  // hadron calorimeter
250  G4VSolid* HadCalorimeterSolid
251  = new G4Box("HadCalorimeterBox",1.5*m,30.*cm,50.*cm);
252  G4LogicalVolume* HadCalorimeterLogical
253  = new G4LogicalVolume(HadCalorimeterSolid,fLead,"HadCalorimeterLogical",0,0,0);
254  new G4PVPlacement(0,G4ThreeVector(0.,0.,3.*m),HadCalorimeterLogical,
255  "HadCalorimeterPhysical",secondArmLogical,0,0);
256 
257  // hadron calorimeter column
258  G4VSolid* HadCalColumnSolid
259  = new G4Box("HadCalColumnBox",15.*cm,30.*cm,50.*cm);
260  G4LogicalVolume* HadCalColumnLogical
261  = new G4LogicalVolume(HadCalColumnSolid,fLead,"HadCalColumnLogical",0,0,0);
262  new G4PVReplica("HadCalColumnPhysical",HadCalColumnLogical,
263  HadCalorimeterLogical,kXAxis,10,30.*cm);
264 
265  // hadron calorimeter cell
266  G4VSolid* HadCalCellSolid
267  = new G4Box("HadCalCellBox",15.*cm,15.*cm,50.*cm);
268  G4LogicalVolume* HadCalCellLogical
269  = new G4LogicalVolume(HadCalCellSolid,fLead,"HadCalCellLogical",0,0,0);
270  new G4PVReplica("HadCalCellPhysical",HadCalCellLogical,
271  HadCalColumnLogical,kYAxis,2,30.*cm);
272 
273  // hadron calorimeter layers
274  G4VSolid* HadCalLayerSolid
275  = new G4Box("HadCalLayerBox",15.*cm,15.*cm,2.5*cm);
276  G4LogicalVolume* HadCalLayerLogical
277  = new G4LogicalVolume(HadCalLayerSolid,fLead,"HadCalLayerLogical",0,0,0);
278  new G4PVReplica("HadCalLayerPhysical",HadCalLayerLogical,
279  HadCalCellLogical,kZAxis,20,5.*cm);
280 
281  // scintillator plates
282  G4VSolid* HadCalScintiSolid
283  = new G4Box("HadCalScintiBox",15.*cm,15.*cm,0.5*cm);
284  G4LogicalVolume* HadCalScintiLogical
285  = new G4LogicalVolume(HadCalScintiSolid,fScintillator,"HadCalScintiLogical",0,0,0);
286  new G4PVPlacement(0,G4ThreeVector(0.,0.,2.*cm),HadCalScintiLogical,
287  "HadCalScintiPhysical",HadCalLayerLogical,0,0);
288 
289  // sensitive detectors -----------------------------------------------------
291  G4String SDname;
292 
293  hodoscope1 = new A01Hodoscope(SDname="/hodoscope1");
294  SDman->AddNewDetector(hodoscope1);
295  hodoscope1Logical->SetSensitiveDetector(hodoscope1);
296  hodoscope2 = new A01Hodoscope(SDname="/hodoscope2");
297  SDman->AddNewDetector(hodoscope2);
298  hodoscope2Logical->SetSensitiveDetector(hodoscope2);
299 
300  chamber1 = new A01DriftChamber(SDname="/chamber1");
301  SDman->AddNewDetector(chamber1);
302  wirePlane1Logical->SetSensitiveDetector(chamber1);
303  chamber2 = new A01DriftChamber(SDname="/chamber2");
304  SDman->AddNewDetector(chamber2);
305  wirePlane2Logical->SetSensitiveDetector(chamber2);
306 
307  EMcalorimeter = new A01EmCalorimeter(SDname="/EMcalorimeter");
308  SDman->AddNewDetector(EMcalorimeter);
309  cellLogical->SetSensitiveDetector(EMcalorimeter);
310 
311  HadCalorimeter = new A01HadCalorimeter(SDname="/HadCalorimeter");
312  SDman->AddNewDetector(HadCalorimeter);
313  HadCalScintiLogical->SetSensitiveDetector(HadCalorimeter);
314 
315  // visualization attributes ------------------------------------------------
316 
317  fWorldVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
318  fWorldVisAtt->SetVisibility(false);
319  worldLogical->SetVisAttributes(fWorldVisAtt);
320 
321  fMagneticVisAtt = new G4VisAttributes(G4Colour(0.9,0.9,0.9)); // LightGray
322  magneticLogical->SetVisAttributes(fMagneticVisAtt);
323 
324  fArmVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
325  fArmVisAtt->SetVisibility(false);
326  firstArmLogical->SetVisAttributes(fArmVisAtt);
327  secondArmLogical->SetVisAttributes(fArmVisAtt);
328 
329  fHodoscopeVisAtt = new G4VisAttributes(G4Colour(0.8888,0.0,0.0));
330  hodoscope1Logical->SetVisAttributes(fHodoscopeVisAtt);
331  hodoscope2Logical->SetVisAttributes(fHodoscopeVisAtt);
332 
333  fChamberVisAtt = new G4VisAttributes(G4Colour(0.0,1.0,0.0));
334  chamber1Logical->SetVisAttributes(fChamberVisAtt);
335  chamber2Logical->SetVisAttributes(fChamberVisAtt);
336 
337  fWirePlaneVisAtt = new G4VisAttributes(G4Colour(0.0,0.8888,0.0));
338  fWirePlaneVisAtt->SetVisibility(false);
339  wirePlane1Logical->SetVisAttributes(fWirePlaneVisAtt);
340  wirePlane2Logical->SetVisAttributes(fWirePlaneVisAtt);
341 
342  fEMcalorimeterVisAtt = new G4VisAttributes(G4Colour(0.8888,0.8888,0.0));
343  fEMcalorimeterVisAtt->SetVisibility(false);
344  EMcalorimeterLogical->SetVisAttributes(fEMcalorimeterVisAtt);
345 
346  fCellVisAtt = new G4VisAttributes(G4Colour(0.9,0.9,0.0));
347  cellLogical->SetVisAttributes(fCellVisAtt);
348 
349  fHadCalorimeterVisAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
350  HadCalorimeterLogical->SetVisAttributes(fHadCalorimeterVisAtt);
351  fHadCalorimeterCellVisAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
352  fHadCalorimeterCellVisAtt->SetVisibility(false);
353  HadCalColumnLogical->SetVisAttributes(fHadCalorimeterCellVisAtt);
354  HadCalCellLogical->SetVisAttributes(fHadCalorimeterCellVisAtt);
355  HadCalLayerLogical->SetVisAttributes(fHadCalorimeterCellVisAtt);
356  HadCalScintiLogical->SetVisAttributes(fHadCalorimeterCellVisAtt);
357 
358  // return the world physical volume ----------------------------------------
359 
360  G4cout << G4endl << "The geometrical tree defined are : " << G4endl << G4endl;
361  DumpGeometricalTree(worldPhysical);
362 
363  return worldPhysical;
364 }
365 
367 {
368  G4double a;
369  G4double z;
371  G4double weightRatio;
372  G4String name;
374  G4int nElem;
375 
376  // Argon gas
377  a = 39.95*g/mole;
378  density = 1.782e-03*g/cm3;
379  fArgonGas = new G4Material(name="ArgonGas", z=18., a, density);
380 
381  // elements for mixtures and compounds
382  a = 1.01*g/mole;
383  G4Element* elH = new G4Element(name="Hydrogen", symbol="H", z=1., a);
384  a = 12.01*g/mole;
385  G4Element* elC = new G4Element(name="Carbon", symbol="C", z=6., a);
386  a = 14.01*g/mole;
387  G4Element* elN = new G4Element(name="Nitrogen", symbol="N", z=7., a);
388  a = 16.00*g/mole;
389  G4Element* elO = new G4Element(name="Oxigen", symbol="O", z=8., a);
390  a = 126.9*g/mole;
391  G4Element* elI = new G4Element(name="Iodine", symbol="I", z=53., a);
392  a = 132.9*g/mole;
393  G4Element* elCs= new G4Element(name="Cesium", symbol="Cs", z=55., a);
394 
395  // Air
396  density = 1.29*mg/cm3;
397  fAir = new G4Material(name="Air", density, nElem=2);
398  fAir->AddElement(elN, weightRatio=.7);
399  fAir->AddElement(elO, weightRatio=.3);
400 
401  // Scintillator
402  density = 1.032*g/cm3;
403  fScintillator = new G4Material(name="Scintillator", density, nElem=2);
404  fScintillator->AddElement(elC, 9);
405  fScintillator->AddElement(elH, 10);
406 
407  // CsI
408  density = 4.51*g/cm3;
409  fCsI = new G4Material(name="CsI", density, nElem=2);
410  fCsI->AddElement(elI, weightRatio=.5);
411  fCsI->AddElement(elCs,weightRatio=.5);
412 
413  // Lead
414  a = 207.19*g/mole;
415  density = 11.35*g/cm3;
416  fLead = new G4Material(name="Lead", z=82., a, density);
417 
418  G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
419  G4cout << *(G4Material::GetMaterialTable()) << G4endl;
420 }
421 
423 {
424  // Destroy all allocated elements and materials
425  size_t i;
427  for(i=0;i<matTable->size();i++)
428  { delete (*(matTable))[i]; }
429  matTable->clear();
431  for(i=0;i<elemTable->size();i++)
432  { delete (*(elemTable))[i]; }
433  elemTable->clear();
434 }
435 
437 {
438  for(int isp=0;isp<depth;isp++)
439  { G4cout << " "; }
440  G4cout << aVolume->GetName() << "[" << aVolume->GetCopyNo() << "] "
441  << aVolume->GetLogicalVolume()->GetName() << " "
442  << aVolume->GetLogicalVolume()->GetNoDaughters() << " "
443  << aVolume->GetLogicalVolume()->GetMaterial()->GetName();
444  if(aVolume->GetLogicalVolume()->GetSensitiveDetector())
445  {
446  G4cout << " " << aVolume->GetLogicalVolume()->GetSensitiveDetector()
447  ->GetFullPathName();
448  }
449  G4cout << G4endl;
450  for(int i=0;i<aVolume->GetLogicalVolume()->GetNoDaughters();i++)
451  { DumpGeometricalTree(aVolume->GetLogicalVolume()->GetDaughter(i),depth+1); }
452 }
453 
455 {
456  if(!fSecondArmPhys)
457  {
458  G4cerr << "Detector has not yet been constructed." << G4endl;
459  return;
460  }
461 
462  fArmAngle = val;
463  *fArmRotation = G4RotationMatrix(); // make it unit vector
464  fArmRotation->rotateY(fArmAngle);
465  G4double x = -5.*m * std::sin(fArmAngle);
466  G4double z = 5.*m * std::cos(fArmAngle);
467  fSecondArmPhys->SetTranslation(G4ThreeVector(x,0.,z));
468 
469  // tell G4RunManager that we change the geometry
471 }