Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
B5DetectorConstruction Class Reference

Detector construction. More...

#include <B5DetectorConstruction.hh>

Inheritance diagram for B5DetectorConstruction:
Collaboration diagram for B5DetectorConstruction:

Public Member Functions

 B5DetectorConstruction ()
 
virtual ~B5DetectorConstruction ()
 
virtual G4VPhysicalVolumeConstruct ()
 
virtual void ConstructSDandField ()
 
void SetArmAngle (G4double val)
 
G4double GetArmAngle ()
 
void ConstructMaterials ()
 
- Public Member Functions inherited from G4VUserDetectorConstruction
 G4VUserDetectorConstruction ()
 
virtual ~G4VUserDetectorConstruction ()
 
virtual void CloneSD ()
 
virtual void CloneF ()
 
void RegisterParallelWorld (G4VUserParallelWorld *)
 
G4int ConstructParallelGeometries ()
 
void ConstructParallelSD ()
 
G4int GetNumberOfParallelWorld () const
 
G4VUserParallelWorldGetParallelWorld (G4int i) const
 

Additional Inherited Members

- Protected Member Functions inherited from G4VUserDetectorConstruction
void SetSensitiveDetector (const G4String &logVolName, G4VSensitiveDetector *aSD, G4bool multi=false)
 
void SetSensitiveDetector (G4LogicalVolume *logVol, G4VSensitiveDetector *aSD)
 

Detailed Description

Detector construction.

Definition at line 51 of file B5DetectorConstruction.hh.

Constructor & Destructor Documentation

B5DetectorConstruction::B5DetectorConstruction ( )

Definition at line 77 of file B5DetectorConstruction.cc.

79  fMessenger(nullptr),
80  fHodoscope1Logical(nullptr), fHodoscope2Logical(nullptr),
81  fWirePlane1Logical(nullptr), fWirePlane2Logical(nullptr),
82  fCellLogical(nullptr), fHadCalScintiLogical(nullptr),
83  fMagneticLogical(nullptr),
84  fVisAttributes(),
85  fArmAngle(30.*deg), fArmRotation(nullptr), fSecondArmPhys(nullptr)
86 
87 {
88  fArmRotation = new G4RotationMatrix();
89  fArmRotation->rotateY(fArmAngle);
90 
91  // define commands for this class
92  DefineCommands();
93 }
CLHEP::HepRotation G4RotationMatrix
HepRotation & rotateY(double delta)
Definition: Rotation.cc:79
static constexpr double deg
Definition: G4SIunits.hh:152

Here is the call graph for this function:

B5DetectorConstruction::~B5DetectorConstruction ( )
virtual

Definition at line 97 of file B5DetectorConstruction.cc.

98 {
99  delete fArmRotation;
100  delete fMessenger;
101 
102  for (auto visAttributes: fVisAttributes) {
103  delete visAttributes;
104  }
105 }

Member Function Documentation

G4VPhysicalVolume * B5DetectorConstruction::Construct ( void  )
virtual

Implements G4VUserDetectorConstruction.

Definition at line 109 of file B5DetectorConstruction.cc.

