VMC Examples Version 6.6
Loading...
Searching...
No Matches
A01DetectorConstruction.cxx
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
27//------------------------------------------------
28// The Virtual Monte Carlo examples
29// Copyright (C) 2007 - 2014 Ivana Hrivnacova
30// All rights reserved.
31//
32// For the licensing terms see geant4_vmc/LICENSE.
33// Contact: root-vmc@cern.ch
34//-------------------------------------------------
35
36/// \file A01DetectorConstruction.cxx
37/// \brief Implementation of the A01DetectorConstruction class
38///
39/// Geant4 example A01 adapted to Virtual Monte Carlo
40
42#include "B5MagneticField.hh"
43
44// Added for VMC
45#include "TG4GeometryManager.h"
46
47#include "G4FieldManager.hh"
48#include "G4Mag_UsualEqRhs.hh"
49#include "G4TransportationManager.hh"
50
51#include "G4Element.hh"
52#include "G4Material.hh"
53#include "G4MaterialTable.hh"
54#include "G4NistManager.hh"
55
56#include "G4Box.hh"
57#include "G4LogicalVolume.hh"
58#include "G4PVParameterised.hh"
59#include "G4PVPlacement.hh"
60#include "G4PVReplica.hh"
61#include "G4Tubs.hh"
62#include "G4UserLimits.hh"
63#include "G4VPhysicalVolume.hh"
64#include "G4VSolid.hh"
65
66#include "G4GenericMessenger.hh"
67#include "G4RunManager.hh"
68#include "G4SDManager.hh"
69#include "G4VSensitiveDetector.hh"
70
71#include "G4Colour.hh"
72#include "G4VisAttributes.hh"
73
74#include "G4SystemOfUnits.hh"
75#include "G4ios.hh"
76
77//#include "A01CellParameterisation.h"
78/*
79#include "A01DriftChamber.hh"
80#include "A01EmCalorimeter.hh"
81#include "A01HadCalorimeter.hh"
82#include "A01Hodoscope.hh"
83
84#include "Geant4GM/volumes/Factory.h"
85#include "RootGM/volumes/Factory.h"
86#include "TGeoManager.h"
87*/
88
89//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90
92G4ThreadLocal G4FieldManager* A01DetectorConstruction::fFieldMgr = 0;
93
94//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
95
97 : fMagneticLogical(0),
98 fVisAttributes(),
99 fArmAngle(30. * deg),
100 fSecondArmPhys(0),
101 fUseLocalMagField(useLocalMagField)
102
103{
104 fArmRotation = new G4RotationMatrix();
105 fArmRotation->rotateY(fArmAngle);
106
107 // define commands for this class
109}
110
112{
113 delete fArmRotation;
114 delete fMessenger;
115
116 for (G4int i = 0; i < G4int(fVisAttributes.size()); ++i) {
117 delete fVisAttributes[i];
118 }
119}
120
122{
124 G4Material* air = G4Material::GetMaterial("G4_AIR");
125 // G4Material* argonGas = G4Material::GetMaterial("B5_Ar");
126 G4Material* argonGas = G4Material::GetMaterial("G4_Ar");
127 G4Material* scintillator =
128 G4Material::GetMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
129 G4Material* csI = G4Material::GetMaterial("G4_CESIUM_IODIDE");
130 G4Material* lead = G4Material::GetMaterial("G4_Pb");
131
132 // Option to switch on/off checking of volumes overlaps
133 //
134 G4bool checkOverlaps = true;
135
136 // geometries --------------------------------------------------------------
137 // experimental hall (world volume)
138 G4VSolid* worldSolid = new G4Box("worldBox", 10. * m, 3. * m, 10. * m);
139 G4LogicalVolume* worldLogical =
140 new G4LogicalVolume(worldSolid, air, "worldLogical", 0, 0, 0);
141 G4VPhysicalVolume* worldPhysical = new G4PVPlacement(0, G4ThreeVector(),
142 worldLogical, "worldPhysical", 0, false, 0, checkOverlaps);
143
144 // Tube with Local Magnetic field
145
146 G4VSolid* magneticSolid =
147 new G4Tubs("magneticTubs", 0., 1. * m, 1. * m, 0., 360. * deg);
148
149 fMagneticLogical = new G4LogicalVolume(magneticSolid, air, "magneticLogical");
150
151 // placement of Tube
152
153 G4RotationMatrix* fieldRot = new G4RotationMatrix();
154 fieldRot->rotateX(90. * deg);
155 new G4PVPlacement(fieldRot, G4ThreeVector(), fMagneticLogical,
156 "magneticPhysical", worldLogical, false, 0, checkOverlaps);
157
158 // set "user limits" for drawing smooth curve
159 G4UserLimits* userLimits = new G4UserLimits(5.0 * cm);
160 fMagneticLogical->SetUserLimits(userLimits);
161
162 // first arm
163 G4VSolid* firstArmSolid = new G4Box("firstArmBox", 1.5 * m, 1. * m, 3. * m);
164 G4LogicalVolume* firstArmLogical =
165 new G4LogicalVolume(firstArmSolid, air, "firstArmLogical", 0, 0, 0);
166 new G4PVPlacement(0, G4ThreeVector(0., 0., -5. * m), firstArmLogical,
167 "firstArmPhysical", worldLogical, false, 0, checkOverlaps);
168
169 // second arm
170 G4VSolid* secondArmSolid = new G4Box("secondArmBox", 2. * m, 2. * m, 3.5 * m);
171 G4LogicalVolume* secondArmLogical =
172 new G4LogicalVolume(secondArmSolid, air, "secondArmLogical", 0, 0, 0);
173 G4double x = -5. * m * std::sin(fArmAngle);
174 G4double z = 5. * m * std::cos(fArmAngle);
175 fSecondArmPhys = new G4PVPlacement(fArmRotation, G4ThreeVector(x, 0., z),
176 secondArmLogical, "fSecondArmPhys", worldLogical, false, 0, checkOverlaps);
177
178 // hodoscopes in first arm
179 G4VSolid* hodoscope1Solid =
180 new G4Box("hodoscope1Box", 5. * cm, 20. * cm, 0.5 * cm);
181 G4LogicalVolume* hodoscope1Logical = new G4LogicalVolume(
182 hodoscope1Solid, scintillator, "hodoscope1Logical", 0, 0, 0);
183 for (G4int i = 0; i < 15; i++) {
184 G4double x1 = (i - 7) * 10. * cm;
185 new G4PVPlacement(0, G4ThreeVector(x1, 0., -1.5 * m), hodoscope1Logical,
186 "hodoscope1Physical", firstArmLogical, false, i, checkOverlaps);
187 }
188
189 // drift chambers in first arm
190 G4VSolid* chamber1Solid = new G4Box("chamber1Box", 1. * m, 30. * cm, 1. * cm);
191 G4LogicalVolume* chamber1Logical =
192 new G4LogicalVolume(chamber1Solid, argonGas, "chamber1Logical", 0, 0, 0);
193 for (G4int i = 0; i < 5; i++) {
194 G4double z1 = (i - 2) * 0.5 * m;
195 new G4PVPlacement(0, G4ThreeVector(0., 0., z1), chamber1Logical,
196 "chamber1Physical", firstArmLogical, false, i, checkOverlaps);
197 }
198
199 // "virtual" wire plane
200 G4VSolid* wirePlane1Solid =
201 new G4Box("wirePlane1Box", 1. * m, 30. * cm, 0.1 * mm);
202 G4LogicalVolume* wirePlane1Logical = new G4LogicalVolume(
203 wirePlane1Solid, argonGas, "wirePlane1Logical", 0, 0, 0);
204 new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), wirePlane1Logical,
205 "wirePlane1Physical", chamber1Logical, false, 0, checkOverlaps);
206
207 // hodoscopes in second arm
208 G4VSolid* hodoscope2Solid =
209 new G4Box("hodoscope2Box", 5. * cm, 20. * cm, 0.5 * cm);
210 G4LogicalVolume* hodoscope2Logical = new G4LogicalVolume(
211 hodoscope2Solid, scintillator, "hodoscope2Logical", 0, 0, 0);
212 for (G4int i = 0; i < 25; i++) {
213 G4double x2 = (i - 12) * 10. * cm;
214 new G4PVPlacement(0, G4ThreeVector(x2, 0., 0.), hodoscope2Logical,
215 "hodoscope2Physical", secondArmLogical, false, 0, checkOverlaps);
216 }
217
218 // drift chambers in second arm
219 G4VSolid* chamber2Solid =
220 new G4Box("chamber2Box", 1.5 * m, 30. * cm, 1. * cm);
221 G4LogicalVolume* chamber2Logical =
222 new G4LogicalVolume(chamber2Solid, argonGas, "chamber2Logical", 0, 0, 0);
223 for (G4int i = 0; i < 5; i++) {
224 G4double z2 = (i - 2) * 0.5 * m - 1.5 * m;
225 new G4PVPlacement(0, G4ThreeVector(0., 0., z2), chamber2Logical,
226 "chamber2Physical", secondArmLogical, false, i, checkOverlaps);
227 }
228
229 // "virtual" wire plane
230 G4VSolid* wirePlane2Solid =
231 new G4Box("wirePlane2Box", 1.5 * m, 30. * cm, 0.1 * mm);
232 G4LogicalVolume* wirePlane2Logical = new G4LogicalVolume(
233 wirePlane2Solid, argonGas, "wirePlane2Logical", 0, 0, 0);
234 new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), wirePlane2Logical,
235 "wirePlane2Physical", chamber2Logical, false, 0, checkOverlaps);
236
237 // CsI calorimeter
238 G4VSolid* EMcalorimeterSolid =
239 new G4Box("EMcalorimeterBox", 1.5 * m, 30. * cm, 15. * cm);
240 G4LogicalVolume* EMcalorimeterLogical = new G4LogicalVolume(
241 EMcalorimeterSolid, csI, "EMcalorimeterLogical", 0, 0, 0);
242 new G4PVPlacement(0, G4ThreeVector(0., 0., 2. * m), EMcalorimeterLogical,
243 "EMcalorimeterPhysical", secondArmLogical, false, 0, checkOverlaps);
244
245 /*
246 // EMcalorimeter cells
247 G4VSolid* cellSolid = new G4Box("cellBox",7.5*cm,7.5*cm,15.*cm);
248 G4LogicalVolume* cellLogical
249 = new G4LogicalVolume(cellSolid,fCsI,"cellLogical",0,0,0);
250 G4VPVParameterisation* cellParam = new A01CellParameterisation();
251 new G4PVParameterised("cellPhysical",cellLogical,EMcalorimeterLogical,
252 kXAxis,80,cellParam);
253 */
254 // EMcalorimeter calorimeter column
255 G4VSolid* EmCalColumnSolid =
256 new G4Box("EmCalColumnBox", 7.5 * cm, 30. * cm, 15. * cm);
257 G4LogicalVolume* EmCalColumnLogical =
258 new G4LogicalVolume(EmCalColumnSolid, csI, "EmCalColumnLogical", 0, 0, 0);
259 new G4PVReplica("EmCalColumnPhysical", EmCalColumnLogical,
260 EMcalorimeterLogical, kXAxis, 20, 15. * cm);
261
262 // EM calorimeter cell
263 G4VSolid* cellSolid = new G4Box("cellBox", 7.5 * cm, 7.5 * cm, 15. * cm);
264 G4LogicalVolume* cellLogical =
265 new G4LogicalVolume(cellSolid, csI, "cellLogical", 0, 0, 0);
266 new G4PVReplica(
267 "cellPhysical", cellLogical, EmCalColumnLogical, kYAxis, 4, 15. * cm);
268
269 // hadron calorimeter
270 G4VSolid* HadCalorimeterSolid =
271 new G4Box("HadCalorimeterBox", 1.5 * m, 30. * cm, 50. * cm);
272 G4LogicalVolume* HadCalorimeterLogical = new G4LogicalVolume(
273 HadCalorimeterSolid, lead, "HadCalorimeterLogical", 0, 0, 0);
274 new G4PVPlacement(0, G4ThreeVector(0., 0., 3. * m), HadCalorimeterLogical,
275 "HadCalorimeterPhysical", secondArmLogical, false, 0, checkOverlaps);
276
277 // hadron calorimeter column
278 G4VSolid* HadCalColumnSolid =
279 new G4Box("HadCalColumnBox", 15. * cm, 30. * cm, 50. * cm);
280 G4LogicalVolume* HadCalColumnLogical = new G4LogicalVolume(
281 HadCalColumnSolid, lead, "HadCalColumnLogical", 0, 0, 0);
282 new G4PVReplica("HadCalColumnPhysical", HadCalColumnLogical,
283 HadCalorimeterLogical, kXAxis, 10, 30. * cm);
284
285 // hadron calorimeter cell
286 G4VSolid* HadCalCellSolid =
287 new G4Box("HadCalCellBox", 15. * cm, 15. * cm, 50. * cm);
288 G4LogicalVolume* HadCalCellLogical =
289 new G4LogicalVolume(HadCalCellSolid, lead, "HadCalCellLogical", 0, 0, 0);
290 new G4PVReplica("HadCalCellPhysical", HadCalCellLogical, HadCalColumnLogical,
291 kYAxis, 2, 30. * cm);
292
293 // hadron calorimeter layers
294 G4VSolid* HadCalLayerSolid =
295 new G4Box("HadCalLayerBox", 15. * cm, 15. * cm, 2.5 * cm);
296 G4LogicalVolume* HadCalLayerLogical =
297 new G4LogicalVolume(HadCalLayerSolid, lead, "HadCalLayerLogical", 0, 0, 0);
298 new G4PVReplica("HadCalLayerPhysical", HadCalLayerLogical, HadCalCellLogical,
299 kZAxis, 20, 5. * cm);
300
301 // scintillator plates
302 G4VSolid* HadCalScintiSolid =
303 new G4Box("HadCalScintiBox", 15. * cm, 15. * cm, 0.5 * cm);
304 G4LogicalVolume* HadCalScintiLogical = new G4LogicalVolume(
305 HadCalScintiSolid, scintillator, "HadCalScintiLogical", 0, 0, 0);
306 new G4PVPlacement(0, G4ThreeVector(0., 0., 2. * cm), HadCalScintiLogical,
307 "HadCalScintiPhysical", HadCalLayerLogical, false, 0, checkOverlaps);
308
309 // visualization attributes ------------------------------------------------
310
311 G4VisAttributes* visAttributes = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
312 visAttributes->SetVisibility(false);
313 worldLogical->SetVisAttributes(visAttributes);
314 fVisAttributes.push_back(visAttributes);
315
316 visAttributes = new G4VisAttributes(G4Colour(0.9, 0.9, 0.9)); // LightGray
317 fMagneticLogical->SetVisAttributes(visAttributes);
318 fVisAttributes.push_back(visAttributes);
319
320 visAttributes = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
321 visAttributes->SetVisibility(false);
322 firstArmLogical->SetVisAttributes(visAttributes);
323 secondArmLogical->SetVisAttributes(visAttributes);
324 fVisAttributes.push_back(visAttributes);
325
326 visAttributes = new G4VisAttributes(G4Colour(0.8888, 0.0, 0.0));
327 hodoscope1Logical->SetVisAttributes(visAttributes);
328 hodoscope2Logical->SetVisAttributes(visAttributes);
329 fVisAttributes.push_back(visAttributes);
330
331 visAttributes = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
332 chamber1Logical->SetVisAttributes(visAttributes);
333 chamber2Logical->SetVisAttributes(visAttributes);
334 fVisAttributes.push_back(visAttributes);
335
336 visAttributes = new G4VisAttributes(G4Colour(0.0, 0.8888, 0.0));
337 visAttributes->SetVisibility(false);
338 wirePlane1Logical->SetVisAttributes(visAttributes);
339 wirePlane2Logical->SetVisAttributes(visAttributes);
340 fVisAttributes.push_back(visAttributes);
341
342 visAttributes = new G4VisAttributes(G4Colour(0.8888, 0.8888, 0.0));
343 visAttributes->SetVisibility(false);
344 EMcalorimeterLogical->SetVisAttributes(visAttributes);
345 fVisAttributes.push_back(visAttributes);
346
347 visAttributes = new G4VisAttributes(G4Colour(0.9, 0.9, 0.0));
348 cellLogical->SetVisAttributes(visAttributes);
349 fVisAttributes.push_back(visAttributes);
350
351 visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
352 HadCalorimeterLogical->SetVisAttributes(visAttributes);
353 fVisAttributes.push_back(visAttributes);
354
355 visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
356 visAttributes->SetVisibility(false);
357 HadCalColumnLogical->SetVisAttributes(visAttributes);
358 HadCalCellLogical->SetVisAttributes(visAttributes);
359 HadCalLayerLogical->SetVisAttributes(visAttributes);
360 HadCalScintiLogical->SetVisAttributes(visAttributes);
361 fVisAttributes.push_back(visAttributes);
362
363 // return the world physical volume ----------------------------------------
364
365 /*
366 // Import Geant4 geometry to VGM
367 //
368 Geant4GM::Factory g4Factory;
369 g4Factory.SetDebug(1);
370 g4Factory.Import(worldPhysical);
371
372 // Export VGM geometry to Root
373 //
374 RootGM::Factory rtFactory;
375 rtFactory.SetDebug(1);
376 g4Factory.Export(&rtFactory);
377 gGeoManager->CloseGeometry();
378 gGeoManager->Export("A01.root");
379
380 //
381 // End of Export geometry in Root
382 //
383 */
384 return worldPhysical;
385}
386
387//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
388
390{
391 // Added for VMC (construct SDs)
392 TG4GeometryManager::Instance()->ConstructSDandField();
393
394 // magnetic field ----------------------------------------------------------
395 if (fUseLocalMagField) {
397 fFieldMgr = new G4FieldManager();
398 fFieldMgr->SetDetectorField(fMagneticField);
399 fFieldMgr->CreateChordFinder(fMagneticField);
400 G4bool forceToAllDaughters = true;
401 fMagneticLogical->SetFieldManager(fFieldMgr, forceToAllDaughters);
402 }
403}
404
405//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
406
408{
409 G4NistManager* nistManager = G4NistManager::Instance();
410
411 // Air
412 nistManager->FindOrBuildMaterial("G4_AIR");
413
414 // Argon gas
415 nistManager->FindOrBuildMaterial("G4_Ar");
416 // With a density different from the one defined in NIST
417 // G4double density = 1.782e-03*g/cm3;
418 // nistManager->BuildMaterialWithNewDensity("B5_Ar","G4_Ar",density);
419 // !! cases segmentation fault
420
421 // Scintillator
422 // (PolyVinylToluene, C_9H_10)
423 nistManager->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
424
425 // CsI
426 nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
427
428 // Lead
429 nistManager->FindOrBuildMaterial("G4_Pb");
430
431 // Vacuum "Galactic"
432 // nistManager->FindOrBuildMaterial("G4_Galactic");
433
434 // Vacuum "Air with low density"
435 // G4Material* air = G4Material::GetMaterial("G4_AIR");
436 // G4double density = 1.0e-5*air->GetDensity();
437 // nistManager
438 // ->BuildMaterialWithNewDensity("Air_lowDensity", "G4_AIR", density);
439
440 G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
441 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
442}
443
444//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
445
447{
448 if (!fSecondArmPhys) {
449 G4cerr << "Detector has not yet been constructed." << G4endl;
450 return;
451 }
452
453 fArmAngle = val;
454 *fArmRotation = G4RotationMatrix(); // make it unit vector
455 fArmRotation->rotateY(fArmAngle);
456 G4double x = -5. * m * std::sin(fArmAngle);
457 G4double z = 5. * m * std::cos(fArmAngle);
458 fSecondArmPhys->SetTranslation(G4ThreeVector(x, 0., z));
459
460 // tell G4RunManager that we change the geometry
461 G4RunManager::GetRunManager()->GeometryHasBeenModified();
462}
463
464//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
465
467{
468 // Define /B5/detector command directory using generic messenger class
469 fMessenger =
470 new G4GenericMessenger(this, "/A01/detector/", "Detector control");
471
472 // armAngle command
473 G4GenericMessenger::Command& armAngleCmd = fMessenger->DeclareMethodWithUnit(
474 "armAngle", "deg", &A01DetectorConstruction::SetArmAngle,
475 "Set rotation angle of the second arm.");
476 armAngleCmd.SetParameterName("angle", true);
477 armAngleCmd.SetRange("angle>=0. && angle<180.");
478 armAngleCmd.SetDefaultValue("30.");
479}
480
481//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Definition of the A01DetectorConstruction class.
Definition of the B5MagneticField class.
virtual G4VPhysicalVolume * Construct()
static G4ThreadLocal G4FieldManager * fFieldMgr
static G4ThreadLocal B5MagneticField * fMagneticField
A01DetectorConstruction(G4bool useLocalMagField)
std::vector< G4VisAttributes * > fVisAttributes
Magnetic field.