source: trunk/examples/extended/analysis/A01/src/A01DetectorConstruction.cc @ 1288

Last change on this file since 1288 was 807, checked in by garnier, 16 years ago

update

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