Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
B5::DetectorConstruction Class Reference

Detector construction. More...

#include <Doxymodules_basic.h>

Inheritance diagram for B5::DetectorConstruction:
G4VUserDetectorConstruction

Public Member Functions

 DetectorConstruction ()
 
 ~DetectorConstruction () override
 
G4VPhysicalVolumeConstruct () override
 
void ConstructSDandField () override
 
void SetArmAngle (G4double val)
 
G4double GetArmAngle ()
 
void ConstructMaterials ()
 

Private Member Functions

void DefineCommands ()
 

Private Attributes

G4GenericMessengerfMessenger = nullptr
 
G4LogicalVolumefHodoscope1Logical = nullptr
 
G4LogicalVolumefHodoscope2Logical = nullptr
 
G4LogicalVolumefWirePlane1Logical = nullptr
 
G4LogicalVolumefWirePlane2Logical = nullptr
 
G4LogicalVolumefCellLogical = nullptr
 
G4LogicalVolumefHadCalScintiLogical = nullptr
 
G4LogicalVolumefMagneticLogical = nullptr
 
G4double fArmAngle = 30.*CLHEP::deg
 
G4RotationMatrix * fArmRotation = nullptr
 
G4VPhysicalVolumefSecondArmPhys = nullptr
 

Static Private Attributes

static G4ThreadLocal MagneticFieldfMagneticField = nullptr
 
static G4ThreadLocal G4FieldManagerfFieldMgr = nullptr
 

Detailed Description

Detector construction.

Definition at line 186 of file Doxymodules_basic.h.

Constructor & Destructor Documentation

◆ DetectorConstruction()

B5::DetectorConstruction::DetectorConstruction ( )

Definition at line 78 of file DetectorConstruction.cc.

79{
80 fArmRotation = new G4RotationMatrix();
81 fArmRotation->rotateY(fArmAngle);
82
83 // define commands for this class
85}

◆ ~DetectorConstruction()

B5::DetectorConstruction::~DetectorConstruction ( )
override

Definition at line 89 of file DetectorConstruction.cc.

90{
91 delete fArmRotation;
92 delete fMessenger;
93}
G4GenericMessenger * fMessenger

Member Function Documentation

◆ Construct()

G4VPhysicalVolume * B5::DetectorConstruction::Construct ( )
override

Definition at line 97 of file DetectorConstruction.cc.

