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

Last change on this file since 812 was 807, checked in by garnier, 17 years ago

update

File size: 17.4 KB
RevLine 
[807]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.