110 {
111  // Construct materials
113  auto air = G4Material::GetMaterial("G4_AIR");
114  //auto argonGas = G4Material::GetMaterial("B5_Ar");
115  auto argonGas = G4Material::GetMaterial("G4_Ar");
116  auto scintillator = G4Material::GetMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
117  auto csI = G4Material::GetMaterial("G4_CESIUM_IODIDE");
118  auto lead = G4Material::GetMaterial("G4_Pb");
119 
120  // Option to switch on/off checking of volumes overlaps
121  //
122  G4bool checkOverlaps = true;
123 
124  // geometries --------------------------------------------------------------
125  // experimental hall (world volume)
126  auto worldSolid
127  = new G4Box("worldBox",10.*m,3.*m,10.*m);
128  auto worldLogical
129  = new G4LogicalVolume(worldSolid,air,"worldLogical");
130  auto worldPhysical
131  = new G4PVPlacement(0,G4ThreeVector(),worldLogical,"worldPhysical",0,
132  false,0,checkOverlaps);
133 
134  // Tube with Local Magnetic field
135 
136  auto magneticSolid
137  = new G4Tubs("magneticTubs",0.,1.*m,1.*m,0.,360.*deg);
138 
139  fMagneticLogical
140  = new G4LogicalVolume(magneticSolid, air, "magneticLogical");
141 
142  // placement of Tube
143 
144  G4RotationMatrix* fieldRot = new G4RotationMatrix();
145  fieldRot->rotateX(90.*deg);
146  new G4PVPlacement(fieldRot,G4ThreeVector(),fMagneticLogical,
147  "magneticPhysical",worldLogical,
148  false,0,checkOverlaps);
149 
150  // set step limit in tube with magnetic field
151  G4UserLimits* userLimits = new G4UserLimits(1*m);
152  fMagneticLogical->SetUserLimits(userLimits);
153 
154  // first arm
155  auto firstArmSolid
156  = new G4Box("firstArmBox",1.5*m,1.*m,3.*m);
157  auto firstArmLogical
158  = new G4LogicalVolume(firstArmSolid,air,"firstArmLogical");
159  new G4PVPlacement(0,G4ThreeVector(0.,0.,-5.*m),firstArmLogical,
160  "firstArmPhysical",worldLogical,
161  false,0,checkOverlaps);
162 
163  // second arm
164  auto secondArmSolid
165  = new G4Box("secondArmBox",2.*m,2.*m,3.5*m);
166  auto secondArmLogical
167  = new G4LogicalVolume(secondArmSolid,air,"secondArmLogical");
168  auto x = -5.*m * std::sin(fArmAngle);
169  auto z = 5.*m * std::cos(fArmAngle);
170  fSecondArmPhys
171  = new G4PVPlacement(fArmRotation,G4ThreeVector(x,0.,z),secondArmLogical,
172  "fSecondArmPhys",worldLogical,
173  false,0,checkOverlaps);
174 
175  // hodoscopes in first arm
176  auto hodoscope1Solid
177  = new G4Box("hodoscope1Box",5.*cm,20.*cm,0.5*cm);
178  fHodoscope1Logical
179  = new G4LogicalVolume(hodoscope1Solid,scintillator,"hodoscope1Logical");
180 
181  for (auto i=0;i<kNofHodoscopes1;i++) {
182  G4double x1 = (i-kNofHodoscopes1/2)*10.*cm;
183  new G4PVPlacement(0,G4ThreeVector(x1,0.,-1.5*m),fHodoscope1Logical,
184  "hodoscope1Physical",firstArmLogical,
185  false,i,checkOverlaps);
186  }
187 
188  // drift chambers in first arm
189  auto chamber1Solid
190  = new G4Box("chamber1Box",1.*m,30.*cm,1.*cm);
191  auto chamber1Logical
192  = new G4LogicalVolume(chamber1Solid,argonGas,"chamber1Logical");
193 
194  for (auto i=0;i<kNofChambers;i++) {
195  G4double z1 = (i-kNofChambers/2)*0.5*m;
196  new G4PVPlacement(0,G4ThreeVector(0.,0.,z1),chamber1Logical,
197  "chamber1Physical",firstArmLogical,
198  false,i,checkOverlaps);
199  }
200 
201  // "virtual" wire plane
202  auto wirePlane1Solid
203  = new G4Box("wirePlane1Box",1.*m,30.*cm,0.1*mm);
204  fWirePlane1Logical
205  = new G4LogicalVolume(wirePlane1Solid,argonGas,"wirePlane1Logical");
206  new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),fWirePlane1Logical,
207  "wirePlane1Physical",chamber1Logical,
208  false,0,checkOverlaps);
209 
210  // hodoscopes in second arm
211  auto hodoscope2Solid
212  = new G4Box("hodoscope2Box",5.*cm,20.*cm,0.5*cm);
213  fHodoscope2Logical
214  = new G4LogicalVolume(hodoscope2Solid,scintillator,"hodoscope2Logical");
215 
216  for (auto i=0;i<kNofHodoscopes2;i++) {
217  G4double x2 = (i-kNofHodoscopes2/2)*10.*cm;
218  new G4PVPlacement(0,G4ThreeVector(x2,0.,0.),fHodoscope2Logical,
219  "hodoscope2Physical",secondArmLogical,
220  false,i,checkOverlaps);
221  }
222 
223  // drift chambers in second arm
224  auto chamber2Solid
225  = new G4Box("chamber2Box",1.5*m,30.*cm,1.*cm);
226  auto chamber2Logical
227  = new G4LogicalVolume(chamber2Solid,argonGas,"chamber2Logical");
228 
229  for (auto i=0;i<kNofChambers;i++) {
230  G4double z2 = (i-kNofChambers/2)*0.5*m - 1.5*m;
231  new G4PVPlacement(0,G4ThreeVector(0.,0.,z2),chamber2Logical,
232  "chamber2Physical",secondArmLogical,
233  false,i,checkOverlaps);
234  }
235 
236  // "virtual" wire plane
237  auto wirePlane2Solid
238  = new G4Box("wirePlane2Box",1.5*m,30.*cm,0.1*mm);
239  fWirePlane2Logical
240  = new G4LogicalVolume(wirePlane2Solid,argonGas,"wirePlane2Logical");
241  new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),fWirePlane2Logical,
242  "wirePlane2Physical",chamber2Logical,
243  false,0,checkOverlaps);
244 
245  // CsI calorimeter
246  auto emCalorimeterSolid
247  = new G4Box("EMcalorimeterBox",1.5*m,30.*cm,15.*cm);
248  auto emCalorimeterLogical
249  = new G4LogicalVolume(emCalorimeterSolid,csI,"EMcalorimeterLogical");
250  new G4PVPlacement(0,G4ThreeVector(0.,0.,2.*m),emCalorimeterLogical,
251  "EMcalorimeterPhysical",secondArmLogical,
252  false,0,checkOverlaps);
253 
254  // EMcalorimeter cells
255  auto cellSolid
256  = new G4Box("cellBox",7.5*cm,7.5*cm,15.*cm);
257  fCellLogical
258  = new G4LogicalVolume(cellSolid,csI,"cellLogical");
260  new G4PVParameterised("cellPhysical",fCellLogical,emCalorimeterLogical,
261  kXAxis,kNofEmCells,cellParam);
262 
263  // hadron calorimeter
264  auto hadCalorimeterSolid
265  = new G4Box("HadCalorimeterBox",1.5*m,30.*cm,50.*cm);
266  auto hadCalorimeterLogical
267  = new G4LogicalVolume(hadCalorimeterSolid,lead,"HadCalorimeterLogical");
268  new G4PVPlacement(0,G4ThreeVector(0.,0.,3.*m),hadCalorimeterLogical,
269  "HadCalorimeterPhysical",secondArmLogical,
270  false,0,checkOverlaps);
271 
272  // hadron calorimeter column
273  auto HadCalColumnSolid
274  = new G4Box("HadCalColumnBox",15.*cm,30.*cm,50.*cm);
275  auto HadCalColumnLogical
276  = new G4LogicalVolume(HadCalColumnSolid,lead,"HadCalColumnLogical");
277  new G4PVReplica("HadCalColumnPhysical",HadCalColumnLogical,
278  hadCalorimeterLogical,kXAxis,kNofHadColumns,30.*cm);
279 
280  // hadron calorimeter cell
281  auto HadCalCellSolid
282  = new G4Box("HadCalCellBox",15.*cm,15.*cm,50.*cm);
283  auto HadCalCellLogical
284  = new G4LogicalVolume(HadCalCellSolid,lead,"HadCalCellLogical");
285  new G4PVReplica("HadCalCellPhysical",HadCalCellLogical,
286  HadCalColumnLogical,kYAxis,kNofHadRows,30.*cm);
287 
288  // hadron calorimeter layers
289  auto HadCalLayerSolid
290  = new G4Box("HadCalLayerBox",15.*cm,15.*cm,2.5*cm);
291  auto HadCalLayerLogical
292  = new G4LogicalVolume(HadCalLayerSolid,lead,"HadCalLayerLogical");
293  new G4PVReplica("HadCalLayerPhysical",HadCalLayerLogical,
294  HadCalCellLogical,kZAxis,kNofHadCells,5.*cm);
295 
296  // scintillator plates
297  auto HadCalScintiSolid
298  = new G4Box("HadCalScintiBox",15.*cm,15.*cm,0.5*cm);
299  fHadCalScintiLogical
300  = new G4LogicalVolume(HadCalScintiSolid,scintillator,
301  "HadCalScintiLogical");
302  new G4PVPlacement(0,G4ThreeVector(0.,0.,2.*cm),fHadCalScintiLogical,
303  "HadCalScintiPhysical",HadCalLayerLogical,
304  false,0,checkOverlaps);
305 
306  // visualization attributes ------------------------------------------------
307 
308  auto visAttributes = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
309  visAttributes->SetVisibility(false);
310  worldLogical->SetVisAttributes(visAttributes);
311  fVisAttributes.push_back(visAttributes);
312 
313  visAttributes = new G4VisAttributes(G4Colour(0.9,0.9,0.9)); // LightGray
314  fMagneticLogical->SetVisAttributes(visAttributes);
315  fVisAttributes.push_back(visAttributes);
316 
317  visAttributes = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
318  visAttributes->SetVisibility(false);
319  firstArmLogical->SetVisAttributes(visAttributes);
320  secondArmLogical->SetVisAttributes(visAttributes);
321  fVisAttributes.push_back(visAttributes);
322 
323  visAttributes = new G4VisAttributes(G4Colour(0.8888,0.0,0.0));
324  fHodoscope1Logical->SetVisAttributes(visAttributes);
325  fHodoscope2Logical->SetVisAttributes(visAttributes);
326  fVisAttributes.push_back(visAttributes);
327 
328  visAttributes = new G4VisAttributes(G4Colour(0.0,1.0,0.0));
329  chamber1Logical->SetVisAttributes(visAttributes);
330  chamber2Logical->SetVisAttributes(visAttributes);
331  fVisAttributes.push_back(visAttributes);
332 
333  visAttributes = new G4VisAttributes(G4Colour(0.0,0.8888,0.0));
334  visAttributes->SetVisibility(false);
335  fWirePlane1Logical->SetVisAttributes(visAttributes);
336  fWirePlane2Logical->SetVisAttributes(visAttributes);
337  fVisAttributes.push_back(visAttributes);
338 
339  visAttributes = new G4VisAttributes(G4Colour(0.8888,0.8888,0.0));
340  visAttributes->SetVisibility(false);
341  emCalorimeterLogical->SetVisAttributes(visAttributes);
342  fVisAttributes.push_back(visAttributes);
343 
344  visAttributes = new G4VisAttributes(G4Colour(0.9,0.9,0.0));
345  fCellLogical->SetVisAttributes(visAttributes);
346  fVisAttributes.push_back(visAttributes);
347 
348  visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
349  hadCalorimeterLogical->SetVisAttributes(visAttributes);
350  fVisAttributes.push_back(visAttributes);
351 
352  visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.9));
353  visAttributes->SetVisibility(false);
354  HadCalColumnLogical->SetVisAttributes(visAttributes);
355  HadCalCellLogical->SetVisAttributes(visAttributes);
356  HadCalLayerLogical->SetVisAttributes(visAttributes);
357  fHadCalScintiLogical->SetVisAttributes(visAttributes);
358  fVisAttributes.push_back(visAttributes);
359 
360  // return the world physical volume ----------------------------------------
361 
362  return worldPhysical;
363 }
static constexpr double mm
Definition: G4SIunits.hh:115
CLHEP::Hep3Vector G4ThreeVector
HepRotation & rotateX(double delta)
Definition: Rotation.cc:66
CLHEP::HepRotation G4RotationMatrix
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:602
Definition: G4Box.hh:64
void SetUserLimits(G4UserLimits *pULimits)
Definition: G4Tubs.hh:85
constexpr G4int kNofChambers
Definition: B5Constants.hh:38
tuple x
Definition: test.py:50
constexpr G4int kNofHadCells
Definition: B5Constants.hh:44
static constexpr double m
Definition: G4SIunits.hh:129
constexpr G4int kNofHadRows
Definition: B5Constants.hh:43
bool G4bool
Definition: G4Types.hh:79
EM Calorimeter cell parameterisation.
static constexpr double cm
Definition: G4SIunits.hh:119
constexpr G4int kNofHadColumns
Definition: B5Constants.hh:42
constexpr G4int kNofHodoscopes2
Definition: B5Constants.hh:37
tuple z
Definition: test.py:28
double G4double
Definition: G4Types.hh:76
static constexpr double deg
Definition: G4SIunits.hh:152
constexpr G4int kNofEmCells
Definition: B5Constants.hh:41
constexpr G4int kNofHodoscopes1
Definition: B5Constants.hh:36
void SetVisAttributes(const G4VisAttributes *pVA)