98{
99 // Construct materials
101 auto air = G4Material::GetMaterial("G4_AIR");
102 //auto argonGas = G4Material::GetMaterial("_Ar");
103 auto argonGas = G4Material::GetMaterial("G4_Ar");
104 auto scintillator = G4Material::GetMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
105 auto csI = G4Material::GetMaterial("G4_CESIUM_IODIDE");
106 auto lead = G4Material::GetMaterial("G4_Pb");
107
108 // Option to switch on/off checking of volumes overlaps
109 //
110 G4bool checkOverlaps = true;
111
112 // geometries --------------------------------------------------------------
113 // experimental hall (world volume)
114 auto worldSolid
115 = new G4Box("worldBox",10.*m,3.*m,10.*m);
116 auto worldLogical
117 = new G4LogicalVolume(worldSolid,air,"worldLogical");
118 auto worldPhysical = new G4PVPlacement(
119 nullptr, G4ThreeVector(), worldLogical, "worldPhysical", nullptr, false, 0, checkOverlaps);
120
121 // Tube with Local Magnetic field
122
123 auto magneticSolid
124 = new G4Tubs("magneticTubs",0.,1.*m,1.*m,0.,360.*deg);
125
127 = new G4LogicalVolume(magneticSolid, air, "magneticLogical");
128
129 // placement of Tube
130
131 auto fieldRot = new G4RotationMatrix();
132 fieldRot->rotateX(90.*deg);
133 new G4PVPlacement(fieldRot,G4ThreeVector(),fMagneticLogical,
134 "magneticPhysical",worldLogical,
135 false,0,checkOverlaps);
136
137 // set step limit in tube with magnetic field
138 auto userLimits = new G4UserLimits(1 * m);
139 fMagneticLogical->SetUserLimits(userLimits);
140
141 // first arm
142 auto firstArmSolid
143 = new G4Box("firstArmBox",1.5*m,1.*m,3.*m);
144 auto firstArmLogical
145 = new G4LogicalVolume(firstArmSolid,air,"firstArmLogical");
146 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., -5. * m), firstArmLogical, "firstArmPhysical",
147 worldLogical, false, 0, checkOverlaps);
148
149 // second arm
150 auto secondArmSolid
151 = new G4Box("secondArmBox",2.*m,2.*m,3.5*m);
152 auto secondArmLogical
153 = new G4LogicalVolume(secondArmSolid,air,"secondArmLogical");
154 auto x = -5.*m * std::sin(fArmAngle);
155 auto z = 5.*m * std::cos(fArmAngle);
157 = new G4PVPlacement(fArmRotation,G4ThreeVector(x,0.,z),secondArmLogical,
158 "fSecondArmPhys",worldLogical,
159 false,0,checkOverlaps);
160
161 // hodoscopes in first arm
162 auto hodoscope1Solid
163 = new G4Box("hodoscope1Box",5.*cm,20.*cm,0.5*cm);
165 = new G4LogicalVolume(hodoscope1Solid,scintillator,"hodoscope1Logical");
166
167 for (auto i=0;i<kNofHodoscopes1;i++) {
168 G4double x1 = (i-kNofHodoscopes1/2)*10.*cm;
169 new G4PVPlacement(nullptr, G4ThreeVector(x1, 0., -1.5 * m), fHodoscope1Logical,
170 "hodoscope1Physical", firstArmLogical, false, i, checkOverlaps);
171 }
172
173 // drift chambers in first arm
174 auto chamber1Solid
175 = new G4Box("chamber1Box",1.*m,30.*cm,1.*cm);
176 auto chamber1Logical
177 = new G4LogicalVolume(chamber1Solid,argonGas,"chamber1Logical");
178
179 for (auto i=0;i<kNofChambers;i++) {
180 G4double z1 = (i-kNofChambers/2)*0.5*m;
181 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., z1), chamber1Logical, "chamber1Physical",
182 firstArmLogical, false, i, checkOverlaps);
183 }
184
185 // "virtual" wire plane
186 auto wirePlane1Solid
187 = new G4Box("wirePlane1Box",1.*m,30.*cm,0.1*mm);
189 = new G4LogicalVolume(wirePlane1Solid,argonGas,"wirePlane1Logical");
190 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 0.), fWirePlane1Logical, "wirePlane1Physical",
191 chamber1Logical, false, 0, checkOverlaps);
192
193 // hodoscopes in second arm
194 auto hodoscope2Solid
195 = new G4Box("hodoscope2Box",5.*cm,20.*cm,0.5*cm);
197 = new G4LogicalVolume(hodoscope2Solid,scintillator,"hodoscope2Logical");
198
199 for (auto i=0;i<kNofHodoscopes2;i++) {
200 G4double x2 = (i-kNofHodoscopes2/2)*10.*cm;
201 new G4PVPlacement(nullptr, G4ThreeVector(x2, 0., 0.), fHodoscope2Logical,
202 "hodoscope2Physical", secondArmLogical, false, i, checkOverlaps);
203 }
204
205 // drift chambers in second arm
206 auto chamber2Solid
207 = new G4Box("chamber2Box",1.5*m,30.*cm,1.*cm);
208 auto chamber2Logical
209 = new G4LogicalVolume(chamber2Solid,argonGas,"chamber2Logical");
210
211 for (auto i=0;i<kNofChambers;i++) {
212 G4double z2 = (i-kNofChambers/2)*0.5*m - 1.5*m;
213 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., z2), chamber2Logical, "chamber2Physical",
214 secondArmLogical, false, i, checkOverlaps);
215 }
216
217 // "virtual" wire plane
218 auto wirePlane2Solid
219 = new G4Box("wirePlane2Box",1.5*m,30.*cm,0.1*mm);
221 = new G4LogicalVolume(wirePlane2Solid,argonGas,"wirePlane2Logical");
222 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 0.), fWirePlane2Logical, "wirePlane2Physical",
223 chamber2Logical, false, 0, checkOverlaps);
224
225 // CsI calorimeter
226 auto emCalorimeterSolid
227 = new G4Box("EMcalorimeterBox",1.5*m,30.*cm,15.*cm);
228 auto emCalorimeterLogical
229 = new G4LogicalVolume(emCalorimeterSolid,csI,"EMcalorimeterLogical");
230 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 2. * m), emCalorimeterLogical,
231 "EMcalorimeterPhysical", secondArmLogical, false, 0, checkOverlaps);
232
233 // EMcalorimeter cells
234 auto cellSolid
235 = new G4Box("cellBox",7.5*cm,7.5*cm,15.*cm);
237 = new G4LogicalVolume(cellSolid,csI,"cellLogical");
238 G4VPVParameterisation* cellParam = new CellParameterisation();
239 new G4PVParameterised("cellPhysical",fCellLogical,emCalorimeterLogical,
240 kXAxis,kNofEmCells,cellParam);
241
242 // hadron calorimeter
243 auto hadCalorimeterSolid
244 = new G4Box("HadCalorimeterBox",1.5*m,30.*cm,50.*cm);
245 auto hadCalorimeterLogical
246 = new G4LogicalVolume(hadCalorimeterSolid,lead,"HadCalorimeterLogical");
247 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 3. * m), hadCalorimeterLogical,
248 "HadCalorimeterPhysical", secondArmLogical, false, 0, checkOverlaps);
249
250 // hadron calorimeter column
251 auto HadCalColumnSolid
252 = new G4Box("HadCalColumnBox",15.*cm,30.*cm,50.*cm);
253 auto HadCalColumnLogical
254 = new G4LogicalVolume(HadCalColumnSolid,lead,"HadCalColumnLogical");
255 new G4PVReplica("HadCalColumnPhysical",HadCalColumnLogical,
256 hadCalorimeterLogical,kXAxis,kNofHadColumns,30.*cm);
257
258 // hadron calorimeter cell
259 auto HadCalCellSolid
260 = new G4Box("HadCalCellBox",15.*cm,15.*cm,50.*cm);
261 auto HadCalCellLogical
262 = new G4LogicalVolume(HadCalCellSolid,lead,"HadCalCellLogical");
263 new G4PVReplica("HadCalCellPhysical",HadCalCellLogical,
264 HadCalColumnLogical,kYAxis,kNofHadRows,30.*cm);
265
266 // hadron calorimeter layers
267 auto HadCalLayerSolid
268 = new G4Box("HadCalLayerBox",15.*cm,15.*cm,2.5*cm);
269 auto HadCalLayerLogical
270 = new G4LogicalVolume(HadCalLayerSolid,lead,"HadCalLayerLogical");
271 new G4PVReplica("HadCalLayerPhysical",HadCalLayerLogical,
272 HadCalCellLogical,kZAxis,kNofHadCells,5.*cm);
273
274 // scintillator plates
275 auto HadCalScintiSolid
276 = new G4Box("HadCalScintiBox",15.*cm,15.*cm,0.5*cm);
278 = new G4LogicalVolume(HadCalScintiSolid,scintillator,
279 "HadCalScintiLogical");
280 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 2. * cm), fHadCalScintiLogical,
281 "HadCalScintiPhysical", HadCalLayerLogical, false, 0, checkOverlaps);
282
283 // visualization attributes ------------------------------------------------
284
285 G4VisAttributes invisible(G4VisAttributes::GetInvisible());
286 G4VisAttributes invisibleBlue(false, G4Colour::Blue());
287 G4VisAttributes invisibleGreen(false, G4Colour::Green());
288 G4VisAttributes invisibleYellow(false, G4Colour::Yellow());
289 G4VisAttributes blue(G4Colour::Blue());
290 G4VisAttributes cgray(G4Colour::Gray());
291 G4VisAttributes green(G4Colour::Green());
292 G4VisAttributes red(G4Colour::Red());
293 G4VisAttributes yellow(G4Colour::Yellow());
294
295 worldLogical->SetVisAttributes(invisible);
296 firstArmLogical->SetVisAttributes(invisible);
297 secondArmLogical->SetVisAttributes(invisible);
298
299 fMagneticLogical->SetVisAttributes(cgray);
300 fHodoscope1Logical->SetVisAttributes(red);
301 fHodoscope2Logical->SetVisAttributes(red);
302
303 chamber1Logical->SetVisAttributes(green);
304 chamber2Logical->SetVisAttributes(green);
305 fWirePlane1Logical->SetVisAttributes(invisibleGreen);
306 fWirePlane2Logical->SetVisAttributes(invisibleGreen);
307
308 emCalorimeterLogical->SetVisAttributes(invisibleYellow);
309 fCellLogical->SetVisAttributes(yellow);
310
311 hadCalorimeterLogical->SetVisAttributes(blue);
312 HadCalColumnLogical->SetVisAttributes(invisibleBlue);
313 HadCalCellLogical->SetVisAttributes(invisibleBlue);
314 HadCalLayerLogical->SetVisAttributes(invisibleBlue);
315 fHadCalScintiLogical->SetVisAttributes(invisibleBlue);
316
317 // return the world physical volume ----------------------------------------
318
319 return worldPhysical;
320}
G4LogicalVolume * fHadCalScintiLogical
G4LogicalVolume * fWirePlane1Logical
G4LogicalVolume * fHodoscope1Logical
G4LogicalVolume * fWirePlane2Logical
G4LogicalVolume * fHodoscope2Logical
G4VPhysicalVolume * fSecondArmPhys
constexpr G4int kNofChambers
Definition Constants.hh:40
constexpr G4int kNofHodoscopes2
Definition Constants.hh:39
constexpr G4int kNofHadCells
Definition Constants.hh:46
constexpr G4int kNofEmCells
Definition Constants.hh:43
constexpr G4int kNofHadRows
Definition Constants.hh:45
constexpr G4int kNofHodoscopes1
Definition Constants.hh:38
constexpr G4int kNofHadColumns
Definition Constants.hh:44

