Loading...
Searching...
No Matches
LXeDetectorConstruction.cc
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/// \file optical/LXe/src/LXeDetectorConstruction.cc
28/// \brief Implementation of the LXeDetectorConstruction class
29//
30//
32
34#include "LXeMainVolume.hh"
35#include "LXePMTSD.hh"
36#include "LXeScintSD.hh"
37#include "LXeWLSSlab.hh"
38
39#include "globals.hh"
40#include "G4Box.hh"
41#include "G4GeometryManager.hh"
42#include "G4LogicalBorderSurface.hh"
43#include "G4LogicalSkinSurface.hh"
44#include "G4LogicalVolume.hh"
45#include "G4LogicalVolumeStore.hh"
46#include "G4Material.hh"
47#include "G4MaterialTable.hh"
48#include "G4OpticalSurface.hh"
49#include "G4PhysicalConstants.hh"
50#include "G4PhysicalVolumeStore.hh"
51#include "G4PVPlacement.hh"
52#include "G4RunManager.hh"
53#include "G4SDManager.hh"
54#include "G4SolidStore.hh"
55#include "G4Sphere.hh"
56#include "G4SystemOfUnits.hh"
57#include "G4ThreeVector.hh"
58#include "G4Tubs.hh"
59#include "G4UImanager.hh"
60#include "G4VisAttributes.hh"
61
63
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
65
72
73//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
74
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
84
86{
87 G4double a; // atomic mass
88 G4double z; // atomic number
89 G4double density;
90
91 G4int polyPMMA = 1;
92 G4int nC_PMMA = 3 + 2 * polyPMMA;
93 G4int nH_PMMA = 6 + 2 * polyPMMA;
94
95 G4int polyeth = 1;
96 G4int nC_eth = 2 * polyeth;
97 G4int nH_eth = 4 * polyeth;
98
99 //***Elements
100 fH = new G4Element("H", "H", z = 1., a = 1.01 * g / mole);
101 fC = new G4Element("C", "C", z = 6., a = 12.01 * g / mole);
102 fN = new G4Element("N", "N", z = 7., a = 14.01 * g / mole);
103 fO = new G4Element("O", "O", z = 8., a = 16.00 * g / mole);
104
105 //***Materials
106 // Liquid Xenon
107 fLXe = new G4Material("LXe", z = 54., a = 131.29 * g / mole,
108 density = 3.020 * g / cm3);
109 // Aluminum
110 fAl = new G4Material("Al", z = 13., a = 26.98 * g / mole,
111 density = 2.7 * g / cm3);
112 // Vacuum
113 fVacuum = new G4Material("Vacuum", z = 1., a = 1.01 * g / mole,
114 density = universe_mean_density, kStateGas,
115 0.1 * kelvin, 1.e-19 * pascal);
116 // Air
117 fAir = new G4Material("Air", density = 1.29 * mg / cm3, 2);
118 fAir->AddElement(fN, 70 * perCent);
119 fAir->AddElement(fO, 30 * perCent);
120 // Glass
121 fGlass = new G4Material("Glass", density = 1.032 * g / cm3, 2);
122 fGlass->AddElement(fC, 91.533 * perCent);
123 fGlass->AddElement(fH, 8.467 * perCent);
124 // Polystyrene
125 fPstyrene = new G4Material("Polystyrene", density = 1.03 * g / cm3, 2);
126 fPstyrene->AddElement(fC, 8);
127 fPstyrene->AddElement(fH, 8);
128 // Fiber(PMMA)
129 fPMMA = new G4Material("PMMA", density = 1190. * kg / m3, 3);
130 fPMMA->AddElement(fH, nH_PMMA);
131 fPMMA->AddElement(fC, nC_PMMA);
132 fPMMA->AddElement(fO, 2);
133 // Cladding(polyethylene)
134 fPethylene1 = new G4Material("Pethylene1", density = 1200. * kg / m3, 2);
135 fPethylene1->AddElement(fH, nH_eth);
136 fPethylene1->AddElement(fC, nC_eth);
137 // Double cladding(flourinated polyethylene)
138 fPethylene2 = new G4Material("Pethylene2", density = 1400. * kg / m3, 2);
139 fPethylene2->AddElement(fH, nH_eth);
140 fPethylene2->AddElement(fC, nC_eth);
141
142 //***Material properties tables
143
144 std::vector<G4double> lxe_Energy = { 7.0 * eV, 7.07 * eV, 7.14 * eV };
145
146 std::vector<G4double> lxe_SCINT = { 0.1, 1.0, 0.1 };
147 std::vector<G4double> lxe_RIND = { 1.59, 1.57, 1.54 };
148 std::vector<G4double> lxe_ABSL = { 35. * cm, 35. * cm, 35. * cm };
150 fLXe_mt->AddProperty("SCINTILLATIONCOMPONENT1", lxe_Energy, lxe_SCINT);
151 fLXe_mt->AddProperty("SCINTILLATIONCOMPONENT2", lxe_Energy, lxe_SCINT);
152 fLXe_mt->AddProperty("RINDEX", lxe_Energy, lxe_RIND);
153 fLXe_mt->AddProperty("ABSLENGTH", lxe_Energy, lxe_ABSL);
154 fLXe_mt->AddConstProperty("SCINTILLATIONYIELD", 12000. / MeV);
155 fLXe_mt->AddConstProperty("RESOLUTIONSCALE", 1.0);
156 fLXe_mt->AddConstProperty("SCINTILLATIONTIMECONSTANT1", 20. * ns);
157 fLXe_mt->AddConstProperty("SCINTILLATIONTIMECONSTANT2", 45. * ns);
158 fLXe_mt->AddConstProperty("SCINTILLATIONYIELD1", 1.0);
159 fLXe_mt->AddConstProperty("SCINTILLATIONYIELD2", 0.0);
160 fLXe->SetMaterialPropertiesTable(fLXe_mt);
161
162 // Set the Birks Constant for the LXe scintillator
163 fLXe->GetIonisation()->SetBirksConstant(0.126 * mm / MeV);
164
165 std::vector<G4double> glass_AbsLength = { 420. * cm, 420. * cm, 420. * cm };
166 auto glass_mt = new G4MaterialPropertiesTable();
167 glass_mt->AddProperty("ABSLENGTH", lxe_Energy, glass_AbsLength);
168 glass_mt->AddProperty("RINDEX", "Fused Silica");
169 fGlass->SetMaterialPropertiesTable(glass_mt);
170
171 auto vacuum_mt = new G4MaterialPropertiesTable();
172 vacuum_mt->AddProperty("RINDEX", "Air");
173 fVacuum->SetMaterialPropertiesTable(vacuum_mt);
174 fAir->SetMaterialPropertiesTable(vacuum_mt); // Give air the same rindex
175
176 std::vector<G4double> wls_Energy = { 2.00 * eV, 2.87 * eV, 2.90 * eV,
177 3.47 * eV };
178
179 std::vector<G4double> rIndexPstyrene = { 1.5, 1.5, 1.5, 1.5 };
180 std::vector<G4double> absorption1 = { 2. * cm, 2. * cm, 2. * cm, 2. * cm };
181 std::vector<G4double> scintilFast = { 0.0, 0.0, 1.0, 1.0 };
183 fMPTPStyrene->AddProperty("RINDEX", wls_Energy, rIndexPstyrene);
184 fMPTPStyrene->AddProperty("ABSLENGTH", wls_Energy, absorption1);
185 fMPTPStyrene->AddProperty("SCINTILLATIONCOMPONENT1", wls_Energy, scintilFast);
186 fMPTPStyrene->AddConstProperty("SCINTILLATIONYIELD", 10. / keV);
187 fMPTPStyrene->AddConstProperty("RESOLUTIONSCALE", 1.0);
188 fMPTPStyrene->AddConstProperty("SCINTILLATIONTIMECONSTANT1", 10. * ns);
189 fPstyrene->SetMaterialPropertiesTable(fMPTPStyrene);
190
191 // Set the Birks Constant for the Polystyrene scintillator
192 fPstyrene->GetIonisation()->SetBirksConstant(0.126 * mm / MeV);
193
194 std::vector<G4double> AbsFiber = { 9.0 * m, 9.0 * m, 0.1 * mm, 0.1 * mm };
195 std::vector<G4double> EmissionFib = { 1.0, 1.0, 0.0, 0.0 };
196 auto fiberProperty = new G4MaterialPropertiesTable();
197 fiberProperty->AddProperty("RINDEX", "PMMA");
198 fiberProperty->AddProperty("WLSABSLENGTH", wls_Energy, AbsFiber);
199 fiberProperty->AddProperty("WLSCOMPONENT", wls_Energy, EmissionFib);
200 fiberProperty->AddConstProperty("WLSTIMECONSTANT", 0.5 * ns);
201 fPMMA->SetMaterialPropertiesTable(fiberProperty);
202
203 std::vector<G4double> RefractiveIndexClad1 = { 1.49, 1.49, 1.49, 1.49 };
204 auto clad1Property = new G4MaterialPropertiesTable();
205 clad1Property->AddProperty("RINDEX", wls_Energy, RefractiveIndexClad1);
206 clad1Property->AddProperty("ABSLENGTH", wls_Energy, AbsFiber);
207 fPethylene1->SetMaterialPropertiesTable(clad1Property);
208
209 std::vector<G4double> RefractiveIndexClad2 = { 1.42, 1.42, 1.42, 1.42 };
210 auto clad2Property = new G4MaterialPropertiesTable();
211 clad2Property->AddProperty("RINDEX", wls_Energy, RefractiveIndexClad2);
212 clad2Property->AddProperty("ABSLENGTH", wls_Energy, AbsFiber);
213 fPethylene2->SetMaterialPropertiesTable(clad2Property);
214}
215
216//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
217
219{
220 // The experimental hall walls are all 1m away from housing walls
221 G4double expHall_x = fScint_x + fD_mtl + 1. * m;
222 G4double expHall_y = fScint_y + fD_mtl + 1. * m;
223 G4double expHall_z = fScint_z + fD_mtl + 1. * m;
224
225 // Create experimental hall
227 new G4Box("expHall_box", expHall_x, expHall_y, expHall_z);
229 new G4LogicalVolume(fExperimentalHall_box, fVacuum, "expHall_log");
231 G4ThreeVector(), fExperimentalHall_log, "expHall", nullptr, false, 0);
232
233 fExperimentalHall_log->SetVisAttributes(G4VisAttributes::GetInvisible());
234
235 // Place the main volume
236 if(fMainVolumeOn)
237 {
238 fMainVolume = new LXeMainVolume(nullptr, G4ThreeVector(),
239 fExperimentalHall_log, false, 0, this);
240 }
241
242 // Place the WLS slab
243 if(fWLSslab)
244 {
245 G4VPhysicalVolume* slab = new LXeWLSSlab(
246 nullptr, G4ThreeVector(0., 0., -fScint_z / 2. - fSlab_z - 1. * cm),
247 fExperimentalHall_log, false, 0, this);
248
249 // Surface properties for the WLS slab
250 auto scintWrap = new G4OpticalSurface("ScintWrap");
251
252 new G4LogicalBorderSurface("ScintWrap", slab, fExperimentalHall_phys,
253 scintWrap);
254
255 scintWrap->SetType(dielectric_metal);
256 scintWrap->SetFinish(polished);
257 scintWrap->SetModel(glisur);
258
259 std::vector<G4double> pp = { 2.0 * eV, 3.5 * eV };
260 std::vector<G4double> reflectivity = { 1.0, 1.0 };
261 std::vector<G4double> efficiency = { 0.0, 0.0 };
262
263 auto scintWrapProperty = new G4MaterialPropertiesTable();
264
265 scintWrapProperty->AddProperty("REFLECTIVITY", pp, reflectivity);
266 scintWrapProperty->AddProperty("EFFICIENCY", pp, efficiency);
267 scintWrap->SetMaterialPropertiesTable(scintWrapProperty);
268 }
269
271}
272
273//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
274
276{
277 if(!fMainVolume)
278 return;
279
280 // PMT SD
281
282 LXePMTSD* pmt = fPmt_SD.Get();
283 if(!pmt)
284 {
285 // Created here so it exists as pmts are being placed
286 G4cout << "Construction /LXeDet/pmtSD" << G4endl;
287 auto pmt_SD = new LXePMTSD("/LXeDet/pmtSD");
288 fPmt_SD.Put(pmt_SD);
289
290 pmt_SD->InitPMTs();
291 pmt_SD->SetPmtPositions(fMainVolume->GetPmtPositions());
292 }
293 else
294 {
295 pmt->InitPMTs();
297 }
298 G4SDManager::GetSDMpointer()->AddNewDetector(fPmt_SD.Get());
299 // sensitive detector is not actually on the photocathode.
300 // processHits gets done manually by the stepping action.
301 // It is used to detect when photons hit and get absorbed & detected at the
302 // boundary to the photocathode (which doesn't get done by attaching it to a
303 // logical volume.
304 // It does however need to be attached to something or else it doesn't get
305 // reset at the begining of events
306
307 SetSensitiveDetector(fMainVolume->GetLogPhotoCath(), fPmt_SD.Get());
308
309 // Scint SD
310
311 if(!fScint_SD.Get())
312 {
313 G4cout << "Construction /LXeDet/scintSD" << G4endl;
314 auto scint_SD = new LXeScintSD("/LXeDet/scintSD");
315 fScint_SD.Put(scint_SD);
316 }
317 G4SDManager::GetSDMpointer()->AddNewDetector(fScint_SD.Get());
318 SetSensitiveDetector(fMainVolume->GetLogScint(), fScint_SD.Get());
319}
320
321//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
322
324{
325 fScint_x = dims[0];
326 fScint_y = dims[1];
327 fScint_z = dims[2];
328 G4RunManager::GetRunManager()->ReinitializeGeometry();
329}
330
331//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
332
334{
335 fD_mtl = d_mtl;
336 G4RunManager::GetRunManager()->ReinitializeGeometry();
337}
338
339//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
340
342{
343 fNx = nx;
344 G4RunManager::GetRunManager()->ReinitializeGeometry();
345}
346
347//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
348
350{
351 fNy = ny;
352 G4RunManager::GetRunManager()->ReinitializeGeometry();
353}
354
355//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
356
358{
359 fNz = nz;
360 G4RunManager::GetRunManager()->ReinitializeGeometry();
361}
362
363//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
364
365void LXeDetectorConstruction::SetPMTRadius(G4double outerRadius_pmt)
366{
367 fOuterRadius_pmt = outerRadius_pmt;
368 G4RunManager::GetRunManager()->ReinitializeGeometry();
369}
370
371//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
372
374{
375 // Resets to default values
376 fD_mtl = 0.0635 * cm;
377
378 fScint_x = 17.8 * cm;
379 fScint_y = 17.8 * cm;
380 fScint_z = 22.6 * cm;
381
382 fNx = 2;
383 fNy = 2;
384 fNz = 3;
385
386 fOuterRadius_pmt = 2.3 * cm;
387
388 fSphereOn = true;
389 fRefl = 1.0;
390
391 fNfibers = 15;
392 fWLSslab = false;
393 fMainVolumeOn = true;
394 fMainVolume = nullptr;
395 fSlab_z = 2.5 * mm;
396
397 G4UImanager::GetUIpointer()->ApplyCommand(
398 "/LXe/detector/scintYieldFactor 1.");
399
400 if(fLXe_mt)
401 fLXe_mt->AddConstProperty("SCINTILLATIONYIELD", 12000. / MeV);
402 if(fMPTPStyrene)
403 fMPTPStyrene->AddConstProperty("SCINTILLATIONYIELD", 10. / keV);
404}
405
406//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
407
409{
410 fSphereOn = b;
411 G4RunManager::GetRunManager()->ReinitializeGeometry();
412}
413
414//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
415
417{
418 fRefl = r;
419 G4RunManager::GetRunManager()->ReinitializeGeometry();
420}
421
422//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
423
425{
426 fWLSslab = b;
427 G4RunManager::GetRunManager()->ReinitializeGeometry();
428}
429
430//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
431
433{
434 fMainVolumeOn = b;
435 G4RunManager::GetRunManager()->ReinitializeGeometry();
436}
437
438//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
439
441{
442 fNfibers = n;
443 G4RunManager::GetRunManager()->ReinitializeGeometry();
444}
445
446//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
447
449{
450 fLXe_mt->AddConstProperty("SCINTILLATIONYIELD", y / MeV);
451}
452
453//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
454
456{
457 fMPTPStyrene->AddConstProperty("SCINTILLATIONYIELD", y / MeV);
458}
459
460//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
461
463{
464 // Sets the save threshold for the random number seed. If the number of
465 // photons generated in an event is lower than this, then save the seed for
466 // this event in a file called run###evt###.rndm
467
468 fSaveThreshold = save;
469 G4RunManager::GetRunManager()->SetRandomNumberStore(true);
470}
471
472//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
std::vector< ExP01TrackerHit * > a
Definition of the LXeDetectorConstruction class.
Definition of the LXeDetectorMessenger class.
Definition of the LXeMainVolume class.
Definition of the LXePMTSD class.
Definition of the LXeScintSD class.
Definition of the LXeWLSSlab class.
G4Cache< LXeScintSD * > fScint_SD
G4MaterialPropertiesTable * fMPTPStyrene
LXeDetectorMessenger * fDetectorMessenger
G4VPhysicalVolume * fExperimentalHall_phys
G4MaterialPropertiesTable * fLXe_mt
G4VPhysicalVolume * Construct() override
std::vector< G4ThreeVector > GetPmtPositions()
G4LogicalVolume * GetLogScint()
G4LogicalVolume * GetLogPhotoCath()
void InitPMTs()
Definition LXePMTSD.hh:57
void SetPmtPositions(const std::vector< G4ThreeVector > &positions)
Definition LXePMTSD.cc:67

Applications | User Support | Publications | Collaboration