Here is the call graph for this function:

void B5DetectorConstruction::ConstructMaterials ( )

Definition at line 412 of file B5DetectorConstruction.cc.

413 {
414  auto nistManager = G4NistManager::Instance();
415 
416  // Air
417  nistManager->FindOrBuildMaterial("G4_AIR");
418 
419  // Argon gas
420  nistManager->FindOrBuildMaterial("G4_Ar");
421  // With a density different from the one defined in NIST
422  // G4double density = 1.782e-03*g/cm3;
423  // nistManager->BuildMaterialWithNewDensity("B5_Ar","G4_Ar",density);
424  // !! cases segmentation fault
425 
426  // Scintillator
427  // (PolyVinylToluene, C_9H_10)
428  nistManager->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
429 
430  // CsI
431  nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
432 
433  // Lead
434  nistManager->FindOrBuildMaterial("G4_Pb");
435 
436  // Vacuum "Galactic"
437  // nistManager->FindOrBuildMaterial("G4_Galactic");
438 
439  // Vacuum "Air with low density"
440  // auto air = G4Material::GetMaterial("G4_AIR");
441  // G4double density = 1.0e-5*air->GetDensity();
442  // nistManager
443  // ->BuildMaterialWithNewDensity("Air_lowDensity", "G4_AIR", density);
444 
445  G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
446  G4cout << *(G4Material::GetMaterialTable()) << G4endl;
447 }
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:587
static G4NistManager * Instance()
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