◆ ConstructSDandField()

void B5::DetectorConstruction::ConstructSDandField ( )
override

Definition at line 324 of file DetectorConstruction.cc.

325{
326 // sensitive detectors -----------------------------------------------------
327 auto sdManager = G4SDManager::GetSDMpointer();
328 G4String SDname;
329
330 auto hodoscope1 = new HodoscopeSD(SDname="/hodoscope1");
331 sdManager->AddNewDetector(hodoscope1);
332 fHodoscope1Logical->SetSensitiveDetector(hodoscope1);
333
334 auto hodoscope2 = new HodoscopeSD(SDname="/hodoscope2");
335 sdManager->AddNewDetector(hodoscope2);
336 fHodoscope2Logical->SetSensitiveDetector(hodoscope2);
337
338 auto chamber1 = new DriftChamberSD(SDname="/chamber1");
339 sdManager->AddNewDetector(chamber1);
340 fWirePlane1Logical->SetSensitiveDetector(chamber1);
341
342 auto chamber2 = new DriftChamberSD(SDname="/chamber2");
343 sdManager->AddNewDetector(chamber2);
344 fWirePlane2Logical->SetSensitiveDetector(chamber2);
345
346 auto emCalorimeter = new EmCalorimeterSD(SDname="/EMcalorimeter");
347 sdManager->AddNewDetector(emCalorimeter);
348 fCellLogical->SetSensitiveDetector(emCalorimeter);
349
350 auto hadCalorimeter = new HadCalorimeterSD(SDname="/HadCalorimeter");
351 sdManager->AddNewDetector(hadCalorimeter);
352 fHadCalScintiLogical->SetSensitiveDetector(hadCalorimeter);
353
354 // magnetic field ----------------------------------------------------------
355 fMagneticField = new MagneticField();
357 fFieldMgr->SetDetectorField(fMagneticField);
358 fFieldMgr->CreateChordFinder(fMagneticField);
359 G4bool forceToAllDaughters = true;
360 fMagneticLogical->SetFieldManager(fFieldMgr, forceToAllDaughters);
361}
static G4ThreadLocal MagneticField * fMagneticField
static G4ThreadLocal G4FieldManager * fFieldMgr

