source: trunk/examples/extended/electromagnetic/TestEm9/src/DetectorConstruction.cc

Last change on this file was 1337, checked in by garnier, 14 years ago

tag geant4.9.4 beta 1 + modifs locales

File size: 13.5 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//
[1337]27// $Id: DetectorConstruction.cc,v 1.14 2009/11/21 17:28:16 vnivanch Exp $
28// GEANT4 tag $Name: geant4-09-04-beta-01 $
[807]29//
30//
31/////////////////////////////////////////////////////////////////////////
32//
33// TestEm9: Crystal calorimeter
34//
35// Created: 31.01.03 V.Ivanchenko
36//
37// Modified:
38//
39////////////////////////////////////////////////////////////////////////
40//
41
42
43//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
44//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
45
46#include "DetectorConstruction.hh"
47#include "DetectorMessenger.hh"
48
49#include "G4Box.hh"
50#include "G4LogicalVolume.hh"
51#include "G4PVPlacement.hh"
52#include "G4PVReplica.hh"
53
54#include "G4TransportationManager.hh"
55
56#include "G4GeometryManager.hh"
57#include "G4RunManager.hh"
58#include "G4Region.hh"
59#include "G4RegionStore.hh"
[1230]60#include "G4ProductionCuts.hh"
[807]61#include "G4PhysicalVolumeStore.hh"
62#include "G4LogicalVolumeStore.hh"
63#include "G4SolidStore.hh"
64#include "G4NistManager.hh"
65
66#include "G4VisAttributes.hh"
67#include "G4Colour.hh"
68
69#include "G4UnitsTable.hh"
70#include "G4ios.hh"
71
72//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
73
74DetectorConstruction::DetectorConstruction()
[1230]75  : G4VUserDetectorConstruction()
[807]76{
77  detectorMessenger = new DetectorMessenger(this);
78
79  ecalLength   = 36.*cm;
80  ecalWidth    = 6.*cm;
81  vertexLength = 3.*cm;
82  padLength    = 0.1*mm;
83  padWidth     = 0.02*mm;
84  absLength    = 2.*mm;
85  vertexRegion = 0;
86  muonRegion   = 0;
[1230]87  logicWorld   = 0;
88  logicCal     = 0;
89  logicA1      = 0;
[807]90  DefineMaterials();
[1230]91  vertexDetectorCuts = new G4ProductionCuts();
92  muonDetectorCuts   = new G4ProductionCuts();
[807]93}
94
95//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
96
97DetectorConstruction::~DetectorConstruction()
[1230]98{ 
99  delete detectorMessenger;
100  delete vertexDetectorCuts;
101  delete muonDetectorCuts;
102}
[807]103
104//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
105
106G4VPhysicalVolume* DetectorConstruction::Construct()
107{
108  return ConstructVolumes();
109}
110
111//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
112
113void DetectorConstruction::DefineMaterials()
114{
115  // Default materials
116
117  G4NistManager* man = G4NistManager::Instance();
[1230]118  //  man->SetVerbose(1);
[807]119  worldMaterial = man->FindOrBuildMaterial("G4_AIR");
120  absMaterial   = man->FindOrBuildMaterial("G4_Al");
121  vertMaterial  = man->FindOrBuildMaterial("G4_Si");
122  yorkMaterial  = man->FindOrBuildMaterial("G4_Fe");
123  calMaterial   = man->FindOrBuildMaterial("G4_CESIUM_IODIDE");
124}
125
126//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
127
128G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
129{
130  // Cleanup old geometry
131
132  G4GeometryManager::GetInstance()->OpenGeometry();
133
[1230]134  if(G4NistManager::Instance()->GetVerbose() > 0)
135    G4cout << *(G4Material::GetMaterialTable()) << G4endl;
136
137  if(vertexRegion) {
138    delete vertexRegion;
139    delete muonRegion;
140  }
[807]141  vertexRegion = new G4Region("VertexDetector");
[1230]142  vertexRegion->SetProductionCuts(vertexDetectorCuts);
143
[807]144  muonRegion   = new G4Region("MuonDetector");
[1230]145  muonRegion->SetProductionCuts(muonDetectorCuts);
[807]146
[1230]147  G4SolidStore::GetInstance()->Clean();
148  G4LogicalVolumeStore::GetInstance()->Clean();
149  G4PhysicalVolumeStore::GetInstance()->Clean();
150
[807]151  if(vertexLength < padLength*5.0) vertexLength = padLength*5.0;
152  G4double gap    = 0.01*mm;
153  G4double biggap = 2.*cm;
154  G4double york   = 10.*cm;
155
[1230]156  worldZ = 2.*vertexLength + 3.*absLength + 0.5*(ecalLength + york) + biggap*2.;
157
[807]158  G4double worldX = ecalWidth*3.0;
159  G4double vertexZ= -worldZ + vertexLength*2.0 + absLength     + biggap;
160  G4double absZ2  = -worldZ + vertexLength*4.0 + absLength*3.5 + biggap;
[1230]161  G4double ecalZ  = -worldZ + vertexLength*4.0 + absLength*4.0 + ecalLength*0.5 
162    + 2.*biggap;
[807]163  G4double yorkZ  = -worldZ + vertexLength*4.0 + absLength*5.0 + ecalLength
[1230]164    + york*0.5 + 3.*biggap;
[807]165
166  //
167  // World
168  //
169  G4Box* solidW = new G4Box("World",worldX,worldX,worldZ);
[1230]170  logicWorld = new G4LogicalVolume( solidW,worldMaterial,"World");
[807]171  G4VPhysicalVolume* world = new G4PVPlacement(0,G4ThreeVector(),
[1230]172                                               "World",logicWorld,0,false,0);
[807]173
174  //
175  // Ecal
176  //
177  G4Box* solidE = new G4Box("VolE",worldX,worldX,ecalLength*0.5 + gap);
[1230]178  logicECal = new G4LogicalVolume( solidE,worldMaterial,"VolE");
[807]179  G4VPhysicalVolume* physE = new G4PVPlacement(0,G4ThreeVector(0.,0.,ecalZ),
[1230]180                                               "VolE",logicECal,world,false,0);
[807]181
182  G4Box* solidC = new G4Box("Ecal",ecalWidth*0.5,ecalWidth*0.5,ecalLength*0.5);
[1230]183  logicCal = new G4LogicalVolume( solidC,calMaterial,"Ecal");
[807]184
185  G4cout << "Ecal is " << G4BestUnit(ecalLength,"Length")
[1230]186         << " of " << calMaterial->GetName() << G4endl;
[807]187
188  // Crystals
189
190  G4double x0 = -(ecalWidth + gap)*2.0;
191  G4double y  = x0;
192  G4double x;
193  G4int k = 0;
194  G4VPhysicalVolume* pv;
195  G4int i,j;
196
197  for (i=0; i<5; i++) {
198    x  = x0;
199    for (j=0; j<5; j++) {
200
[1230]201      pv = new G4PVPlacement(0,G4ThreeVector(x,y,0.),"Ecal",logicCal,
[807]202                                    physE,false,k);
203      k++;
204      x += ecalWidth + gap;
205    }
206    y += ecalWidth + gap;
207  }
208
209  //Absorber
210
211  G4Box* solidA = new G4Box("Abso",worldX,worldX,absLength*0.5);
212  logicA2 = new G4LogicalVolume( solidA,absMaterial,"Abs2");
213  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,absZ2),
[1230]214                         "Abs2",logicA2,world,false,0);
[807]215
216  G4cout << "Absorber is " << G4BestUnit(absLength,"Length")
[1230]217         << " of " << absMaterial->GetName() << G4endl;
[807]218
219  //York
220
221  G4Box* solidYV = new G4Box("VolY",worldX,worldX,york*0.5+absLength);
[1230]222  logicYV = new G4LogicalVolume( solidYV,yorkMaterial,"VolY");
[807]223  G4VPhysicalVolume* physYV = new G4PVPlacement(0,G4ThreeVector(0.,0.,yorkZ),
[1230]224                                                "VolY",logicYV,world,false,0);
[807]225
226  G4Box* solidY = new G4Box("York",worldX,worldX,york*0.5);
[1230]227  logicY = new G4LogicalVolume( solidY,yorkMaterial,"York");
[807]228  pv = new G4PVPlacement(0,G4ThreeVector(),
[1230]229                         "York",logicY,physYV,false,0);
[807]230
231  logicA3 = new G4LogicalVolume( solidA,absMaterial,"Abs3");
232  logicA4 = new G4LogicalVolume( solidA,absMaterial,"Abs4");
[1230]233
[807]234  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,-(york+absLength)*0.5),
[1230]235                         "Abs3",logicA3,physYV,false,0);
[807]236  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,(york+absLength)*0.5),
[1230]237                         "Abs4",logicA4,physYV,false,0);
[807]238
239  //Vertex volume
240  G4Box* solidVV = new G4Box("VolV",worldX,worldX,vertexLength*2.+absLength+gap);
[1230]241  logicVV = new G4LogicalVolume( solidVV,worldMaterial,"VolV");
[807]242  G4VPhysicalVolume* physVV = new G4PVPlacement(0,G4ThreeVector(0.,0.,vertexZ),
[1230]243                                                "VolV",logicVV,world,false,0);
[807]244
245  //Absorber
246  logicA1 = new G4LogicalVolume( solidA,absMaterial,"Abs1");
247  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,vertexLength*2.-absLength*0.5),
[1230]248                         "Abs1",logicA1,physVV,false,0);
[807]249
250  //Vertex
251  G4double vertWidth = ecalWidth/5.;
252  G4int npads = (G4int)(vertWidth/padWidth);
[1337]253  //G4cout << " vertWidth= " << vertWidth << " padWidth= " << padWidth
254  //     << " npads= " << npads << G4endl;
255  // insure beam to hit a middle of central pad
[807]256  npads = (npads/2)*2 + 1;
[1337]257  x0 = -0.5*(padWidth + vertWidth);
258  G4double x1 = 0.5*vertWidth + gap; 
[807]259  G4double z  = -(vertexLength+absLength);
260
261  G4Box* solidVD = new G4Box("VertDet",x1,ecalWidth*0.5+gap,padLength*0.5);
[1230]262  logicVD = new G4LogicalVolume( solidVD,vertMaterial,"VertDet");
263  logicVD->SetSolid(solidVD);
[807]264
265  G4Box* solidV = new G4Box("Vert",padWidth*0.5,ecalWidth*0.5,padLength*0.5);
[1230]266  logicV = new G4LogicalVolume( solidV,vertMaterial,"Vert");
[807]267
268  for (i=0; i<3; i++) {
269    pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,z),"VertDet",logicVD,
270                                    physVV,false,i);
271    z += vertexLength;
272  }
273  x = x0;
274
275  for (j=0; j<npads; j++) {
276
277    pv = new G4PVPlacement(0,G4ThreeVector(x,0.,0.),logicV,"Vert",logicVD,
278                                    false,k);
279    x += padWidth;
280  }
281
282  G4cout << "Vertex is " << G4BestUnit(vertexLength,"Length")
283         << " of 3 layers of Si of " << G4BestUnit(padLength,"Length")
284         << " npads= " << npads
285         << G4endl;
286
287  // Define region for the vertex detector
288  vertexRegion->AddRootLogicalVolume(logicVV);
289  vertexRegion->AddRootLogicalVolume(logicA3);
290
291  // Define region for the muon detector
292  muonRegion->AddRootLogicalVolume(logicYV);
293
294  // color regions
295  logicVV-> SetVisAttributes(G4VisAttributes::Invisible);
296  logicV-> SetVisAttributes(G4VisAttributes::Invisible);
[1230]297  logicECal-> SetVisAttributes(G4VisAttributes::Invisible);
[807]298  logicYV-> SetVisAttributes(G4VisAttributes::Invisible);
299
300  G4VisAttributes* regWcolor = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3));
[1230]301  logicWorld->SetVisAttributes(regWcolor);
[807]302
303  G4VisAttributes* regVcolor = new G4VisAttributes(G4Colour(0., 0.3, 0.7));
304  logicVD->SetVisAttributes(regVcolor);
305
306  G4VisAttributes* regCcolor = new G4VisAttributes(G4Colour(0., 0.7, 0.3));
[1230]307  logicCal->SetVisAttributes(regCcolor);
[807]308
309  G4VisAttributes* regAcolor = new G4VisAttributes(G4Colour(1., 0.5, 0.5));
310  logicA1->SetVisAttributes(regAcolor);
311  logicA2->SetVisAttributes(regAcolor);
312  logicA3->SetVisAttributes(regAcolor);
313  logicA4->SetVisAttributes(regAcolor);
314
315  G4VisAttributes* regMcolor = new G4VisAttributes(G4Colour(1., 1., 0.));
316  logicY->SetVisAttributes(regMcolor);
317
318  // always return world
319  G4cout << "### New geometry is constructed" << G4endl;
[1230]320 
[807]321  return world;
322}
323
324//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
325
326void DetectorConstruction::SetEcalMaterial(const G4String& mat)
327{
328  // search the material by its name
329  G4Material* pttoMaterial = 
330    G4NistManager::Instance()->FindOrBuildMaterial(mat, false);
[1230]331  if (pttoMaterial) {
332    calMaterial = pttoMaterial;
333    if(logicCal) {
334      logicCal->SetMaterial(calMaterial);
335      G4RunManager::GetRunManager()->PhysicsHasBeenModified();
336    }
337  }
[807]338}
339
340//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
341
342void DetectorConstruction::SetAbsMaterial(const G4String& mat)
343{
344  // search the material by its name
345  G4Material* pttoMaterial = 
346    G4NistManager::Instance()->FindOrBuildMaterial(mat, false);
[1230]347  if (pttoMaterial) {
348    absMaterial = pttoMaterial;
349    if(logicA1) {
350      logicA1->SetMaterial(absMaterial);
351      logicA2->SetMaterial(absMaterial);
352      logicA3->SetMaterial(absMaterial);
353      logicA4->SetMaterial(absMaterial);
354      G4RunManager::GetRunManager()->PhysicsHasBeenModified();
355    }
356  }
[807]357}
358
359//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
360
361void DetectorConstruction::UpdateGeometry()
362{
[1230]363  G4RunManager::GetRunManager()->PhysicsHasBeenModified();
[807]364  G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
365}
366
367//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
[1230]368
369void DetectorConstruction::SetEcalLength (G4double val)   
370{
371  if(val > 0.0) {
372    ecalLength = val;
373    G4RunManager::GetRunManager()->GeometryHasBeenModified();
374  }
375}
376
377//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
378
379void DetectorConstruction::SetEcalWidth  (G4double val)   
380{
381  if(val > 0.0) {
382    ecalWidth = val;
383    G4RunManager::GetRunManager()->GeometryHasBeenModified();
384  }
385}
386
387//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
388
389void DetectorConstruction::SetVertexLength (G4double val) 
390{
391  if(val > 0.0) {
392    vertexLength = val;
393    G4RunManager::GetRunManager()->GeometryHasBeenModified();
394  }
395}
396
397//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
398
399void DetectorConstruction::SetPadLength  (G4double val)   
400{
401  if(val > 0.0) {
402    padLength = val;
403    G4RunManager::GetRunManager()->GeometryHasBeenModified();
404  }
405}
406
407//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
408
409void DetectorConstruction::SetPadWidth  (G4double val)   
410{
411  if(val > 0.0) {
412    padWidth = val;
413    G4RunManager::GetRunManager()->GeometryHasBeenModified();
414  }
415}
416
417//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
418
419void DetectorConstruction::SetAbsLength(G4double val)     
420{
421  if(val > 0.0) {
422    absLength = val;
423    G4RunManager::GetRunManager()->GeometryHasBeenModified();
424  }
425}
426
427//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Note: See TracBrowser for help on using the repository browser.