EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4mRICHDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4mRICHDetector.cc
1 /*===============================================================*
2  * March 2nd 2017 *
3  * mRICH Detector created by Cheuk-Ping Wong @GSU *
4  *===============================================================*
5  * Even mRICH is a tiny detector, it has nine logical volumes per*
6  * modules. To make the code easy to manage, material definition *
7  * and components dimensions are written in different functions *
8  * which are not supposed for frequent modification. *
9  * *
10  * While Construct() and Construct_a_mRIHC(), are two *
11  * handy and simple functions for user to control detector *
12  * construction. *
13  *---------------------------------------------------------------*
14  * to ignore a particular component of a single mRICH, comment *
15  * out the build_xxx() function correspond to the component. *
16  *---------------------------------------------------------------*
17  * Materials are defined in gmain/PHG4Reco::DefineMaterials *
18  *===============================================================*/
19 #include "PHG4mRICHDetector.h"
20 
21 #include <phparameter/PHParameters.h>
22 
23 #include <fun4all/Fun4AllBase.h>
24 
25 #include <g4main/PHG4Detector.h> // for PHG4Detector
26 
27 #include <Geant4/G4AssemblyVolume.hh>
28 #include <Geant4/G4Box.hh>
29 #include <Geant4/G4LogicalBorderSurface.hh>
30 #include <Geant4/G4LogicalVolume.hh>
31 #include <Geant4/G4Material.hh>
32 #include <Geant4/G4MaterialPropertiesTable.hh> // for G4MaterialProperties...
33 #include <Geant4/G4OpticalSurface.hh>
34 #include <Geant4/G4PVPlacement.hh>
35 #include <Geant4/G4PhysicalConstants.hh>
36 #include <Geant4/G4Polycone.hh>
37 #include <Geant4/G4Polyhedra.hh>
38 #include <Geant4/G4RotationMatrix.hh>
39 #include <Geant4/G4SurfaceProperty.hh> // for dielectric_dielectric
40 #include <Geant4/G4SystemOfUnits.hh>
41 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
42 #include <Geant4/G4Types.hh> // for G4double, G4int
43 #include <Geant4/G4VPhysicalVolume.hh>
44 #include <Geant4/G4VisAttributes.hh>
45 #include <Geant4/G4ios.hh> // for G4cout, G4endl
46 
47 #include <algorithm> // for fill, max
48 #include <cmath> // for floor, sqrt, acos, asin
49 #include <cstdio>
50 #include <iostream> // for operator<<, basic_os...
51 #include <iterator> // for begin, end
52 #include <string>
53 
54 class PHCompositeNode;
55 
56 using namespace CLHEP;
57 
58 //_______________________________________________________________
59 PHG4mRICHDetector::PHG4mRICHDetector(PHG4Subsystem* subsys, PHCompositeNode* Node, PHParameters* parameters, const std::string& dnam, const int lyr)
60  : PHG4Detector(subsys, Node, dnam)
61  , params(parameters)
62  , layer(lyr)
63  , active(0)
64  , absorberactive(0)
65  , mRICH_PV(nullptr)
66  , sensor_PV{nullptr, nullptr, nullptr, nullptr}
67 {
68 }
69 
70 //_______________________________________________________________
71 int PHG4mRICHDetector::IsInmRICH(G4VPhysicalVolume* volume) const
72 {
73  if (active && sensor_vol.find(volume) != sensor_vol.end())
74  {
75  return SENSOR;
76  }
77 
78  if (active && aerogel_vol.find(volume) != aerogel_vol.end())
79  {
80  return AEROGEL;
81  }
82 
83  return INACTIVE;
84 }
85 //______________________________________________________________
86 void PHG4mRICHDetector::ConstructMe(G4LogicalVolume* logicWorld)
87 {
88  int subsystemSetup = params->get_int_param("subsystemSetup");
89  // -1: single module
90  // 0: h-side sectors and e-side wall
91  // 1: h-side sectors
92  // 2: e-side wall
93  // 3: h-side wall
94  // 4: h-side wall and e-side wall
95 
96  if (subsystemSetup == DetectorSetUp::kSingle_Modular) Construct_a_mRICH(logicWorld);
97  if (subsystemSetup == DetectorSetUp::kHSector_EWall)
98  {
99  build_mRICH_sector(logicWorld, 8);
100  build_mRICH_wall_eside(logicWorld);
101  }
102  if (subsystemSetup == DetectorSetUp::kHSector) build_mRICH_sector(logicWorld, 8);
103  if (subsystemSetup == DetectorSetUp::kEWall) build_mRICH_wall_eside(logicWorld);
104  if (subsystemSetup == DetectorSetUp::kEWall_proj) build_mRICH_wall_eside_proj(logicWorld);
105  if (subsystemSetup == DetectorSetUp::kHWall) build_mRICH_wall_hside(logicWorld);
106  if (subsystemSetup == DetectorSetUp::kHWall_EWall)
107  {
108  build_mRICH_wall_hside(logicWorld);
109  build_mRICH_wall_eside(logicWorld);
110  }
111  if (subsystemSetup == DetectorSetUp::kHWall_Barrel)
112  {
113  build_mRICH_sector2(logicWorld, 8);
114  }
115 }
116 //_______________________________________________________________
117 G4LogicalVolume* PHG4mRICHDetector::Construct_a_mRICH(G4LogicalVolume* logicWorld) //, int detectorSetup )
118 {
119  int detectorSetup = params->get_int_param("detectorSetup");
120 
121  mRichParameter* parameters = new mRichParameter();
122 
123  //--------------------------- skeleton setup ---------------------------//
124  /*holder box and hollow volume*/ G4VPhysicalVolume* hollowVol = build_holderBox(parameters, logicWorld);
125  /*aerogel */ build_aerogel(parameters, hollowVol);
126  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << ": build_aerogel" << std::endl;
127 
128  /*sensor plane */ build_sensor(parameters, hollowVol->GetLogicalVolume());
129 
130  //-------------------------- for full set up ---------------------------//
131  if (detectorSetup)
132  { //for full setup
133  /*foam holder for aerogel */ build_foamHolder(parameters, hollowVol->GetLogicalVolume());
134  /*lens */ build_lens(parameters->GetLensPar("fresnelLens"), hollowVol->GetLogicalVolume());
135  /*mirror */ build_mirror(parameters, hollowVol);
136  /*readout electronics */ G4VPhysicalVolume* pol = build_polyhedra(parameters->GetPolyPar("readout"), hollowVol->GetLogicalVolume());
137  if (!pol)
138  {
139  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << ": readout electronics not placed" << std::endl;
140  }
141  }
142 
143  return hollowVol->GetMotherLogical(); //return detector holder box.
144  //you have more than 1 daugthers,
145  //but you can only have one mother.
146 }
147 
148 //________________________________________________________________________//
150 {
151  std::fill(std::begin(halfXYZ), std::end(halfXYZ), (G4double) 0 * mm);
152  pos = G4ThreeVector(0 * mm, 0 * mm, 0 * mm);
153  material = GetDetectorMaterial("G4_AIR");
154  sensitivity = 0;
155 
156  color = G4Colour(0, 0, 0, 0);
157  visibility = false;
158  wireframe = false;
159  surface = false;
160 }
161 //________________________________________________________________________//
163 //________________________________________________________________________//
165  : name("")
166  , pos(G4ThreeVector(0 * mm, 0 * mm, 0 * mm))
167  , start(0.)
168  , theta(0.)
169  , numSide(0)
170  , num_zLayer(0)
171  , material(GetDetectorMaterial("G4_AIR"))
172  , sensitivity(0)
173  , color(G4Colour(0, 0, 0, 0))
174  , visibility(false)
175  , wireframe(false)
177 {
178  std::fill(std::begin(z), std::end(z), (G4double) 0 * mm);
179  std::fill(std::begin(rinner), std::end(rinner), (G4double) 0 * mm);
180  std::fill(std::begin(router), std::end(router), (G4double) 0 * mm);
181 }
182 //________________________________________________________________________//
184  : name("")
185  , n(0.)
186  , f(0.)
187  , diameter(0.)
188  , eff_diameter(0.)
189  , centerThickness(0.)
190  , grooveWidth(0.)
191  , pos(G4ThreeVector(0 * mm, 0 * mm, 0 * mm))
192  , material(GetDetectorMaterial("G4_AIR"))
193  , sensitivity(0.)
194  , color(G4Colour(0, 0, 0, 0))
195  , visibility(false)
196  , wireframe(false)
197  , surface(false)
198 
199 {
200  std::fill(std::begin(halfXYZ), std::end(halfXYZ), (G4double) 0 * mm);
201 }
202 //________________________________________________________________________//
203 void PHG4mRICHDetector::LensPar::Set_halfXYZ(G4double halfX, G4double grooveDensity)
204 {
205  halfXYZ[0] = halfX;
206  halfXYZ[1] = halfXYZ[0];
207 
208  G4double NumberOfGrooves = floor(grooveDensity * (eff_diameter / 2.0));
209  G4double Rmin1 = (NumberOfGrooves - 1) * (grooveWidth);
210  G4double Rmax1 = (NumberOfGrooves - 0) * (grooveWidth);
211  halfXYZ[2] = (GetSagita(Rmax1) - GetSagita(Rmin1) + centerThickness) / 2.0;
212 }
213 //________________________________________________________________________//
215 {
216  G4double Conic = -1.0; // original:
217  //G4int lens_type = 3;
218  G4int lens_type = 5;
219  G4double Curvature;
220  G4double Aspher[8] = {0, 0, 0, 0, 0, 0, 0, 0};
221 
222  if (lens_type == 1)
223  {
224  Curvature = 0.00437636761488 / mm;
225  Aspher[0] = 4.206739256e-05 / (mm);
226  Aspher[1] = 9.6440152e-10 / (mm3);
227  Aspher[2] = -1.4884317e-15 / (mm2 * mm3);
228  }
229  else if (lens_type == 2)
230  {
231  Curvature = 0.0132 / mm; // r=77mm, f~14cm
232  Aspher[0] = 32.0e-05 / (mm);
233  Aspher[1] = -2.0e-7 / (mm3);
234  Aspher[2] = 1.2e-13 / (mm2 * mm3);
235  }
236  else if (lens_type == 3)
237  {
238  Curvature = 0.0150 / mm; // r=77mm, f~12.5cm
239  Aspher[0] = 42.0e-05 / (mm);
240  Aspher[1] = -3.0e-7 / (mm3);
241  Aspher[2] = 1.2e-13 / (mm2 * mm3);
242  }
243  else if (lens_type == 4)
244  {
245  Curvature = 0.0175 / mm; // r=77mm, f~10cm
246  Aspher[0] = 72.0e-05 / (mm);
247  Aspher[1] = -5.0e-7 / (mm3);
248  Aspher[2] = 1.2e-13 / (mm2 * mm3);
249  }
250  else if (lens_type == 5)
251  {
252  Curvature = 1 / (f * (n - 1));
253  }
254 
255  G4double TotAspher = 0.0 * mm;
256  for (G4int k = 1; k < 9; k++)
257  {
258  TotAspher += Aspher[k - 1] * std::pow(r, 2 * k);
259  }
260 
261  G4double ArgSqrt = 1.0 - (1.0 + Conic) * std::pow(Curvature, 2) * std::pow(r, 2); // note conic=-1, so ArgSqrt = 1.0
262  /*
263  if (ArgSqrt < 0.0)
264  {
265  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << "UltraFresnelLensParameterisation::Sagita: Square Root of <0 !" << std::endl;
266  }
267  */
268  G4double Sagita_value = Curvature * std::pow(r, 2) / (1.0 + std::sqrt(ArgSqrt)) + TotAspher;
269  return Sagita_value;
270 }
271 
272 //________________________________________________________________________//
274 {
275  int i;
276  //----------
277  // Constant
278  //----------
279  //if (Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) std::cout << __FILE__ << "::" << __func__ << " Using the local code " << std::endl;
280 
281  const double myPI = 4 * atan(1);
282  fresnelLens = new LensPar();
283  holderBox = new BoxPar();
284  hollowVolume = new BoxPar();
285  foamHolderBox = new BoxPar();
286  foamHolderPoly = new PolyPar();
287  aerogel = new BoxPar();
288  mirror = new PolyPar();
289  glassWindow = new BoxPar();
290  sensor = new BoxPar();
291  readout = new PolyPar();
292 
293  //--------------------Holder box key parameters-----------------------------//
294  const G4double BoxDelz = 2.0 * mm; // extract space between components
295  const G4double box_thicknessXYZ[4] = {0.1 * cm, 0.1 * cm, 0.1 * cm, 0.1 * cm};
296 
297  //------------------------- Aerogel gel key parameters---------------------//
298  const G4double foamHolderThicknessXYZ[3] = {0.2 * cm, 0.2 * cm, 0.2 * cm};
299  const G4double agel_halfXYZ[3] = {6.325 * cm, 6.325 * cm, 1.50 * cm};
300 
301  //------------------------Fresnel lens key parameters----------------------//
302  const G4double lens_gap = (2.54 / 8.0) * cm; //gap between agel and lens, and between lens and mirror
303 
304  const G4double lensHalfx = (5.25 / 2.0) * 2.54 * cm;
305  const G4double grooveDensity = 125.0 / (2.54 * cm);
306 
307  fresnelLens->n = 1.49;
308  fresnelLens->f = 6.0 * 2.54 * cm;
309  fresnelLens->eff_diameter = 15.24 * cm;
310  fresnelLens->diameter = 2.0 * sqrt(2.0) * lensHalfx;
311  fresnelLens->centerThickness = 0.068 * 2.54 * cm;
312  fresnelLens->grooveWidth = (G4double) 1.0 / grooveDensity;
313  fresnelLens->Set_halfXYZ(lensHalfx, grooveDensity);
314  //rest of lens parameters are set below
315 
316  //---------------------------Photodetector key parameters-------------------//
317  const G4double sensorGap = 0.2 * cm; //half width of the gap
318  const G4double glassWindow_halfXYZ[3] = {5.18 / 2.0 * cm, 5.18 / 2.0 * cm, 0.075 * cm};
319  const G4double phodet_halfXYZ[3] = {2.425 * cm, 2.425 * cm, 0.075 * cm};
320 
321  //--------------------------- mirror key parameters ------------------------//
322  const G4double mirrorThickness = 0.2 * cm;
323 
324  //-----------------------Readout Electronics key parameters-----------------//
325  const G4double readout_halfz = 0.4 * cm; //redendunt?
326  const G4double readoutThickness = 0.2 * cm;
327 
328  //----------
329  // calculation
330  //----------
331  G4double sensor_total_halfx = 2 * glassWindow_halfXYZ[0] + sensorGap;
332 
333  G4double foamHolder_halfXYZ[3];
334  foamHolder_halfXYZ[0] = agel_halfXYZ[0] + foamHolderThicknessXYZ[0];
335  foamHolder_halfXYZ[1] = foamHolder_halfXYZ[0];
336  foamHolder_halfXYZ[2] = foamHolderThicknessXYZ[2] / 2.0;
337 
338  G4double acrylicBox_halfXYZ[3];
339  acrylicBox_halfXYZ[0] = std::max(std::max(foamHolder_halfXYZ[0], sensor_total_halfx + readoutThickness), fresnelLens->halfXYZ[0]) + 0.1 * cm + box_thicknessXYZ[0];
340  acrylicBox_halfXYZ[1] = acrylicBox_halfXYZ[0];
341  acrylicBox_halfXYZ[2] = (BoxDelz + 2 * foamHolder_halfXYZ[2] + 2 * agel_halfXYZ[2] +
342  lens_gap + 2 * fresnelLens->halfXYZ[2] + fresnelLens->f + 2 * glassWindow_halfXYZ[2] +
343  2 * phodet_halfXYZ[2] + (2 * readout_halfz + BoxDelz) + box_thicknessXYZ[2] + box_thicknessXYZ[3]) /
344  2.0;
345 
346  G4double hollow_halfXYZ[3];
347  hollow_halfXYZ[0] = acrylicBox_halfXYZ[0] - box_thicknessXYZ[0];
348  hollow_halfXYZ[1] = hollow_halfXYZ[0];
349  hollow_halfXYZ[2] = (2 * acrylicBox_halfXYZ[2] - box_thicknessXYZ[2] - box_thicknessXYZ[3]) / 2.0;
350 
351  G4ThreeVector hollow_pos = G4ThreeVector(0.0 * cm, 0.0 * cm, -acrylicBox_halfXYZ[2] + hollow_halfXYZ[2] + box_thicknessXYZ[2]);
352 
353  G4double foamHolder_posz = -hollow_halfXYZ[2] + BoxDelz + foamHolder_halfXYZ[2];
354  G4double agel_posz = foamHolder_posz + foamHolder_halfXYZ[2] + agel_halfXYZ[2];
355 
356  G4double lens_z = agel_posz + agel_halfXYZ[2] + fresnelLens->halfXYZ[2] + lens_gap;
357 
358  G4double glassWindow_z = lens_z - fresnelLens->halfXYZ[2] + fresnelLens->f + glassWindow_halfXYZ[2] - 16.; //out of focus. 16 mm closer to the lens is the optimal position of the censor
359  G4double phodet_z = glassWindow_z + glassWindow_halfXYZ[2] + phodet_halfXYZ[2];
360 
361  //redendunt:
362  G4double readout_z[2];
363  readout_z[0] = glassWindow_z - glassWindow_halfXYZ[2];
364  readout_z[1] = phodet_z + phodet_halfXYZ[2];
365 
366  //----------
367  // set holderBox
368  //----------
369  // holderBox->name="HolderBox";
370  holderBox->name = "mRICH_module";
371  for (i = 0; i < 3; i++) holderBox->halfXYZ[i] = acrylicBox_halfXYZ[i];
372  holderBox->pos = G4ThreeVector(0 * cm, 0 * cm, 0 * cm);
373  //holderBox->material=GetDetectorMaterial("G4_Al");
374  //holderBox->material=GetDetectorMaterial("CFRP_INTTxxxxx"); // carbon fiber
375  holderBox->material = GetDetectorMaterial("CFRP_INTT"); // carbon fiber
376  holderBox->sensitivity = 0;
377 
378  holderBox->color = G4Colour(0.0, 0.0, 0.0);
379  holderBox->visibility = true;
380  holderBox->wireframe = true;
381  holderBox->surface = false;
382 
383  //----------
384  // set HollowVolume
385  //----------
386  hollowVolume->name = "HollowVolume";
387  for (i = 0; i < 3; i++) hollowVolume->halfXYZ[i] = hollow_halfXYZ[i];
388  hollowVolume->pos = hollow_pos;
389  hollowVolume->material = GetDetectorMaterial("mRICH_Air_Opt");
390 
391  hollowVolume->sensitivity = 0;
392 
393  hollowVolume->color = G4Colour(0.0, 0.0, 0.0);
394  hollowVolume->visibility = true;
395  hollowVolume->wireframe = true;
396  hollowVolume->surface = false;
397 
398  //----------
399  // set FoamHolder_box
400  //----------
401  foamHolderBox->name = "FoamHolder";
402  for (i = 0; i < 3; i++) foamHolderBox->halfXYZ[i] = foamHolder_halfXYZ[i];
403  foamHolderBox->pos = G4ThreeVector(0.0 * cm, 0.0 * cm, foamHolder_posz);
404  foamHolderBox->material = GetDetectorMaterial("mRICH_Air_Opt");
405  foamHolderBox->sensitivity = 0;
406 
407  foamHolderBox->color = G4Colour(0.2, 0.498, 0.369);
408  foamHolderBox->visibility = true;
409  foamHolderBox->wireframe = true;
410  foamHolderBox->surface = false;
411 
412  //----------
413  // set FoamHolder_polyhedra
414  //----------
415  foamHolderPoly->name = "FoamHolder";
416  foamHolderPoly->pos = G4ThreeVector(0, 0, 0);
417  foamHolderPoly->start = 45.0 * myPI / 180.0;
418  foamHolderPoly->theta = 2 * myPI;
419  foamHolderPoly->numSide = 4;
420  foamHolderPoly->num_zLayer = 2;
421 
422  foamHolderPoly->z[0] = agel_posz - agel_halfXYZ[2]; //front of agel
423  foamHolderPoly->z[1] = agel_posz + agel_halfXYZ[2]; //back of sensor plane
424 
425  foamHolderPoly->rinner[0] = agel_halfXYZ[0];
426  foamHolderPoly->rinner[1] = agel_halfXYZ[0];
427 
428  foamHolderPoly->router[0] = foamHolderPoly->rinner[0] + foamHolderThicknessXYZ[0];
429  foamHolderPoly->router[1] = foamHolderPoly->rinner[1] + foamHolderThicknessXYZ[0];
430 
431  foamHolderPoly->material = GetDetectorMaterial("mRICH_Air_Opt");
432  foamHolderPoly->sensitivity = 0;
433 
434  foamHolderPoly->color = G4Colour(0.298, 0.6, 0.471);
435  foamHolderPoly->visibility = true;
436  foamHolderPoly->wireframe = true;
437  foamHolderPoly->surface = false;
438 
439  // /*
440  //----------
441  // set aerogel
442  //----------
443  aerogel->name = "Aerogel";
444  for (i = 0; i < 3; i++) aerogel->halfXYZ[i] = agel_halfXYZ[i];
445  aerogel->pos = G4ThreeVector(0, 0, agel_posz);
446  aerogel->material = GetDetectorMaterial("mRICH_Aerogel2");
447  aerogel->sensitivity = 0;
448  aerogel->color = G4Colour(1.0, 0.65, 0.0);
449  aerogel->visibility = true;
450  aerogel->wireframe = true;
451  aerogel->surface = false;
452 
453  //if (Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) std::cout << __FILE__ << "::" << __func__ << agel_posz<< "\t......55555.....\t" <<agel_halfXYZ[2] << std::endl;
454 
455  //*/
456  //----------
457  // set Fresnel lens
458  //----------
459  fresnelLens->name = "FresnelLens";
460  fresnelLens->pos = G4ThreeVector(0, 0, lens_z);
461  fresnelLens->material = GetDetectorMaterial("mRICH_Acrylic");
462  fresnelLens->sensitivity = 0;
463  fresnelLens->color = G4Colour(0.0, 1.0, 1.0);
464  fresnelLens->visibility = true;
465  fresnelLens->wireframe = true;
466  fresnelLens->surface = false;
467 
468  //----------
469  // set mirror
470  //----------
471  mirror->name = "mirror";
472  mirror->pos = G4ThreeVector(0, 0, 0);
473  mirror->start = 45.0 * myPI / 180.0;
474  mirror->theta = 2 * myPI;
475  mirror->numSide = 4;
476  mirror->num_zLayer = 2;
477 
478  mirror->z[0] = lens_z + fresnelLens->halfXYZ[2] + lens_gap; //back of lens+air gap
479  mirror->z[1] = glassWindow_z - glassWindow_halfXYZ[2]; //front of sensor plane
480 
481  mirror->rinner[0] = agel_halfXYZ[0];
482  mirror->rinner[1] = sensor_total_halfx;
483 
484  mirror->router[0] = mirror->rinner[0] + mirrorThickness;
485  mirror->router[1] = mirror->rinner[1] + mirrorThickness;
486 
487  mirror->material = GetDetectorMaterial("G4_Al");
488  mirror->sensitivity = 0;
489 
490  mirror->color = G4Colour(1.0, 1.0, 0.0);
491  mirror->visibility = true;
492  mirror->wireframe = true;
493 
494  //----------
495  // set glass window
496  //----------
497  glassWindow->name = "glassWindow";
498  for (i = 0; i < 3; i++) glassWindow->halfXYZ[i] = glassWindow_halfXYZ[i];
499  glassWindow->pos = G4ThreeVector(glassWindow_halfXYZ[0] + sensorGap, //the position of the first sensor module.
500  glassWindow_halfXYZ[0] + sensorGap, //the position of other sensor module will
501  glassWindow_z); //be set glass window position in another func.
502  glassWindow->material = GetDetectorMaterial("mRICH_Borosilicate");
503  glassWindow->sensitivity = 0;
504 
505  glassWindow->color = G4Colour(0.101, 0.737, 0.612);
506  glassWindow->visibility = true;
507  glassWindow->wireframe = true;
508  glassWindow->surface = false;
509 
510  //----------
511  // set sensor
512  //----------
513  sensor->name = "sensor";
514  for (i = 0; i < 3; i++) sensor->halfXYZ[i] = phodet_halfXYZ[i];
515  sensor->pos = G4ThreeVector(0, 0, phodet_z); //temporary. will be set in another func.
516  sensor->material = GetDetectorMaterial("mRICH_Air_Opt");
517  sensor->sensitivity = 0;
518 
519  sensor->color = G4Colour(0.0, 0.0, 0.63);
520  sensor->visibility = true;
521  sensor->wireframe = true;
522  sensor->surface = true;
523 
524  //----------
525  // set readout
526  //----------
527  readout->name = "readout";
528  readout->pos = G4ThreeVector(0, 0, 0);
529  readout->start = 45.0 * myPI / 180.0;
530  readout->theta = 2 * myPI;
531  readout->numSide = 4;
532  readout->num_zLayer = 2;
533 
534  readout->z[0] = readout_z[0];
535  readout->z[1] = readout_z[1];
536 
537  readout->rinner[0] = sensor_total_halfx;
538  readout->rinner[1] = readout->rinner[0];
539 
540  readout->router[0] = readout->rinner[0] + readoutThickness;
541  readout->router[1] = readout->router[0];
542 
543  readout->material = GetDetectorMaterial("G4_Al");
544  readout->sensitivity = 0;
545 
546  readout->color = G4Colour(1.0, 0.0, 0.0);
547  readout->visibility = true;
548  readout->wireframe = true;
549  readout->surface = false;
550 }
551 //________________________________________________________________________//
553 //________________________________________________________________________//
555 {
556  glassWindow->name = "glassWindow" + std::to_string(i);
557  //sprintf(glassWindow->name,"glassWindow%d",i);
558  glassWindow->pos.setX(x);
559  glassWindow->pos.setY(y);
560 }
561 //________________________________________________________________________//
562 void PHG4mRICHDetector::mRichParameter::SetPar_sensor(int i, G4double x, G4double y)
563 {
564  sensor->name = "sensor_" + std::to_string(i);
565  //sprintf(sensor->name,"sensor%d",i);
566  sensor->pos.setX(x);
567  sensor->pos.setY(y);
568 }
569 //________________________________________________________________________//
571 {
572  if (componentName.compare("holderBox") == 0)
573  return holderBox;
574  else if (componentName.compare("hollowVolume") == 0)
575  return hollowVolume;
576  else if (componentName.compare("foamHolderBox") == 0)
577  return foamHolderBox;
578  else if (componentName.compare("aerogel") == 0)
579  return aerogel;
580  else if (componentName.compare("glassWindow") == 0)
581  return glassWindow;
582  else if (componentName.compare("sensor") == 0)
583  return sensor;
584  else
585  std::cout << __FILE__ << "::" << __func__ << ":: ERROR: cannot find parameter " << componentName << std::endl;
586 
587  return 0;
588 }
589 //________________________________________________________________________//
591 {
592  if (componentName.compare("fresnelLens") == 0)
593  return fresnelLens;
594  else
595  std::cout << __FILE__ << "::" << __func__ << "::ERROR: cannot find parameter " << componentName << std::endl;
596  return 0;
597 }
598 //________________________________________________________________________//
600 {
601  if (componentName.compare("foamHolderPoly") == 0)
602  return foamHolderPoly;
603  else if (componentName.compare("mirror") == 0)
604  return mirror;
605  else if (componentName.compare("readout") == 0)
606  return readout;
607  else
608  std::cout << __FILE__ << "::" << __func__ << "::ERROR: cannot find parameter " << componentName << std::endl;
609 
610  return 0;
611 }
612 //________________________________________________________________________//
613 G4VPhysicalVolume* PHG4mRICHDetector::build_box(BoxPar* par, G4LogicalVolume* motherLV)
614 {
615  G4Box* box = new G4Box(par->name.c_str(), par->halfXYZ[0], par->halfXYZ[1], par->halfXYZ[2]);
616  G4LogicalVolume* log = new G4LogicalVolume(box, par->material, par->name.c_str(), 0, 0, 0);
617  G4VPhysicalVolume* phy = new G4PVPlacement(0, par->pos, log, par->name.c_str(), motherLV, false, 0, OverlapCheck());
618 
619  G4VisAttributes* visAtt = new G4VisAttributes(par->color);
620  visAtt->SetVisibility(par->visibility);
621  visAtt->SetForceWireframe(par->wireframe);
622  visAtt->SetForceSolid(par->surface);
623  log->SetVisAttributes(visAtt);
624 
625  return phy;
626 }
627 //________________________________________________________________________//
628 G4VPhysicalVolume* PHG4mRICHDetector::build_polyhedra(PolyPar* par, G4LogicalVolume* motherLV)
629 {
630  G4Polyhedra* polyhedra = new G4Polyhedra(par->name.c_str(), par->start, par->theta, par->numSide,
631  par->num_zLayer, par->z, par->rinner, par->router);
632  G4LogicalVolume* log = new G4LogicalVolume(polyhedra, par->material, par->name.c_str(), 0, 0, 0);
633  G4VPhysicalVolume* phy = new G4PVPlacement(0, par->pos, log, par->name.c_str(), motherLV, false, 0, OverlapCheck());
634 
635  G4VisAttributes* visAtt = new G4VisAttributes(par->color);
636  visAtt->SetVisibility(par->visibility);
637  visAtt->SetForceWireframe(par->wireframe);
638  visAtt->SetForceSolid(par->surface);
639  log->SetVisAttributes(visAtt);
640 
641  return phy;
642 }
643 //________________________________________________________________________//
644 G4VPhysicalVolume* PHG4mRICHDetector::build_holderBox(mRichParameter* detectorParameter, G4LogicalVolume* motherLV)
645 {
646  mRICH_PV = build_box(detectorParameter->GetBoxPar("holderBox"), motherLV);
647  return build_box(detectorParameter->GetBoxPar("hollowVolume"), mRICH_PV->GetLogicalVolume());
648 }
649 //________________________________________________________________________//
650 void PHG4mRICHDetector::build_foamHolder(mRichParameter* detectorParameter, G4LogicalVolume* motherLV)
651 {
652  G4VPhysicalVolume* box = build_box(detectorParameter->GetBoxPar("foamHolderBox"), motherLV);
653  if (!box)
654  {
655  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << ": placement of foamholderbox failed" << std::endl;
656  }
657  box = build_polyhedra(detectorParameter->GetPolyPar("foamHolderPoly"), motherLV);
658  if (!box)
659  {
660  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << ": placement of foamholderpoly failed" << std::endl;
661  }
662 }
663 //________________________________________________________________________//
664 void PHG4mRICHDetector::build_aerogel(mRichParameter* detectorParameter, G4VPhysicalVolume* motherPV)
665 {
666  G4VPhysicalVolume* aerogel = build_box(detectorParameter->GetBoxPar("aerogel"), motherPV->GetLogicalVolume());
667  aerogel_vol[aerogel] = 0;
668 
669  G4OpticalSurface* OpWaterSurface = new G4OpticalSurface("WaterSurface");
670  OpWaterSurface->SetType(dielectric_dielectric);
671  OpWaterSurface->SetFinish(ground);
672  OpWaterSurface->SetModel(unified);
673  new G4LogicalBorderSurface("WaterSurface", aerogel, motherPV, OpWaterSurface);
674 
675  const G4int num = 2;
676  G4double Ephoton[num] = {2.034 * eV, 4.136 * eV};
677  G4double RefractiveIndex[num] = {1.03, 1.03};
678  G4double SpecularLobe[num] = {0.3, 0.3};
679  G4double SpecularSpike[num] = {0.2, 0.2};
680  G4double Backscatter[num] = {0.2, 0.2};
681 
682  G4MaterialPropertiesTable* myST1 = new G4MaterialPropertiesTable();
683  myST1->AddProperty("RINDEX", Ephoton, RefractiveIndex, num);
684  myST1->AddProperty("SPECULARLOBECONSTANT", Ephoton, SpecularLobe, num);
685  myST1->AddProperty("SPECULARSPIKECONSTANT", Ephoton, SpecularSpike, num);
686  myST1->AddProperty("BACKSCATTERCONSTANT", Ephoton, Backscatter, num);
687 
688  OpWaterSurface->SetMaterialPropertiesTable(myST1);
689 }
690 //________________________________________________________________________//
691 void PHG4mRICHDetector::build_mirror(mRichParameter* detectorParameter, G4VPhysicalVolume* motherPV)
692 {
693  G4VPhysicalVolume* mirror = build_polyhedra(detectorParameter->GetPolyPar("mirror"), motherPV->GetLogicalVolume());
694 
695  //-----------
696  // Optical properties of the interface between the Air and Reflective Surface
697  // For Mirror, reflectivity is set at 95% and specular reflection is assumed.
698  //-----------
699  G4OpticalSurface* OpticalAirMirror = new G4OpticalSurface("AirMirrorSurface");
700  OpticalAirMirror->SetModel(unified);
701  OpticalAirMirror->SetType(dielectric_dielectric);
702  OpticalAirMirror->SetFinish(polishedfrontpainted);
703 
704  const G4int NUM = 2;
705  G4double lambda_min = 200 * nm;
706  G4double lambda_max = 700 * nm;
707 
708  G4double XX[NUM] = {h_Planck * c_light / lambda_max, h_Planck * c_light / lambda_min};
709  G4double ICEREFLECTIVITY[NUM] = {0.95, 0.95};
710 
711  G4MaterialPropertiesTable* AirMirrorMPT = new G4MaterialPropertiesTable();
712  AirMirrorMPT->AddProperty("REFLECTIVITY", XX, ICEREFLECTIVITY, NUM);
713  OpticalAirMirror->SetMaterialPropertiesTable(AirMirrorMPT);
714 
715  new G4LogicalBorderSurface("Air/Mirror Surface", motherPV, mirror, OpticalAirMirror);
716 }
717 //________________________________________________________________________//
718 void PHG4mRICHDetector::build_sensor(mRichParameter* detectorParameter, G4LogicalVolume* motherLV)
719 {
720  //position of the first sensor module
721  G4double last_x = detectorParameter->GetBoxPar("glassWindow")->pos.getX();
722  G4double last_y = last_x;
723 
724  G4double x, y;
725 
726  int i;
727  for (i = 0; i < 4; i++)
728  {
729  if (i == 0)
730  {
731  x = last_x;
732  y = last_y;
733  }
734  else
735  {
736  x = -last_y;
737  y = last_x;
738  }
739 
740  detectorParameter->SetPar_glassWindow(i + 1, x, y);
741 
742  detectorParameter->SetPar_sensor(i + 1, x, y);
743  sensor_PV[i] = build_box(detectorParameter->GetBoxPar("sensor"), motherLV);
744 
745  sensor_vol[sensor_PV[i]] = i;
746  //cout << "in build_sensor: sensor_vol = " << sensor_vol[sensor_PV[i]] << endl;
747 
748  last_x = x;
749  last_y = y;
750  } //end of for(i)
751 }
752 //________________________________________________________________________//
753 void PHG4mRICHDetector::build_lens(LensPar* par, G4LogicalVolume* motherLV)
754 {
755  const G4int NumberOfGrooves = floor((par->eff_diameter / 2.0) / par->grooveWidth);
756  G4Polycone* Groove_poly[NumberOfGrooves];
757  G4LogicalVolume* Groove_log[NumberOfGrooves];
758 
759  G4VisAttributes* SurfaceVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 1.0));
760  SurfaceVisAtt->SetVisibility(true);
761  SurfaceVisAtt->SetForceWireframe(true);
762  SurfaceVisAtt->SetForceSolid(true);
763 
764  int igroove;
765  for (igroove = 0; igroove < 1000; igroove++)
766  { //just put a arbitrary large number
767  //--------------------------------
768  //Grooves' inner and outer radius
769  //--------------------------------
770  G4double iRmin1 = (igroove + 0) * par->grooveWidth;
771  G4double iRmax1 = (igroove + 1) * par->grooveWidth;
772  G4double iRmin2 = iRmin1;
773  G4double iRmax2 = iRmin2 + 0.0001;
774 
775  G4double lens_poly_rmin[3] = {iRmin1, iRmin1, iRmin2};
776  G4double lens_poly_rmax[3] = {iRmax1, iRmax1, iRmax2};
777 
778  if (iRmax1 > par->diameter / 2.0) break; //if iRmax1>Lens radius (outside the lens), break
779 
780  //--------------------------------
781  //phi angle
782  //--------------------------------
783  G4double phi1;
784  G4double phi2;
785  G4double deltaPhi;
786 
787  if (iRmax1 < par->halfXYZ[0])
788  { //draw a full circle
789  phi1 = 0; //in rad
790  deltaPhi = twopi; //in rad. two pi
791  }
792  else
793  {
794  phi1 = acos(par->halfXYZ[0] / iRmax1); //in rad
795  phi2 = asin(par->halfXYZ[0] / iRmax1); //in rad, assume lens is square -> halfy=halfx
796  deltaPhi = phi2 - phi1;
797  }
798  //--------------------------------
799  //grooves profile
800  //--------------------------------
801  G4double lens_poly_z[3];
802  int numOfLayer;
803 
804  if (iRmin1 < par->eff_diameter / 2.0)
805  { //if iRmin>=effective radius, dZ=0, i.e. flat
806  numOfLayer = 3;
807  G4double dZ = par->GetSagita(iRmax1) - par->GetSagita(iRmin1);
808  lens_poly_z[0] = par->halfXYZ[2];
809  lens_poly_z[1] = -par->halfXYZ[2] + dZ;
810  lens_poly_z[2] = -par->halfXYZ[2];
811  }
812  else
813  {
814  numOfLayer = 2;
815  lens_poly_z[0] = par->halfXYZ[2];
816  lens_poly_z[1] = par->halfXYZ[2] - par->centerThickness;
817  lens_poly_z[2] = 0;
818  }
819 
820  //--------------------------------
821  //build grooves
822  //--------------------------------
823  int repeat = 1;
824  if (iRmax1 >= par->halfXYZ[0])
825  {
826  repeat = 4;
827  } //4 edges
828  for (int i = 0; i < repeat; i++)
829  {
830  Groove_poly[i] = new G4Polycone(par->name.c_str(), phi1, deltaPhi, numOfLayer, lens_poly_z, lens_poly_rmin, lens_poly_rmax);
831  Groove_log[i] = new G4LogicalVolume(Groove_poly[i], par->material, par->name.c_str(), 0, 0, 0);
832  new G4PVPlacement(0, par->pos, Groove_log[i], par->name.c_str(), motherLV, false, 0, OverlapCheck());
833 
834  Groove_log[i]->SetVisAttributes(SurfaceVisAtt);
835  phi1 = phi1 + halfpi; //g4 pre-defined: halfpi=pi/2
836  }
837  }
838 }
839 //________________________________________________________________________//
840 void PHG4mRICHDetector::build_mRICH_wall_hside(G4LogicalVolume* logicWorld)
841 {
842  G4AssemblyVolume* mRICHwall = new G4AssemblyVolume(); //"mother volume"
843 
844  G4LogicalVolume* a_mRICH = Construct_a_mRICH(0); // build a single mRICH
845 
846  int NumOfModule = params->get_int_param("NumOfModule_wall_hside");
847 
848  for (int i_mRICH = 0; i_mRICH < NumOfModule; ++i_mRICH)
849  {
850  // get moduleID
851  // std::stringstream key_moduleID;
852  // key_moduleID << "mRICH_wall_hside_" << i_mRICH << "_moduleID";
853  // int module_id = params->get_int_param(key_moduleID.str());
854 
855  // get position
856  std::stringstream key_position_x;
857  key_position_x << "mRICH_wall_hside_" << i_mRICH << "_position_x";
858  G4double x = params->get_double_param(key_position_x.str());
859 
860  std::stringstream key_position_y;
861  key_position_y << "mRICH_wall_hside_" << i_mRICH << "_position_y";
862  G4double y = params->get_double_param(key_position_y.str());
863 
864  std::stringstream key_position_z;
865  key_position_z << "mRICH_wall_hside_" << i_mRICH << "_position_z";
866  G4double z = params->get_double_param(key_position_z.str());
867 
868  // get rotation
869  std::stringstream key_rotation_theta;
870  key_rotation_theta << "mRICH_wall_hside_" << i_mRICH << "_rotation_theta";
871  G4double theta = params->get_double_param(key_rotation_theta.str());
872 
873  std::stringstream key_rotation_phi;
874  key_rotation_phi << "mRICH_wall_hside_" << i_mRICH << "_rotation_phi";
875  G4double phi = params->get_double_param(key_rotation_phi.str());
876 
877  //cout << "module_id = " << module_id << ", x = " << x << ", y = " << y << ", z = " << z << ", theta = " << theta << ", phi = " << phi << endl;
878 
879  G4ThreeVector pos(x, y, z);
880  G4RotationMatrix* rot = new G4RotationMatrix();
881 
882  if (x != 0 || y != 0)
883  {
884  rot->rotateX(theta * (-1) * sin(phi) * 180 * deg / pi);
885  rot->rotateY(theta * cos(phi) * 180 * deg / pi);
886  }
887  mRICHwall->AddPlacedVolume(a_mRICH, pos, rot);
888  }
889 
890  G4ThreeVector pos(0, 0, 0);
891  mRICHwall->MakeImprint(logicWorld, pos, nullptr, 0, OverlapCheck());
892 }
893 //________________________________________________________________________//
894 
895 //________________________________________________________________________//
896 void PHG4mRICHDetector::build_mRICH_wall_eside(G4LogicalVolume* logicWorld)
897 {
898  G4AssemblyVolume* mRICHwall = new G4AssemblyVolume(); //"mother volume"
899 
900  G4LogicalVolume* a_mRICH = Construct_a_mRICH(0); // build a single mRICH
901 
902  G4double shift = params->get_double_param("mRICH_wall_eside_shift");
903 
904  int NumOfModule = params->get_int_param("NumOfModule_wall_eside");
905 
906  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << "::NumOfModule: " << NumOfModule << std::endl;
907 
908  for (int i_mRICH = 0; i_mRICH < NumOfModule; ++i_mRICH)
909  {
910  // get moduleID
911  // std::stringstream key_moduleID;
912  // key_moduleID << "mRICH_wall_eside_" << i_mRICH << "_moduleID";
913  // int module_id = params->get_int_param(key_moduleID.str());
914 
915  // get position
916  std::stringstream key_position_x;
917  key_position_x << "mRICH_wall_eside_" << i_mRICH << "_position_x";
918  G4double x = params->get_double_param(key_position_x.str());
919 
920  std::stringstream key_position_y;
921  key_position_y << "mRICH_wall_eside_" << i_mRICH << "_position_y";
922  G4double y = params->get_double_param(key_position_y.str());
923 
924  std::stringstream key_position_z;
925  key_position_z << "mRICH_wall_eside_" << i_mRICH << "_position_z";
926  G4double z = params->get_double_param(key_position_z.str());
927 
928  //cout << "module_id = " << i_mRICH << ", x = " << x << ", y = " << y << ", z = " << z << endl;
929 
930  G4ThreeVector pos(x, y, z);
931  G4RotationMatrix* rot = new G4RotationMatrix();
932  mRICHwall->AddPlacedVolume(a_mRICH, pos, rot);
933  }
934 
935  G4ThreeVector pos(0, 0, shift);
936  G4RotationMatrix* rot = new G4RotationMatrix();
937  rot->rotateX(180 * deg);
938  mRICHwall->MakeImprint(logicWorld, pos, rot, 0, OverlapCheck());
939 }
940 //________________________________________________________________________//
941 void PHG4mRICHDetector::build_mRICH_sector(G4LogicalVolume* logicWorld, int numSector)
942 {
943  G4AssemblyVolume* sector = new G4AssemblyVolume(); //"mother volume"
944 
945  G4LogicalVolume* a_mRICH = Construct_a_mRICH(0); // build a single mRICH
946 
947  G4double theta = params->get_double_param("mRICH_sector_hside_rotation_theta");
948 
949  G4double shift = params->get_double_param("mRICH_sector_hside_shift");
950 
951  int NumOfModule = params->get_int_param("NumOfModule_sector_hside");
952 
953  for (int i_mRICH = 0; i_mRICH < NumOfModule; ++i_mRICH)
954  {
955  // get moduleID
956  // std::stringstream key_moduleID;
957  // key_moduleID << "mRICH_sector_hside_" << i_mRICH << "_moduleID";
958  // int module_id = params->get_int_param(key_moduleID.str());
959 
960  // get position
961  std::stringstream key_position_x;
962  key_position_x << "mRICH_sector_hside_" << i_mRICH << "_position_x";
963  G4double x = params->get_double_param(key_position_x.str());
964 
965  std::stringstream key_position_y;
966  key_position_y << "mRICH_sector_hside_" << i_mRICH << "_position_y";
967  G4double y = params->get_double_param(key_position_y.str());
968 
969  std::stringstream key_position_z;
970  key_position_z << "mRICH_sector_hside_" << i_mRICH << "_position_z";
971  G4double z = params->get_double_param(key_position_z.str());
972  if (i_mRICH == 10) z -= 10.;
973 
974  //cout << "module_id = " << module_id << ", x = " << x << ", y = " << y << ", z = " << z << ", theta = " << theta << endl;
975 
976  G4ThreeVector pos(x, y, z);
977  G4RotationMatrix* rot = new G4RotationMatrix();
978 
979  sector->AddPlacedVolume(a_mRICH, pos, rot);
980  }
981 
982  for (int i = 0; i < numSector; i++)
983  {
984  // G4ThreeVector pos(0, 0, 3.0*m);
985  G4ThreeVector pos(0, 0, shift);
986  // G4ThreeVector pos(0, 0, 2.8085*m);
987  G4RotationMatrix* rot = new G4RotationMatrix();
988  rot->rotateX(-theta * 180 * deg / pi);
989  rot->rotateZ(i * 45 * deg);
990  sector->MakeImprint(logicWorld, pos, rot, 0, OverlapCheck());
991  }
992 }
993 
994 //________________________________________________________________________//
995 //________________________________________________________________________//
996 void PHG4mRICHDetector::build_mRICH_sector2(G4LogicalVolume* logicWorld, int numSector)
997 {
998  G4AssemblyVolume* sector = new G4AssemblyVolume(); //"mother volume"
999 
1000  G4LogicalVolume* a_mRICH = Construct_a_mRICH(0); // build a single mRICH
1001 
1002  //-m/s-G4double theta = params->get_double_param("mRICH_sector_bside_rotation_theta");
1003 
1004  //G4double shift = 70;//params->get_double_param("mRICH_sector_bside_shift");
1005 
1006  int NumOfModule = params->get_int_param("NumOfModule_sector_bside");
1007 
1008  //--G4double delta = 2.15833;
1009  G4double yy[8] = {61.92, 61.92, 63.09, 63.09, 63.34, 63.34, 63.00, 63.00};
1010  G4double zz[8] = {8.94, -8.94, 27.78, -27.78, 48.26, -48.26, 71.41, -71.41};
1011  G4double rotAng[8] = {-81.78, -98.22, -66.23, -113.77, -52.69, -127.31, -41.42, -138.58};
1012 
1013  //for (int i_mRICH = 0; i_mRICH < NumOfModule; ++i_mRICH)
1014  //for (int i_mRICH = 0; i_mRICH < 10; ++i_mRICH)
1015  for (int i_mRICH = 0; i_mRICH < 8; ++i_mRICH)
1016  {
1017  // get moduleID
1018  //std::stringstream key_moduleID;
1019  // key_moduleID << "mRICH_sector_bside_" << i_mRICH << "_moduleID";
1020  //int module_id = params->get_int_param(key_moduleID.str());
1021 
1022  // get position
1023  std::stringstream key_position_x;
1024  key_position_x << "mRICH_sector_bside_" << i_mRICH << "_position_x";
1025  G4double x = 0.; //params->get_double_param(key_position_x.str());
1026 
1027  std::stringstream key_position_y;
1028  key_position_y << "mRICH_sector_bside_" << i_mRICH << "_position_y";
1029  G4double y = yy[i_mRICH] * 10.; //params->get_double_param(key_position_y.str()); //500
1030 
1031  std::stringstream key_position_z;
1032  key_position_z << "mRICH_sector_bside_" << i_mRICH << "_position_z";
1033  G4double z = zz[i_mRICH] * 10.; //params->get_double_param(key_position_z.str());
1034 
1035  //cout << "222: module_id = " <<i_mRICH << ", x = " << x << ", y = " << y << ", z = " << z << endl;
1036 
1037  //G4double rotAng = -90 + pow(-1,i_mRICH)*(rotAng0*2*i_mRICH+rotAng0);
1038 
1039  G4ThreeVector pos(x, y, z);
1040  G4RotationMatrix* rot = new G4RotationMatrix();
1041  rot->rotateX(rotAng[i_mRICH] * deg);
1042  //rot->rotateX(-91 * deg);
1043  //rot->rotateX(-90 * deg);
1044 
1045  sector->AddPlacedVolume(a_mRICH, pos, rot);
1046  }
1047 
1048  if (Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) std::cout << __FILE__ << "::" << __func__ << "::222x1x222" << NumOfModule << "\t" << numSector << std::endl;
1049 
1050  G4double nSecs = 21;
1051  G4double Ang = 360. / nSecs;
1052 
1053  //for (int i = 0; i < numSector; i++)
1054  for (int i = 0; i < nSecs; i++)
1055  //for (int i = 0; i < 1; i++)
1056  {
1057  //G4ThreeVector pos(0, 0, shift);
1058  G4ThreeVector pos(0, 0, 0);
1059  G4RotationMatrix* rot = new G4RotationMatrix();
1060  //rot->rotateX(-theta * 180 * deg / pi);
1061  rot->rotateZ(i * Ang * deg);
1062  sector->MakeImprint(logicWorld, pos, rot, 0, OverlapCheck());
1063  }
1064 }
1065 
1066 //________________________________________________________________________//
1067 
1068 //________________________________________________________________________//
1069 void PHG4mRICHDetector::build_mRICH_wall_eside_proj(G4LogicalVolume* logicWorld)
1070 {
1071  G4AssemblyVolume* mRICHwall = new G4AssemblyVolume(); //"mother volume"
1072 
1073  G4LogicalVolume* a_mRICH = Construct_a_mRICH(0); // build a single mRICH
1074 
1075  G4double shift = params->get_double_param("mRICH_wall_eside_proj_shift");
1076 
1077  int NumOfModule = params->get_int_param("NumOfModule_wall_eside_proj");
1078 
1079  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << __FILE__ << "::" << __func__ << "::NumOfModule: " << NumOfModule << std::endl;
1080 
1081  G4double scale = 1.0;
1082  for (int i_mRICH = 0; i_mRICH < NumOfModule; ++i_mRICH)
1083  {
1084  // get moduleID
1085  // std::stringstream key_moduleID;
1086  // key_moduleID << "mRICH_wall_eside_" << i_mRICH << "_moduleID";
1087  // int module_id = params->get_int_param(key_moduleID.str());
1088 
1089  /*
1090  if(i_mRICH<12) scale = 1.067;
1091  else if(i_mRICH>=12 && i_mRICH<24) scale = 1.070;
1092  else if(i_mRICH>=24 && i_mRICH<44) scale = 1.074;
1093  else if(i_mRICH>=44 && i_mRICH<48) scale = 1.077;
1094  else scale = 1.078;
1095  */
1096  if (i_mRICH < 8)
1097  scale = 1.08;
1098  else if (i_mRICH >= 8 && i_mRICH < 20)
1099  scale = 1.085;
1100  else if (i_mRICH >= 20 && i_mRICH < 44)
1101  scale = 1.11;
1102  else
1103  scale = 1.15;
1104 
1105  // get position
1106  std::stringstream key_position_x;
1107  key_position_x << "mRICH_wall_eside_proj_" << i_mRICH << "_position_x";
1108  G4double x = params->get_double_param(key_position_x.str()) * scale;
1109 
1110  std::stringstream key_position_y;
1111  key_position_y << "mRICH_wall_eside_proj_" << i_mRICH << "_position_y";
1112  G4double y = params->get_double_param(key_position_y.str()) * scale;
1113 
1114  std::stringstream key_position_z;
1115  key_position_z << "mRICH_wall_eside_proj_" << i_mRICH << "_position_z";
1116  G4double z = params->get_double_param(key_position_z.str());
1117 
1118  //cout << "module_id = " << i_mRICH << ", x = " << x << ", y = " << y << ", z = " << z << endl;
1119  G4double rotAngX = atan(y / shift);
1120  G4double rotAngY = atan(x / std::abs(shift));
1121  G4ThreeVector pos(x, y, z);
1122  G4RotationMatrix* rot = new G4RotationMatrix();
1123  rot->rotateX(rotAngX * rad);
1124  rot->rotateY(rotAngY * rad);
1125 
1126  mRICHwall->AddPlacedVolume(a_mRICH, pos, rot);
1127  }
1128 
1129  G4ThreeVector pos(0, 0, shift);
1130  G4RotationMatrix* rot = new G4RotationMatrix();
1131  rot->rotateX(180 * deg);
1132  mRICHwall->MakeImprint(logicWorld, pos, rot, 1000, OverlapCheck());
1133 }