◆ SetArmAngle()

void B5::DetectorConstruction::SetArmAngle ( G4double  val)

Definition at line 404 of file DetectorConstruction.cc.

405{
406 if (!fSecondArmPhys) {
407 G4cerr << "Detector has not yet been constructed." << G4endl;
408 return;
409 }
410
411 fArmAngle = val;
412 *fArmRotation = G4RotationMatrix(); // make it unit vector
413 fArmRotation->rotateY(fArmAngle);
414 auto x = -5.*m * std::sin(fArmAngle);
415 auto z = 5.*m * std::cos(fArmAngle);
416 fSecondArmPhys->SetTranslation(G4ThreeVector(x,0.,z));
417
418 // tell G4RunManager that we change the geometry
419 G4RunManager::GetRunManager()->GeometryHasBeenModified();
420}

◆ GetArmAngle()

G4double B5::DetectorConstruction::GetArmAngle ( )
inline

Definition at line 62 of file DetectorConstruction.hh.

62{ return fArmAngle; }

◆ ConstructMaterials()

void B5::DetectorConstruction::ConstructMaterials ( )

Definition at line 365 of file DetectorConstruction.cc.

366{
367 auto nistManager = G4NistManager::Instance();
368
369 // Air
370 nistManager->FindOrBuildMaterial("G4_AIR");
371
372 // Argon gas
373 nistManager->FindOrBuildMaterial("G4_Ar");
374 // With a density different from the one defined in NIST
375 // G4double density = 1.782e-03*g/cm3;
376 // nistManager->BuildMaterialWithNewDensity("_Ar","G4_Ar",density);
377 // !! cases segmentation fault
378
379 // Scintillator
380 // (PolyVinylToluene, C_9H_10)
381 nistManager->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
382
383 // CsI
384 nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
385
386 // Lead
387 nistManager->FindOrBuildMaterial("G4_Pb");
388
389 // Vacuum "Galactic"
390 // nistManager->FindOrBuildMaterial("G4_Galactic");
391
392 // Vacuum "Air with low density"
393 // auto air = G4Material::GetMaterial("G4_AIR");
394 // G4double density = 1.0e-5*air->GetDensity();
395 // nistManager
396 // ->BuildMaterialWithNewDensity("Air_lowDensity", "G4_AIR", density);
397
398 G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
399 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
400}

