EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ePHENIXRICHConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ePHENIXRICHConstruction.cc
1 // $$Id: ePHENIXRICHConstruction.cc,v 1.7 2014/05/01 19:02:45 phnxbld Exp $$
2 
12 
13 #include "PHG4RICHDisplayAction.h"
14 
15 #include <g4main/PHG4DisplayAction.h> // for PHG4DisplayAction
16 #include <g4main/PHG4Subsystem.h> // for PHG4Subsystem
17 
18 #include <TSystem.h>
19 
20 #include <Geant4/G4Cons.hh>
21 #include <Geant4/G4DisplacedSolid.hh> // for G4DisplacedSolid
22 #include <Geant4/G4IntersectionSolid.hh>
23 #include <Geant4/G4LogicalSkinSurface.hh>
24 #include <Geant4/G4LogicalVolume.hh>
25 #include <Geant4/G4Material.hh>
26 #include <Geant4/G4MaterialPropertiesTable.hh> // for G4MaterialProperties...
27 #include <Geant4/G4OpticalSurface.hh>
28 #include <Geant4/G4Orb.hh>
29 #include <Geant4/G4PVPlacement.hh>
30 #include <Geant4/G4PhysicalConstants.hh> // for pi
31 #include <Geant4/G4Sphere.hh>
32 #include <Geant4/G4String.hh> // for G4String
33 #include <Geant4/G4SubtractionSolid.hh>
34 #include <Geant4/G4SurfaceProperty.hh> // for dielectric_metal
35 #include <Geant4/G4SystemOfUnits.hh> // for cm, eV, um
36 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
37 #include <Geant4/G4Transform3D.hh> // for G4RotateX3D, G4Rotat...
38 #include <Geant4/G4Tubs.hh>
39 #include <Geant4/G4Types.hh> // for G4double, G4int
40 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
41 #include <Geant4/G4NistManager.hh>
42 
43 #include <cassert>
44 #include <cmath>
45 #include <iostream>
46 #include <sstream>
47 #include <string> // for operator+, operator<<
48 #include <boost/stacktrace.hpp>
49 
50 class G4VSolid;
51 
52 using namespace std;
53 using namespace ePHENIXRICH;
54 
55 ePHENIXRICHConstruction::ePHENIXRICHConstruction(PHG4Subsystem *subsys)
56  : m_DisplayAction(dynamic_cast<PHG4RICHDisplayAction *>(subsys->GetDisplayAction()))
57  , overlapcheck_rich(false)
58 
59 {
60 }
62  : geom(g)
63  , m_DisplayAction(dynamic_cast<PHG4RICHDisplayAction *>(subsys->GetDisplayAction()))
64  , overlapcheck_rich(false)
65 {
66 }
67 
68 G4LogicalVolume *ePHENIXRICHConstruction::RegisterLogicalVolume(G4LogicalVolume *v)
69 {
70  if (!v)
71  {
72  std::cout << "ePHENIXRICHConstruction::RegisterVolume - Error - invalid volume!"
73  << std::endl;
74  return v;
75  }
76  if (map_log_vol.find(v->GetName()) != map_log_vol.end())
77  {
78  std::cout << "ePHENIXRICHConstruction::RegisterVolume - Warning - replacing "
79  << v->GetName() << std::endl;
80  }
81 
82  map_log_vol[v->GetName()] = v;
83 
84  return v;
85 }
86 
87 G4PVPlacement *ePHENIXRICHConstruction::RegisterPhysicalVolume(G4PVPlacement *v)
88 {
89  if (!v)
90  {
91  std::cout << "ePHENIXRICHConstruction::RegisterPhysicalVolume - Error - invalid volume!"
92  << std::endl;
93  return v;
94  }
95 
96  phy_vol_idx_t id(v->GetName(), v->GetCopyNo());
97 
98  if (map_phy_vol.find(id) != map_phy_vol.end())
99  {
100  std::cout << "ePHENIXRICHConstruction::RegisterPhysicalVolume - Warning - replacing "
101  << v->GetName() << "[" << v->GetCopyNo() << "]" << std::endl;
102  }
103 
104  map_phy_vol[id] = v;
105  return v;
106 }
107 
108 G4LogicalVolume *
109 ePHENIXRICHConstruction::Construct_RICH(G4LogicalVolume *WorldLog)
110 {
111  // -- Logical volume:
112  G4VSolid *RICHOutSphereBoundary = new G4Orb("RICHOutSphereBoundary",
113  geom.get_R_max());
114  G4VSolid *RICHOutSphereBoundary_place = new G4DisplacedSolid("RICHOutSphereBoundary_place", RICHOutSphereBoundary, 0,
115  G4ThreeVector(0, geom.get_R_shift(), geom.get_z_shift()));
116 
117  G4VSolid *RICHInnerSphereBoundary = new G4Orb("RICHInnerSphereBoundary",
119  G4VSolid *RICHInnerSphereBoundary_place = new G4DisplacedSolid("RICHInnerSphereBoundary_place",
120  RICHInnerSphereBoundary,
121  0,
122  G4ThreeVector(0,
125 
126  G4VSolid *RICHConeBoundary = new G4Cons("RICHConeBoundary", //
128  geom.get_z_shift() / 2 * std::tan(2 * std::atan(std::exp(-geom.get_min_eta()))), // G4double pRmin1, G4double pRmax1,
130  geom.get_cone_size_z() * std::tan(2 * std::atan(std::exp(-geom.get_min_eta()))), // G4double pRmin2, G4double pRmax2,
131  (geom.get_cone_size_z() - (geom.get_z_shift() / 2)) / 2, // G4double pDz,
132  0, 2 * pi // G4double pSPhi, G4double pDPhi
133  );
134  G4VSolid *RICHConeBoundary_place = new G4DisplacedSolid("RICHConeBoundary_place",
135  RICHConeBoundary,
136  0,
137  G4ThreeVector(
138  0,
139  0,
140  (geom.get_cone_size_z() - (geom.get_z_shift() / 2)) / 2 + (geom.get_z_shift() / 2)));
141 
142  G4VSolid *RICHSecBoundary = new G4Tubs("RICHSecBoundary", //
143  0, // G4double pRMin,
144  geom.get_cone_size_z(), // G4double pRMax,
145  geom.get_cone_size_z(), // G4double pDz,
146  pi / 2 - pi / geom.get_N_RICH_Sector(), // G4double pSPhi,
147  2 * pi / geom.get_N_RICH_Sector() // G4double pDPhi
148  );
149 
150  G4VSolid *RICHSphereBoundary = new G4SubtractionSolid("RICHSphereBoundary",
151  RICHOutSphereBoundary_place, RICHInnerSphereBoundary_place);
152  // G4VSolid *RICHSecBox_ConeSphere = new G4IntersectionSolid(
153  // "RICHSecBox_ConeSphere", RICHSphereBoundary,
154  // RICHConeBoundary_place);
155  G4VSolid *RICHSecBox_ConeSec = new G4IntersectionSolid("RICHSecBox_ConeSec",
156  RICHSecBoundary, RICHConeBoundary_place);
157 
158  // RICH sector
159  G4VSolid *RICHSecBox = new G4IntersectionSolid("RICHSecBox",
160  RICHSecBox_ConeSec, RICHSphereBoundary);
161 
162  G4LogicalVolume *RICHSecLog = new G4LogicalVolume(RICHSecBox,
163  GetDetectorMaterial(geom.get_RICH_gas_mat()), "RICHSecLogical",
164  0, 0, 0);
165  RegisterLogicalVolume(RICHSecLog);
166 
167  for (G4int sec = 0; sec < geom.get_N_RICH_Sector(); sec++)
168  {
169  G4RotateZ3D sec_rot(2 * pi / geom.get_N_RICH_Sector() * sec);
170 
171  // Insert sector volumes into sector set
172  sector_vec.insert(RegisterPhysicalVolume(new G4PVPlacement(sec_rot, RICHSecLog, "RICHSecPhysical", WorldLog,
173  false, sec, overlapcheck_rich)));
174  }
175  // CLHEP::HepRotationZ sec_rot(0);
176  // G4RotationMatrix g4_sec_rot(sec_rot);
177  // new G4PVPlacement(transform1, "RICHSecPhysical", RICHSecLog, WorldPhys,
178  // false, 0);
179 
180  //RICH mirror
181  // LHCb website: 3mm thick Be base + 0.3mm glass surface layer coated with Al.
182  // LHCb TDR: The mirrors are made of polished 6mm-thick glass coated by vacuum
183  // deposition with 900 nm of aluminium and overcoated with 200 nm of quartz.
184  G4VSolid *RICHMirrorSphereBoundary = new G4Sphere("RICHMirrorSphereBoundary", //
186  geom.get_R_mirror_ref() + geom.get_dR_mirror(), // G4double pRmin, G4double pRmax,
187  0, 2 * pi, // G4double pSPhi, G4double pDPhi,
188  0, pi // G4double pSTheta, G4double pDTheta
189  );
190  G4VSolid *RICHMirrorSphereBoundary_place = new G4DisplacedSolid("RICHMirrorSphereBoundary_place", RICHMirrorSphereBoundary, 0,
191  G4ThreeVector(0, geom.get_R_shift(), geom.get_z_shift()));
192  G4VSolid *RICHMirror = new G4IntersectionSolid("RICHMirror",
193  RICHSecBox_ConeSec, RICHMirrorSphereBoundary_place);
194  G4LogicalVolume *RICHMirrorLog = new G4LogicalVolume(RICHMirror,
196  "RICHMirrorLog");
197  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(), RICHMirrorLog, "RICHMirrorPhysical",
198  RICHSecLog, false, 0, overlapcheck_rich));
199  RegisterLogicalVolume(RICHMirrorLog);
200 
201  // RICH mirror Optical Surface
202  //
203  G4LogicalSkinSurface *RICHMirrorSurface = new G4LogicalSkinSurface("RICHMirrorSurface",
204  RICHMirrorLog,
206  RICHMirrorSurface->GetName(); // only to avoid error message for unused object
207 
208  //RICH gas vessel window - back
209  //LHCb TDR: The frame will be sealed to contain the C4F10 gas radiator. The vacuum chamber acts as part of the boundary to the gas volume.
210  // Kapton foils of 150um thickness and 400 mm diameter will be glued to flanges on the vacuum chamber
211  G4VSolid *RICHBackWindowSphereBoundary = new G4Sphere("RICHBackWindowSphereBoundary", //
213  geom.get_R_mirror_ref() + geom.get_dR_mirror() + geom.get_dR_mirror_spt() + geom.get_dR_backwindow(), // G4double pRmin, G4double pRmax,
214  0, 2 * pi, // G4double pSPhi, G4double pDPhi,
215  0, pi // G4double pSTheta, G4double pDTheta
216  );
217  G4VSolid *RICHBackWindowSphereBoundary_place = new G4DisplacedSolid("RICHBackWindowSphereBoundary_place", RICHBackWindowSphereBoundary,
218  0, G4ThreeVector(0, geom.get_R_shift(), geom.get_z_shift()));
219  G4VSolid *RICHBackWindow = new G4IntersectionSolid("RICHBackWindow",
220  RICHSecBox_ConeSec, RICHBackWindowSphereBoundary_place);
221  G4LogicalVolume *RICHBackWindowLog = new G4LogicalVolume(RICHBackWindow,
223  "RICHBackWindowLog");
224  RegisterLogicalVolume(RICHBackWindowLog);
225  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(), RICHBackWindowLog,
226  "RICHBackWindowPhysical", RICHSecLog, false, 0, overlapcheck_rich));
227 
228  //RICH gas vessel window - front
229  //LHCb TDR: The frame will be sealed to contain the C4F10 gas radiator. The vacuum chamber acts as part of the boundary to the gas volume.
230  // Kapton foils of 150um thickness and 400 mm diameter will be glued to flanges on the vacuum chamber
231  G4VSolid *RICHFrontWindowSphereBoundary = new G4Sphere("RICHFrontWindowSphereBoundary", //
233  geom.get_R_frontwindow() + geom.get_dR_frontwindow(), // G4double pRmin, G4double pRmax,
234  0, 2 * pi, // G4double pSPhi, G4double pDPhi,
235  0, pi // G4double pSTheta, G4double pDTheta
236  );
237  G4VSolid *RICHFrontWindowSphereBoundary_place = new G4DisplacedSolid("RICHFrontWindowSphereBoundary_place",
238  RICHFrontWindowSphereBoundary,
239  0,
240  G4ThreeVector(0,
243  G4VSolid *RICHFrontWindow = new G4IntersectionSolid("RICHFrontWindow",
244  RICHSecBox_ConeSec, RICHFrontWindowSphereBoundary_place);
245  G4LogicalVolume *RICHFrontWindowLog = new G4LogicalVolume(RICHFrontWindow,
247  "RICHFrontWindowLog");
248  RegisterLogicalVolume(RICHFrontWindowLog);
249  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(), RICHFrontWindowLog,
250  "RICHFrontWindowPhysical", RICHSecLog, false, 0, overlapcheck_rich));
251 
252  // photon detector - HBD
253  G4LogicalVolume *RICHHBDLog = Construct_HBD(RICHSecLog);
254 
255  GetDisplayAction()->AddVolume(RICHSecLog, "Sector");
256 
257  GetDisplayAction()->AddVolume(RICHMirrorLog, "Mirror");
258 
259  GetDisplayAction()->AddVolume(RICHBackWindowLog, "Window");
260  GetDisplayAction()->AddVolume(RICHFrontWindowLog, "Window");
261 
262  GetDisplayAction()->AddVolume(RICHHBDLog, "HBD");
263 
264 // if you want this printout - put some verbosity around it
265  // std::cout << "ePHENIXRICHConstruction::Construct_RICH - " << map_log_vol.size()
266  // << " logical volume constructed" << std::endl;
267  // std::cout << "ePHENIXRICHConstruction::Construct_RICH - " << map_phy_vol.size()
268  // << " physical volume constructed" << std::endl;
269 
270  return WorldLog;
271 }
272 
273 G4LogicalVolume *
274 ePHENIXRICHConstruction::Construct_HBD(G4LogicalVolume *RICHSecLog)
275 {
276  const double HBD_thickness = geom.get_HBD_thickness();
277  const int n_GEM_layers = geom.get_n_GEM_layers();
278 
279  assert(
280  HBD_thickness < geom.get_dR_frontwindow_shrink() - geom.get_dR_frontwindow());
281  // depth check
282 
283  G4VSolid *RICHHBDBox = new G4Cons("RICHHBDBox", //
284  0, geom.get_RZ_Seg1_HBD() + geom.get_RZ_Seg2_HBD(), // G4double pRmin1, G4double pRmax1,
285  0, geom.get_RZ_Seg1_HBD() + geom.get_RZ_Seg2_HBD(), // G4double pRmin2, G4double pRmax2,
286  HBD_thickness / 2, // G4double pDz,
287  -geom.get_half_angle_HBD() + pi / 2, 2 * geom.get_half_angle_HBD() // G4double pSPhi, G4double pDPhi
288  );
289 
290  G4LogicalVolume *RICHHBDLog = new G4LogicalVolume(RICHHBDBox,
291  GetDetectorMaterial(geom.get_RICH_gas_mat()), "RICHHBDLog");
292  RegisterLogicalVolume(RICHHBDLog);
293 
294  G4Transform3D transform1 = G4Translate3D(0, geom.get_R_Tip_HBD(),
295  geom.get_Z_Tip_HBD()) *
296  G4RotateX3D(-geom.get_Rotation_HBD()) * G4RotateY3D(pi) * G4TranslateZ3D(HBD_thickness / 2);
297  // G4Transform3D transform1 = G4TranslateZ3D(HBD_thickness / 2);
298 
299  RegisterPhysicalVolume(new G4PVPlacement(transform1, RICHHBDLog, "RICHHBDPhysical", RICHSecLog,
300  false, 0, overlapcheck_rich));
301 
302  // Internal HBD structure
303  // From doi:10.1016/j.nima.2011.04.015
304  // Component Material X0 (cm) Thickness (cm) Area (%) Rad. Length (%)
305  double current_z = -HBD_thickness / 2;
306 
307  // Mesh SS 1.67 0.003 11.5 0.021
308  // exclude for now to let all potons pass to the top GEM foil
309  //G4LogicalVolume* HBDMeshLog = Construct_HBD_Layers(RICHHBDLog, "Mesh", "Steel", current_z,
310  // 0.003 * cm * 11.5e-2);
311  current_z += 0.003 * cm;
312 
313  // photon detector - photocathode is CsI coating on top layer (surface)
314  //
315  G4LogicalSkinSurface *RICHPhotocathodeSurface;
316 
317  // GEM frames FR4 17.1 0.15x4 6.5 0.228 ; 6.5 is the percentage of the area covered by material.
318  // exclude for now to let all potons pass to the top GEM foil
319  //Construct_HBD_Layers(RICHHBDLog, "Frame0", "G10", current_z,
320  // 0.15 * cm * 6.5e-2);
321  current_z += 0.15 * cm;
322 
323  for (int gem = 1; gem <= n_GEM_layers; gem++)
324  {
325  stringstream sid;
326  sid << gem;
327 
328  // GEM Copper 1.43 0.0005x6 64 0.134
329  G4LogicalVolume *GemTopLog = Construct_HBD_Layers(RICHHBDLog,
330  G4String("GEMFrontCu") + G4String(sid.str()), "G4_Cu",
331  current_z, 0.0005 * cm * 64e-2);
332  current_z += 0.0005 * cm;
333 
334  // top GEM has CsI coating for photon detection
335  if (gem == 1)
336  {
337  RICHPhotocathodeSurface = new G4LogicalSkinSurface("RICHPhotocathodeSurface", GemTopLog, geom.get_RICH_Photocathode_OpticalSurface());
338  RICHPhotocathodeSurface->GetName(); // avoid error due to unused object
339  }
340 
341  // GEM Kapton 28.6 0.005x3 64 0.034
342  Construct_HBD_Layers(RICHHBDLog,
343  G4String("GEMKapton") + G4String(sid.str()), "G4_KAPTON",
344  current_z, 0.005 * cm * 64e-2);
345  current_z += 0.005 * cm;
346 
347  // GEM Copper 1.43 0.0005x6 64 0.134
348  Construct_HBD_Layers(RICHHBDLog,
349  G4String("GEMBackCu") + G4String(sid.str()), "G4_Cu", current_z,
350  0.0005 * cm * 64e-2);
351  current_z += 0.0005 * cm;
352 
353  // GEM frames FR4 17.1 0.15x4 6.5 0.228
354  Construct_HBD_Layers(RICHHBDLog,
355  G4String("Frame") + G4String(sid.str()), "G10", current_z,
356  0.15 * cm * 6.5e-2);
357  current_z += 0.15 * cm;
358  }
359 
360  // PCB Kapton 28.6 0.005 100 0.017
361  Construct_HBD_Layers(RICHHBDLog, G4String("PCBKapton"), "G4_KAPTON",
362  current_z, 0.005 * cm * 100e-2);
363  current_z += 0.005 * cm;
364 
365  // PCB Copper 1.43 0.0005 80 0.028
366  Construct_HBD_Layers(RICHHBDLog, G4String("PCBCu"), "G4_Cu", current_z,
367  0.0005 * cm * 80e-2);
368  current_z += 0.0005 * cm;
369 
370  // Facesheet FR4 17.1 0.025x2 100 0.292
371  Construct_HBD_Layers(RICHHBDLog, "Facesheet", "G10", current_z,
372  0.025 * 2 * cm * 100e-2);
373  current_z += 0.025 * 2 * cm;
374 
375  // Panel core Honeycomb 8170 1.905 100 0.023 <- very thin-X0 stuff, ignore
376 
377  // Total vessel 0.82
378  // Readout
379  // Readout board FR4/copper 17.1/1.43 0.05/0.001 100 0.367
380  Construct_HBD_Layers(RICHHBDLog, G4String("ReadoutFR4"), "G10", current_z,
381  0.05 * cm * 100e-2);
382  current_z += 0.05 * cm;
383  Construct_HBD_Layers(RICHHBDLog, G4String("ReadoutCu"), "G4_Cu", current_z,
384  0.001 * cm * 100e-2);
385  current_z += 0.001 * cm;
386 
387  // Preamps + sockets Copper 1.43 0.0005 100 0.66
388  // Total readout 1.03
389  Construct_HBD_Layers(RICHHBDLog, G4String("SocketsCu"), "G4_Cu", current_z,
390  0.0005 * cm * 100e-2);
391  current_z += 0.0005 * cm;
392 
393  assert(current_z < HBD_thickness / 2);
394  //boundary check
395 
396  return RICHHBDLog;
397 }
398 
399 G4LogicalVolume *
401  const G4String name, const G4String material, const double start_z,
402  const double thickness)
403 {
404  G4VSolid *box = new G4Cons(G4String("RICHHBD") + name + G4String("Box"), //
405  0, geom.get_RZ_Seg1_HBD() + geom.get_RZ_Seg2_HBD(), // G4double pRmin1, G4double pRmax1,
406  0, geom.get_RZ_Seg1_HBD() + geom.get_RZ_Seg2_HBD(), // G4double pRmin2, G4double pRmax2,
407  thickness / 2, // G4double pDz,
408  -geom.get_half_angle_HBD() + pi / 2, 2 * geom.get_half_angle_HBD() // G4double pSPhi, G4double pDPhi
409  );
410 
411  G4LogicalVolume *Log = new G4LogicalVolume(box,
412  GetDetectorMaterial(material), //
413  G4String("RICHHBD") + name + G4String("Log"));
415 
416  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, start_z + thickness / 2), Log,
417  G4String("RICHHBD") + name + G4String("Physical"), RICHHBDLog,
418  false, 0, overlapcheck_rich));
419 
420  return Log;
421 }
422 
424 {
425  N_RICH_Sector = 8;
426  min_eta = 1;
427  R_beam_pipe_front = 3 * cm;
428  R_beam_pipe_back = 3 * cm;
429  z_shift = 100 * cm;
430  R_shift = 40 * cm;
431  frontwindow_DisplaceRatio = .85; // Displace R,Z and radius simultainously
433  R_mirror_ref = 200 * cm;
434  dR_mirror = 0.6 * cm;
435  dR_mirror_spt = 1.4 * cm;
436  dR_backwindow = 150 * um;
437  dR_frontwindow = 150 * um;
438 
439  HBD_thickness = 1.5 * cm;
440  n_GEM_layers = 5;
441 
442  RICH_gas_mat = "CF4";
443  RICH_Mirror_mat = "G4_Pyrex_Glass";
444  RICH_Gas_Window_mat = "G4_KAPTON";
445 }
446 
448 {
449  // Mirror
450  //
452  RICH_Mirror_OpticalSurface = new G4OpticalSurface("RICHMirrorSurfaceOptical");
453 
454  const G4int NUM = 2;
455 
456  G4double pp[NUM] = {2.038 * eV, 4.144 * eV};
457  G4double rindex[NUM] = {1.4, 1.4};
458  G4double reflectivity[NUM] = {1.0, 1.0};
459  G4double efficiency[NUM] = {0.0, 0.0};
460 
461  G4MaterialPropertiesTable *RICH_Mirror_OpticalSurface_SMPT = new G4MaterialPropertiesTable();
462 
463  RICH_Mirror_OpticalSurface_SMPT->AddProperty("RINDEX", pp, rindex, NUM);
464  RICH_Mirror_OpticalSurface_SMPT->AddProperty("REFLECTIVITY", pp, reflectivity, NUM);
465  RICH_Mirror_OpticalSurface_SMPT->AddProperty("EFFICIENCY", pp, efficiency, NUM);
466 
467  RICH_Mirror_OpticalSurface->SetType(dielectric_metal);
468  RICH_Mirror_OpticalSurface->SetModel(glisur);
469  RICH_Mirror_OpticalSurface->SetFinish(polished);
470 
471  // Photocathode
472  //
473  RICH_Photocathode_OpticalSurface = new G4OpticalSurface("RICH_Photocathode_OpticalSurface", glisur, polished, dielectric_metal);
474 
475  G4double photocath_EPHOTON[2] = {1., 1000.};
476  G4double photocath_EFF[2] = {1., 1.};
477  G4double photocath_REFL[2] = {0., 0.};
478 
479  G4MaterialPropertiesTable *RICH_Photocathode_OpticalSurface_MPT = new G4MaterialPropertiesTable();
480  RICH_Photocathode_OpticalSurface_MPT->AddProperty("EFFICIENCY", photocath_EPHOTON, photocath_EFF, 2);
481  RICH_Photocathode_OpticalSurface_MPT->AddProperty("REFLECTIVITY", photocath_EPHOTON, photocath_REFL, 2);
482  RICH_Photocathode_OpticalSurface->SetMaterialPropertiesTable(RICH_Photocathode_OpticalSurface_MPT);
483 
484  // done
485  //
486  return;
487 }
488 
490 {
492 }
493 
495 {
496  return atan(
497  tan(pi / N_RICH_Sector) / sqrt(1 + R_shift * R_shift / z_shift / z_shift));
498 }
499 
501 {
502  return R_shift * (R_mirror_ref + 2 * sqrt(z_shift * z_shift + R_shift * R_shift)) / 4 / z_shift;
503 }
504 
506 {
507  return ((R_mirror_ref + 2 * sqrt(pow(z_shift, 2) + pow(R_shift, 2))) * tan(2 * atan(exp(-min_eta)) - atan(R_shift / z_shift))) / 4.;
508 }
509 
511 {
512  const double l = sqrt(z_shift * z_shift + R_shift * R_shift) + R_mirror_ref / 2;
513 
514  return l * sin(get_Rotation_HBD()) - get_RZ_Seg1_HBD() * cos(get_Rotation_HBD());
515 }
516 
518 {
519  const double l = sqrt(z_shift * z_shift + R_shift * R_shift) + R_mirror_ref / 2;
520 
521  return l * cos(get_Rotation_HBD()) + get_RZ_Seg1_HBD() * sin(get_Rotation_HBD());
522 }
523 
525 {
526  return atan(R_shift / z_shift);
527 }
528 
529 int ePHENIXRICHConstruction::is_in_sector(G4VPhysicalVolume *volume) const
530 {
531  if (sector_vec.find(volume) != sector_vec.end())
532  return volume->GetCopyNo();
533  else
534  return -1;
535 }
536 
537 
538 G4Material *ePHENIXRICHConstruction::GetDetectorMaterial(const std::string &name, const bool quit)
539 {
540  G4Material *thismaterial = G4Material::GetMaterial(name,false);
541  if (thismaterial)
542  {
543  return thismaterial;
544  }
545  thismaterial = G4NistManager::Instance()->FindOrBuildMaterial(name);
546  if (!thismaterial)
547  {
548  if (!quit)
549  {
550  return nullptr;
551  }
552  std::cout << "PHG4Detector::GetDetectorMaterial: Could not locate " << name << " in NIST DB or create it" << std::endl;
553  std::cout << boost::stacktrace::stacktrace();
554  std::cout << std::endl;
555  std::cout << "read the above stack trace who is calling this material" << std::endl;
556  gSystem->Exit(1);
557  exit(1); // so coverity gets it
558  }
559  return thismaterial;
560 }
561