void B5DetectorConstruction::ConstructSDandField ( )
virtual

Reimplemented from G4VUserDetectorConstruction.

Definition at line 367 of file B5DetectorConstruction.cc.

368 {
369  // sensitive detectors -----------------------------------------------------
370  auto sdManager = G4SDManager::GetSDMpointer();
371  G4String SDname;
372 
373  auto hodoscope1 = new B5HodoscopeSD(SDname="/hodoscope1");
374  sdManager->AddNewDetector(hodoscope1);
375  fHodoscope1Logical->SetSensitiveDetector(hodoscope1);
376 
377  auto hodoscope2 = new B5HodoscopeSD(SDname="/hodoscope2");
378  sdManager->AddNewDetector(hodoscope2);
379  fHodoscope2Logical->SetSensitiveDetector(hodoscope2);
380 
381  auto chamber1 = new B5DriftChamberSD(SDname="/chamber1");
382  sdManager->AddNewDetector(chamber1);
383  fWirePlane1Logical->SetSensitiveDetector(chamber1);
384 
385  auto chamber2 = new B5DriftChamberSD(SDname="/chamber2");
386  sdManager->AddNewDetector(chamber2);
387  fWirePlane2Logical->SetSensitiveDetector(chamber2);
388 
389  auto emCalorimeter = new B5EmCalorimeterSD(SDname="/EMcalorimeter");
390  sdManager->AddNewDetector(emCalorimeter);
391  fCellLogical->SetSensitiveDetector(emCalorimeter);
392 
393  auto hadCalorimeter = new B5HadCalorimeterSD(SDname="/HadCalorimeter");
394  sdManager->AddNewDetector(hadCalorimeter);
395  fHadCalScintiLogical->SetSensitiveDetector(hadCalorimeter);
396 
397  // magnetic field ----------------------------------------------------------
398  fMagneticField = new B5MagneticField();
399  fFieldMgr = new G4FieldManager();
400  fFieldMgr->SetDetectorField(fMagneticField);
401  fFieldMgr->CreateChordFinder(fMagneticField);
402  G4bool forceToAllDaughters = true;
403  fMagneticLogical->SetFieldManager(fFieldMgr, forceToAllDaughters);
404 
405  // Register the field and its manager for deleting
406  G4AutoDelete::Register(fMagneticField);
407  G4AutoDelete::Register(fFieldMgr);
408 }
G4bool SetDetectorField(G4Field *detectorField)
Drift chamber sensitive detector.
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
void Register(T *inst)
Definition: G4AutoDelete.hh:65
bool G4bool
Definition: G4Types.hh:79
Magnetic field.
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
Hodoscope sensitive detector.
void CreateChordFinder(G4MagneticField *detectorMagField)
EM calorimeter sensitive detector.
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
Hadron calorimeter sensitive detector.