◆ DefineCommands()

void B5::DetectorConstruction::DefineCommands ( )
private

Definition at line 424 of file DetectorConstruction.cc.

425{
426 // Define /B5/detector command directory using generic messenger class
428 "/B5/detector/",
429 "Detector control");
430
431 // armAngle command
432 auto& armAngleCmd
433 = fMessenger->DeclareMethodWithUnit("armAngle","deg",
435 "Set rotation angle of the second arm.");
436 armAngleCmd.SetParameterName("angle", true);
437 armAngleCmd.SetRange("angle>=0. && angle<180.");
438 armAngleCmd.SetDefaultValue("30.");
439}

Member Data Documentation

◆ fMagneticField

G4ThreadLocal MagneticField * B5::DetectorConstruction::fMagneticField = nullptr
staticprivate

Definition at line 69 of file DetectorConstruction.hh.

◆ fFieldMgr

G4ThreadLocal G4FieldManager * B5::DetectorConstruction::fFieldMgr = nullptr
staticprivate

Definition at line 70 of file DetectorConstruction.hh.

◆ fMessenger

G4GenericMessenger* B5::DetectorConstruction::fMessenger = nullptr
private

Definition at line 72 of file DetectorConstruction.hh.

◆ fHodoscope1Logical

G4LogicalVolume* B5::DetectorConstruction::fHodoscope1Logical = nullptr
private

Definition at line 74 of file DetectorConstruction.hh.

◆ fHodoscope2Logical

G4LogicalVolume* B5::DetectorConstruction::fHodoscope2Logical = nullptr
private

Definition at line 75 of file DetectorConstruction.hh.

◆ fWirePlane1Logical

G4LogicalVolume* B5::DetectorConstruction::fWirePlane1Logical = nullptr
private

Definition at line 76 of file DetectorConstruction.hh.

◆ fWirePlane2Logical

G4LogicalVolume* B5::DetectorConstruction::fWirePlane2Logical = nullptr
private

Definition at line 77 of file DetectorConstruction.hh.

◆ fCellLogical

G4LogicalVolume* B5::DetectorConstruction::fCellLogical = nullptr
private

Definition at line 78 of file DetectorConstruction.hh.

◆ fHadCalScintiLogical

G4LogicalVolume* B5::DetectorConstruction::fHadCalScintiLogical = nullptr
private

Definition at line 79 of file DetectorConstruction.hh.

◆ fMagneticLogical

G4LogicalVolume* B5::DetectorConstruction::fMagneticLogical = nullptr
private

Definition at line 80 of file DetectorConstruction.hh.

◆ fArmAngle

G4double B5::DetectorConstruction::fArmAngle = 30.*CLHEP::deg
private

Definition at line 82 of file DetectorConstruction.hh.

◆ fArmRotation

G4RotationMatrix* B5::DetectorConstruction::fArmRotation = nullptr
private

Definition at line 83 of file DetectorConstruction.hh.

◆ fSecondArmPhys

G4VPhysicalVolume* B5::DetectorConstruction::fSecondArmPhys = nullptr
private

Definition at line 84 of file DetectorConstruction.hh.


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

Applications | User Support | Publications | Collaboration