Here is the call graph for this function:

G4double B5DetectorConstruction::GetArmAngle ( )
inline

Definition at line 61 of file B5DetectorConstruction.hh.

61 { return fArmAngle; }
void B5DetectorConstruction::SetArmAngle ( G4double  val)

Definition at line 451 of file B5DetectorConstruction.cc.

452 {
453  if (!fSecondArmPhys) {
454  G4cerr << "Detector has not yet been constructed." << G4endl;
455  return;
456  }
457 
458  fArmAngle = val;
459  *fArmRotation = G4RotationMatrix(); // make it unit vector
460  fArmRotation->rotateY(fArmAngle);
461  auto x = -5.*m * std::sin(fArmAngle);
462  auto z = 5.*m * std::cos(fArmAngle);
463  fSecondArmPhys->SetTranslation(G4ThreeVector(x,0.,z));
464 
465  // tell G4RunManager that we change the geometry
467 }
void GeometryHasBeenModified(G4bool prop=true)
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
tuple x
Definition: test.py:50
HepRotation & rotateY(double delta)
Definition: Rotation.cc:79
static constexpr double m
Definition: G4SIunits.hh:129
void SetTranslation(const G4ThreeVector &v)
static G4RunManager * GetRunManager()
Definition: G4RunManager.cc:79
tuple z
Definition: test.py:28
#define G4endl
Definition: G4ios.hh:61
G4GLOB_DLL std::ostream G4cerr

Here is the call graph for this function:


The documentation for this class was generated from the following files: