ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4CylinderStripDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4CylinderStripDetector.cc
2 
3 #include <phparameter/PHParameters.h>
4 
5 #include <g4main/PHG4Detector.h> // for PHG4Detector
6 #include <g4main/PHG4DisplayAction.h> // for PHG4DisplayAction
7 #include <g4main/PHG4Subsystem.h>
8 
9 #include <Geant4/G4Box.hh>
10 #include <Geant4/G4Element.hh>
11 #include <Geant4/G4LogicalVolume.hh>
12 #include <Geant4/G4Material.hh>
13 #include <Geant4/G4PVPlacement.hh>
14 #include <Geant4/G4PhysicalConstants.hh>
15 #include <Geant4/G4String.hh> // for G4String
16 #include <Geant4/G4SubtractionSolid.hh>
17 #include <Geant4/G4SystemOfUnits.hh>
18 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
19 #include <Geant4/G4Tubs.hh>
20 #include <Geant4/G4UnionSolid.hh>
21 #include <Geant4/G4UserLimits.hh>
22 #include <Geant4/G4VisAttributes.hh>
23 
24 #include <TMath.h>
25 #include <TSystem.h>
26 
27 #include <cmath>
28 #include <iostream> // for operator<<, endl, basic_ost...
29 #include <map>
30 #include <sstream>
31 
32 class G4VSolid;
33 class PHCompositeNode;
34 
35 using namespace std;
36 
37 //_______________________________________________________________
39  : PHG4Detector(subsys, Node, dnam)
40  , m_Params(parameters)
41  , m_CylinderPhysicalVolume(nullptr)
42  , m_Layer(lyr)
43  , thickness(0)
44 {
45  barwidth = 3 * mm;
46 }
47 
48 //_______________________________________________________________
49 //bool PHG4CylinderStripDetector::IsInDetector(G4VPhysicalVolume *volume) const
50 //{
51 // set<G4VPhysicalVolume *>::const_iterator iter =
52 // m_PhysicalVolumesSet.find(volume);
53 // if (iter != m_PhysicalVolumesSet.end())
54 // {
55 // return true;
56 // }
57 //
58 // return false;
59 //}
60 
61 //_______________________________________________________________
62 
64 {
65  set<G4VPhysicalVolume *>::const_iterator iter =
66  m_CylinderCPhysicalVolume.find(volume);
67  if (iter != m_CylinderCPhysicalVolume.end())
68  {
69  return true;
70  }
71 
72  return false;
73 }
74 
75 //_______________________________________________________________
76 
78 {
79  set<G4VPhysicalVolume *>::const_iterator iter =
80  m_CylinderZPhysicalVolume.find(volume);
81  if (iter != m_CylinderZPhysicalVolume.end())
82  {
83  return true;
84  }
85 
86  return false;
87 }
88 
89 //_______________________________________________________________
91 {
93  G4Material *TrackerMaterial = GetDetectorMaterial(m_Params->get_string_param("gas"));
94 
95  if (!TrackerMaterial)
96  {
97  std::cout << "Error: Can not set Micromegas Gas" << std::endl;
98  gSystem->Exit(1);
99  }
100 
101  // components
102  enum components
103  {
104  coverlay,
105  CuGround,
106  PCB,
107  CuStrips,
108  KaptonStrips,
109  ResistiveStrips,
110  Gas1,
111  Mesh,
112  Gas2,
113  DriftCuElectrode,
114  DriftKapton,
115  DriftCuGround,
116  kNcomponents
117  };
118  // component names
119  G4String names[] = {
120  "coverlay",
121  "CuGround",
122  "PCB",
123  "CuStrips",
124  "KaptonStrips",
125  "ResistiveStrips",
126  "Gas1",
127  "Mesh",
128  "Gas2",
129  "DriftCuElectrode",
130  "DriftKapton",
131  "DriftCuGround"};
132 
133  // thicknesses
134  map<int, float> thick;
135  thick[coverlay] = 0.0050000 * cm;
136  thick[CuGround] = 0.0001580 * cm;
137  thick[PCB] = 0.0100000 * cm;
138  thick[CuStrips] = 0.0012000 * cm;
139  thick[KaptonStrips] = 0.0075000 * cm;
140  thick[ResistiveStrips] = 0.0020000 * cm;
141  //thick[ Gas1 ] = 0.0020000 * cm;
142  thick[Gas1] = m_Params->get_double_param("gas1thickness") * cm;
143  thick[Mesh] = 0.0018000 * cm;
144  //thick[ Gas2 ] = 0.3000000 * cm;
145  thick[Gas2] = m_Params->get_double_param("gas2thickness") * cm;
146  thick[DriftCuElectrode] = 0.0005000 * cm;
147  thick[DriftKapton] = 0.0250000 * cm;
148  thick[DriftCuGround] = 0.0000410 * cm;
149 
150  // media
151  map<int, G4Material *> media;
152  media[coverlay] = GetDetectorMaterial("myKapton");
153  media[CuGround] = GetDetectorMaterial("myCopper");
154  media[PCB] = GetDetectorMaterial("myFR4");
155  media[CuStrips] = GetDetectorMaterial("myMMStrips");
156  media[KaptonStrips] = GetDetectorMaterial("myKapton");
157  media[ResistiveStrips] = GetDetectorMaterial("myMMResistivePaste");
158  media[Gas1] = TrackerMaterial;
159  media[Mesh] = GetDetectorMaterial("myMMMesh");
160  media[Gas2] = TrackerMaterial;
161  media[DriftCuElectrode] = GetDetectorMaterial("myCopper");
162  media[DriftKapton] = GetDetectorMaterial("myKapton");
163  media[DriftCuGround] = GetDetectorMaterial("myCopper");
164 
165  // color
166  map<int, G4Colour> color;
167  color[coverlay] = G4Colour(204 / 255., 153 / 255., 0);
168  color[CuGround] = G4Colour::Brown();
169  color[PCB] = G4Colour::Green();
170  color[CuStrips] = G4Colour::Brown();
171  color[KaptonStrips] = G4Colour::Brown();
172  color[ResistiveStrips] = G4Colour::Black();
173  color[Gas1] = G4Colour::Grey();
174  color[Mesh] = G4Colour::White();
175  color[Gas2] = G4Colour::Grey();
176  color[DriftCuElectrode] = G4Colour::Brown();
177  color[DriftKapton] = G4Colour::Brown();
178  color[DriftCuGround] = G4Colour(51 / 255., 26 / 255., 0);
179 
180  // components meca PCB
181  enum components_meca
182  {
183  Cu1_meca,
184  FR4_1_meca,
185  Cu2_meca,
186  FR4_2_meca,
187  Cu3_meca,
188  kNcomponents_meca
189  };
190  // component names
191  G4String names_meca[] = {
192  "Cu1_meca",
193  "FR4_1_meca",
194  "Cu2_meca",
195  "FR4_2_meca",
196  "Cu3_meca"};
197 
198  // thicknesses
199  map<int, float> thick_meca;
200  thick_meca[Cu1_meca] = 25 * um;
201  thick_meca[FR4_1_meca] = 100 * um;
202  thick_meca[Cu2_meca] = 25 * um;
203  thick_meca[FR4_2_meca] = 100 * um;
204  thick_meca[Cu3_meca] = 9 * um;
205 
206  // media
207  map<int, G4Material *> media_meca;
208  media_meca[Cu1_meca] = GetDetectorMaterial("myCopper");
209  media_meca[FR4_1_meca] = GetDetectorMaterial("myFR4");
210  media_meca[Cu2_meca] = GetDetectorMaterial("myCopper");
211  media_meca[FR4_2_meca] = GetDetectorMaterial("myFR4");
212  media_meca[Cu3_meca] = GetDetectorMaterial("myCopper");
213 
214  // color
215  map<int, G4Colour> color_meca;
216  color_meca[Cu1_meca] = G4Colour::Brown();
217  color_meca[FR4_1_meca] = G4Colour::Green();
218  color_meca[Cu2_meca] = G4Colour::Brown();
219  color_meca[FR4_2_meca] = G4Colour::Green();
220  color_meca[Cu3_meca] = G4Colour::Brown();
221  // determine length of cylinder using PHENIX's rapidity coverage if flag is true
222  double radius = m_Params->get_double_param("radius") * cm;
223  double gap = m_Params->get_double_param("gap") * cm;
224  double gas_deadzone = m_Params->get_double_param("deadzone") * cm;
225  int nhit = 1;
226 
227  int nCZlayer = 2;
228  if (m_Params->get_int_param("use_2Dreadout"))
229  {
230  nhit = m_Params->get_int_param("nhit");
231  nCZlayer = 1;
232  gap = 0;
233  }
234 
235  if (nCZlayer == 2)
236  thick[CuStrips] = 9 * um;
237  else if (nCZlayer == 1)
238  thick[CuStrips] = 25 * um;
239 
240  thickness = 0;
241  for (map<int, float>::iterator iter = thick.begin(); iter != thick.end(); ++iter)
242  {
243  thickness += iter->second;
244  }
245  // cout << "2D readout? " << m_Params->get_int_param("use_2Dreadout") << " Cu strips thickness : " << thick[CuStrips] << endl;
246  cout << "The tile thickness is " << thickness / mm << " mm" << endl;
248 
249  // make a "sub-world": a tube that contains all the tiles of this layer
250  // --------------------------------------------------------------------
251 
252  // max thickness (cm)
253 
254  // radius is defined from the middle of the tracker layer, and now move it to the lower boundary of the bottom MM layer (1D), or to the lower boundary of the MM layer (2D)
255  radius = radius - gap / 2. - thickness / 2. * nCZlayer;
256 
257  double spaceforhollowbar = 6 * mm;
258 
259  G4VSolid *cylinder_solid = new G4Tubs(G4String(GetName()),
260  radius - 0.001 * mm - spaceforhollowbar / 2,
261  radius + thickness * nCZlayer + gap + 0.001 * mm + spaceforhollowbar / 2,
262  m_Params->get_double_param("length") * cm / 2. + barwidth + 2 * mm, 0, twopi);
263  G4LogicalVolume *cylinder_logic = new G4LogicalVolume(cylinder_solid,
264  GetDetectorMaterial("myAir"),
265  G4String(GetName()));
266  G4VisAttributes *vis = new G4VisAttributes(G4Color(G4Colour::Grey())); // grey is good to see the tracks in the display
267  vis->SetForceSolid(false);
268  vis->SetVisibility(false);
270  cylinder_logic->SetVisAttributes(vis);
271 
272  // add mother logical volume to subsystem
273  PHG4Subsystem *mysys = GetMySubsystem();
274  mysys->SetLogicalVolume(cylinder_logic);
275 
276  // compute how many tiles
277  // ----------------------
278 
279  float maxTileWidth = 50. * cm; // cm
280  float spacer = 2. * cm; // cm, mechanical space between tiles, to be filled with carbon fiber
281 
282  float circumference = twopi * radius;
283  int Ntiles = ceil(circumference / (maxTileWidth + spacer));
284 
285  float tileW = (circumference - Ntiles * spacer) / Ntiles;
286 
287  cout << setw(10) << radius << setw(10) << "Ntiles: " << Ntiles << setw(20) << "tileW: " << tileW << endl;
288 
289  // make 1 tile
290  // -----------
291 
292  float deltaPhi = tileW / radius * TMath::RadToDeg();
293  spacer = radius * 360. / Ntiles * deg - tileW;
294  double steplimits = m_Params->get_double_param("steplimits") * cm;
295  G4UserLimits *g4userlimits = nullptr;
296  if (isfinite(steplimits))
297  {
298  g4userlimits = new G4UserLimits(steplimits);
299  }
300 
301  G4VSolid *tile_o = new G4Tubs(G4String(GetName()) + "_tile",
302  radius - 0.001 * mm - spaceforhollowbar / 2,
303  radius + thickness * nCZlayer + gap + 0.001 * mm + spaceforhollowbar / 2,
304  m_Params->get_double_param("length") * cm / 2. + barwidth + 2 * mm, 0, 360. / Ntiles * deg - 0.01 * deg);
305  G4LogicalVolume *tile_o_logic = new G4LogicalVolume(tile_o,
306  GetDetectorMaterial("myAir"),
307  G4String(GetName()) + "_tile_logic");
308  tile_o_logic->SetVisAttributes(vis);
309 
310  double thickness_mecaPCB = 25 * um + 100 * um + 25 * um + 100 * um + 9 * um;
311  double radius_mecaPCB = radius + thickness / 2. - thickness_mecaPCB / 2.;
312  // build a mother volume filled by carbon fiber using union volume
313  G4VSolid *mecaPCB_solid = new G4Tubs("mecaPCB_solid",
314  radius_mecaPCB - 0.1 * um,
315  radius_mecaPCB + thickness_mecaPCB + 0.1 * um,
316  m_Params->get_double_param("length") * cm / 2.,
317  360. / Ntiles * deg - (spacer - 2 * barwidth + 1 * mm) / radius_mecaPCB * radian,
318  (spacer - 2 * barwidth) / (radius_mecaPCB) *radian);
319  G4VSolid *MM_solid = new G4Tubs("MM_solid",
320  radius - 0.1 * um,
321  radius + thickness + 0.1 * um,
322  m_Params->get_double_param("length") * cm / 2. + barwidth + .1 * mm,
323  barwidth / radius * radian - 0.5 * mm / radius * radian,
324  deltaPhi * deg + 0.5 * mm / radius * radian);
325  G4VSolid *bar_solid = GetHollowBar();
326 
328  double rotang_bar2 = barwidth / 2. / radius * radian;
329  zrot->rotateZ(rotang_bar2);
330  G4VSolid *u1 = new G4UnionSolid("MM+bar1", MM_solid, bar_solid, G4Transform3D(*zrot, G4ThreeVector((radius + thickness / 2.) * TMath::Cos(rotang_bar2), (radius + thickness / 2.) * TMath::Sin(rotang_bar2), 0)));
331 
332  rotang_bar2 = 360. / Ntiles * deg + rotang_bar2 - ((spacer - barwidth) / radius * radian) - 0.5 * mm / radius * radian;
333  zrot->setDelta(twopi - (360. / Ntiles * deg - ((spacer - barwidth) / radius * radian) - 90 * deg));
334  u1 = new G4UnionSolid("MM+bar1+bar2", u1, bar_solid, zrot, G4ThreeVector((radius + thickness / 2.) * TMath::Cos(rotang_bar2), (radius + thickness / 2.) * TMath::Sin(rotang_bar2), 0));
335  //G4RotationMatrix* zrotx = new G4RotationMatrix();
336  //zrotx->rotateZ(deltaPhi*deg + 2*barwidth/radius *radian + 2*mm/radius);
337  //u1 = new G4UnionSolid("MM+bar1+bar2+arch1+arch2+meca", u1, mecaPCB_solid, G4Transform3D(*zrotx, G4ThreeVector(0,0,0)));
338  u1 = new G4UnionSolid("MM+bar1+bar2+arch1+arch2+meca", u1, mecaPCB_solid);
339  // logic volume filled with carbon fiber
340  G4LogicalVolume *u1_C_logic = new G4LogicalVolume(u1,
341  GetDetectorMaterial("myCfiber"),
342  "u1_C_logic");
343 
344  vis = new G4VisAttributes(G4Color(G4Colour::Grey())); // grey is good to see the tracks in the display
345  vis->SetForceSolid(false);
346  vis->SetVisibility(true);
348  u1_C_logic->SetVisAttributes(vis);
349  zrot->setDelta(0);
350  new G4PVPlacement(G4Transform3D(*zrot, G4ThreeVector(0, 0, 0)),
351  u1_C_logic,
352  "u1_C_phys",
353  tile_o_logic, false, 0, OverlapCheck());
354 
355  float Rm = radius;
356  float RM = Rm;
357  float Rm_meca = radius_mecaPCB;
358  float RM_meca = Rm_meca;
359 
360  G4VSolid *tile_o_comp = nullptr;
361  G4LogicalVolume *tile_o_comp_logic = nullptr;
362 
363  for (int ic = 0; ic < kNcomponents; ic++)
364  {
365  G4UserLimits *g4userlimits_gas = nullptr;
366  if (ic == Gas2)
367  g4userlimits_gas = g4userlimits;
368 
369  G4String cname = G4String(GetName()) + "_tileC" + "_" + names[ic];
370 
371  zrot->setDelta(barwidth / radius * radian);
372  G4VPhysicalVolume *phys = nullptr;
373 
374  vis = new G4VisAttributes(G4Color(color[ic])); // grey is good to see the tracks in the display
375  vis->SetForceSolid(true);
376  vis->SetVisibility(true);
378 
379  if (ic == Gas2)
380  {
381  thick[ic] /= nhit;
382  for (int ii = 0; ii < nhit; ii++)
383  {
384  RM = Rm + thick[ic];
385  tile_o_comp = new G4Tubs(cname + "_solid",
386  Rm,
387  RM,
388  m_Params->get_double_param("length") * cm / 2. - gas_deadzone, gas_deadzone / Rm * radian, deltaPhi * deg - 2 * gas_deadzone / Rm * radian);
389  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
390  media[ic],
391  cname + "_logic",
392  nullptr,
393  nullptr,
394  g4userlimits_gas);
395  tile_o_comp_logic->SetVisAttributes(vis);
396  Rm = RM;
397  phys = new G4PVPlacement(G4Transform3D(*zrot, G4ThreeVector(0, 0, 0)),
398  tile_o_comp_logic,
399  cname + "_phys",
400  u1_C_logic, false, 0, OverlapCheck());
401  }
402  }
403  else
404  {
405  RM = Rm + thick[ic];
406  tile_o_comp = new G4Tubs(cname + "_solid",
407  Rm,
408  RM,
409  m_Params->get_double_param("length") * cm / 2., 0, deltaPhi * deg);
410  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
411  media[ic],
412  cname + "_logic",
413  nullptr,
414  nullptr,
415  g4userlimits_gas);
416  tile_o_comp_logic->SetVisAttributes(vis);
417  Rm = RM;
418  phys = new G4PVPlacement(G4Transform3D(*zrot, G4ThreeVector(0, 0, 0)),
419  tile_o_comp_logic,
420  cname + "_phys",
421  u1_C_logic, false, 0, OverlapCheck());
422  }
423  if (ic == Gas2)
424  m_CylinderCPhysicalVolume.insert(phys);
425  }
426 
427  for (int ic = 0; ic < kNcomponents_meca; ic++)
428  {
429  G4String cname = G4String(GetName()) + "_tileC" + "_" + names_meca[ic];
430 
431  RM_meca = Rm_meca + thick_meca[ic];
432 
433  tile_o_comp = new G4Tubs(cname + "_solid",
434  Rm_meca,
435  RM_meca,
436  m_Params->get_double_param("length") * cm / 2.,
437  0,
438  (spacer - 2 * barwidth - 0.001 * mm) / (radius_mecaPCB) *radian);
439  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
440  media_meca[ic],
441  cname + "_logic");
442  vis = new G4VisAttributes(G4Color(color_meca[ic])); // grey is good to see the tracks in the display
443  vis->SetForceSolid(true);
444  vis->SetVisibility(true);
446  tile_o_comp_logic->SetVisAttributes(vis);
447  G4RotationMatrix *zrot_tmp = new G4RotationMatrix();
448  zrot_tmp->rotateZ(360. / Ntiles * deg - (spacer - 2 * barwidth + 1 * mm) / radius_mecaPCB * radian);
449  new G4PVPlacement(G4Transform3D(*zrot_tmp,
450  G4ThreeVector(0, 0, 0)),
451  tile_o_comp_logic,
452  cname + "_phys",
453  u1_C_logic,
454  false,
455  0,
456  OverlapCheck());
457  Rm_meca = RM_meca;
458  }
459 
460  if (nCZlayer == 2)
461  {
462  //Rm += gap;
463  //RM += gap;
464  //Rm_meca = Rm + thickness/2. - thickness_mecaPCB/2.;
465  //RM_meca = Rm_meca;
466  Rm = radius;
467  RM = Rm;
468  Rm_meca = radius_mecaPCB;
469  RM_meca = Rm_meca;
470  // logic volume filled with carbon fiber
471  G4LogicalVolume *u1_Z_logic = new G4LogicalVolume(u1,
472  GetDetectorMaterial("myCfiber"),
473  "u1_Z_logic");
474  vis = new G4VisAttributes(G4Color(G4Colour::Grey())); // grey is good to see the tracks in the display
475  vis->SetForceSolid(false);
476  vis->SetVisibility(true);
478  u1_Z_logic->SetVisAttributes(vis);
479  new G4PVPlacement(0, G4ThreeVector((gap + thickness) * TMath::Cos(360. / Ntiles * deg / 2.), (gap + thickness) * TMath::Sin(360. / Ntiles * deg / 2.), 0),
480  u1_Z_logic,
481  "u1_Z_phys",
482  tile_o_logic, false, 0, OverlapCheck());
483  for (int ic = 0; ic < kNcomponents; ic++)
484  {
485  G4UserLimits *g4userlimits_gas = nullptr;
486  if (ic == Gas2)
487  g4userlimits_gas = g4userlimits;
488 
489  G4String cname = G4String(GetName()) + "_tileZ" + "_" + names[ic];
490 
491  RM = Rm + thick[ic];
492 
493  if (ic == Gas2)
494  {
495  thick[ic] /= nhit;
496  for (int ii = 0; ii < nhit; ii++)
497  {
498  RM = Rm + thick[ic];
499  tile_o_comp = new G4Tubs(cname + "_solid",
500  Rm,
501  RM,
502  m_Params->get_double_param("length") * cm / 2. - gas_deadzone, gas_deadzone / Rm * radian, deltaPhi * deg - 2 * gas_deadzone / Rm * radian);
503  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
504  media[ic],
505  cname + "_logic",
506  nullptr,
507  nullptr,
508  g4userlimits_gas);
509  Rm = RM;
510  }
511  }
512  else
513  {
514  RM = Rm + thick[ic];
515  tile_o_comp = new G4Tubs(cname + "_solid",
516  Rm,
517  RM,
518  m_Params->get_double_param("length") * cm / 2., 0, deltaPhi * deg);
519  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
520  media[ic],
521  cname + "_logic",
522  nullptr,
523  nullptr,
524  g4userlimits_gas);
525  Rm = RM;
526  }
527  vis = new G4VisAttributes(G4Color(color[ic])); // grey is good to see the tracks in the display
528  vis->SetForceSolid(true);
529  vis->SetVisibility(true);
531  tile_o_comp_logic->SetVisAttributes(vis);
532  zrot->setDelta(barwidth / radius * radian);
533  G4VPhysicalVolume *phys = new G4PVPlacement(G4Transform3D(*zrot, G4ThreeVector(0, 0, 0)),
534  tile_o_comp_logic,
535  cname + "_phys",
536  u1_Z_logic, false, 0, OverlapCheck());
537  if (ic == Gas2)
538  m_CylinderZPhysicalVolume.insert(phys);
539  }
540  for (int ic = 0; ic < kNcomponents_meca; ic++)
541  {
542  G4String cname = G4String(GetName()) + "_tileZ" + "_" + names_meca[ic];
543 
544  RM_meca = Rm_meca + thick_meca[ic];
545 
546  tile_o_comp = new G4Tubs(cname + "_solid",
547  Rm_meca,
548  RM_meca,
549  m_Params->get_double_param("length") * cm / 2.,
550  0,
551  (spacer - 2 * barwidth - 0.001 * mm) / (radius_mecaPCB) *radian);
552  tile_o_comp_logic = new G4LogicalVolume(tile_o_comp,
553  media_meca[ic],
554  cname + "_logic");
555  vis = new G4VisAttributes(G4Color(color_meca[ic])); // grey is good to see the tracks in the display
556  vis->SetForceSolid(true);
557  vis->SetVisibility(true);
559  tile_o_comp_logic->SetVisAttributes(vis);
560  G4RotationMatrix *zrot_tmp2 = new G4RotationMatrix();
561  zrot_tmp2->rotateZ(360. / Ntiles * deg - (spacer - 2 * barwidth + 1 * mm) / radius_mecaPCB * radian);
562  new G4PVPlacement(G4Transform3D(*zrot_tmp2,
563  G4ThreeVector(0, 0, 0)),
564  tile_o_comp_logic,
565  cname + "_phys",
566  u1_Z_logic,
567  false,
568  0,
569  OverlapCheck());
570  Rm_meca = RM_meca;
571  }
572  }
573 
574  // repeate N tiles
575  for (int i = 0; i < Ntiles; i++)
576  {
578  yRot->rotateZ(i * 360. / Ntiles * deg);
579  new G4PVPlacement(G4Transform3D(*yRot, G4ThreeVector(0, 0, 0)),
580  tile_o_logic,
581  G4String(GetName()) + "_tile_phys",
582  cylinder_logic,
583  true,
584  i,
585  OverlapCheck());
586  }
587 
588  double phi0 = m_Params->get_double_param("phi0") * deg;
589  G4RotationMatrix *yRot0 = new G4RotationMatrix;
590  yRot0->rotateZ(phi0);
592  cylinder_logic,
593  G4String(GetName()),
594  logicWorld, 0, false, OverlapCheck());
595 }
596 
598 {
599  // get the list of chemical elements
600  // ---------------------------------
601 
602  //G4Element *N = G4Element::GetElement( "N" );
603  //G4Element *O = G4Element::GetElement( "O" );
604  //G4Element *H = G4Element::GetElement( "H" );
605  //G4Element *C = G4Element::GetElement( "C" );
606 
607  // get the list of NIST materials
608  // ---------------------------------
609  G4Material *G4_N = GetDetectorMaterial("G4_N");
610  G4Material *G4_O = GetDetectorMaterial("G4_O");
611  G4Material *G4_C = GetDetectorMaterial("G4_C");
612  G4Material *G4_H = GetDetectorMaterial("G4_H");
613  G4Material *G4_Si = GetDetectorMaterial("G4_Si");
614  G4Material *G4_Ar = GetDetectorMaterial("G4_Ar");
615  G4Material *G4_Cr = GetDetectorMaterial("G4_Cr");
616  G4Material *G4_Fe = GetDetectorMaterial("G4_Fe");
617  G4Material *G4_Mn = GetDetectorMaterial("G4_Mn");
618  G4Material *G4_Ni = GetDetectorMaterial("G4_Ni");
619  G4Material *G4_Cu = GetDetectorMaterial("G4_Cu");
620 
621  // combine elements
622  // ----------------
623  G4int ncomponents;
624  G4double fraction;
625  G4double temperature = 298.15 * kelvin;
626  G4double pressure = 1. * atmosphere;
627 
628  // air
629  if (!GetDetectorMaterial("myAir", false))
630  {
631  G4Material *myAir = new G4Material("myAir", 0.001205 * g / cm3, ncomponents = 2, kStateGas, temperature, pressure);
632  myAir->AddMaterial(G4_N, fraction = 0.77);
633  myAir->AddMaterial(G4_O, fraction = 0.23);
634  }
635 
636  // FR4
637  if (!GetDetectorMaterial("myFR4", false))
638  {
639  G4Material *myFR4 = new G4Material("myFR4", 1.860 * g / cm3, ncomponents = 4, kStateSolid);
640  myFR4->AddMaterial(G4_C, fraction = 0.43550);
641  myFR4->AddMaterial(G4_H, fraction = 0.03650);
642  myFR4->AddMaterial(G4_O, fraction = 0.28120);
643  myFR4->AddMaterial(G4_Si, fraction = 0.24680);
644  }
645 
646  // Kapton
647  if (!GetDetectorMaterial("myKapton", false))
648  {
649  G4Material *myKapton = new G4Material("myKapton", 1.420 * g / cm3, ncomponents = 4, kStateSolid);
650  myKapton->AddMaterial(G4_C, 0.6911330);
651  myKapton->AddMaterial(G4_H, 0.0263620);
652  myKapton->AddMaterial(G4_N, 0.0732700);
653  myKapton->AddMaterial(G4_O, 0.2092350);
654  }
655 
656  // MMgas
657  if (!GetDetectorMaterial("myMMGas", false))
658  {
659  G4Material *myMMGas = new G4Material("myMMGas", 0.00170335 * g / cm3, ncomponents = 3, kStateGas, temperature, pressure);
660  myMMGas->AddMaterial(G4_Ar, 0.900);
661  myMMGas->AddMaterial(G4_C, 0.0826586);
662  myMMGas->AddMaterial(G4_H, 0.0173414);
663  }
664 
665  // MMMesh
666  if (!GetDetectorMaterial("myMMMesh", false))
667  {
668  G4Material *myMMMesh = new G4Material("myMMMesh", 2.8548 * g / cm3, ncomponents = 5, kStateSolid);
669  myMMMesh->AddMaterial(G4_Cr, 0.1900);
670  myMMMesh->AddMaterial(G4_Fe, 0.6800);
671  myMMMesh->AddMaterial(G4_Mn, 0.0200);
672  myMMMesh->AddMaterial(G4_Ni, 0.1000);
673  myMMMesh->AddMaterial(G4_Si, 0.0100);
674  }
675 
676  // MMStrips
677  if (!GetDetectorMaterial("myMMStrips", false))
678  {
679  G4Material *myMMStrips = new G4Material("myMMStrips", 5.248414 * g / cm3, G4_Cu, kStateSolid);
680  cout << myMMStrips->GetName() << endl;
681  }
682 
683  // MMResistivePaste
684  if (!GetDetectorMaterial("myMMResistivePaste", false))
685  {
686  G4Material *myMMResistivePaste = new G4Material("myMMResistivePaste", 0.77906 * g / cm3, G4_C, kStateSolid);
687  cout << myMMResistivePaste->GetName() << endl;
688  }
689 
690  // Copper
691  if (!GetDetectorMaterial("myCopper", false))
692  {
693  G4Material *myCopper = new G4Material("myCopper", 8.9600 * g / cm3, G4_Cu, kStateSolid);
694  cout << myCopper->GetName() << endl;
695  }
696 
697  // Carbon fiber
698  if (!GetDetectorMaterial("myCfiber", false))
699  {
700  G4Material *myCfiber = new G4Material("myCfiber", 1.80 * g / cm3, G4_C, kStateSolid);
701  cout << myCfiber->GetName() << endl;
702  }
703 }
704 
706 {
707  double length = m_Params->get_double_param("length") * cm;
708  G4VSolid *box1 = new G4Box("bar0", barwidth / 2, barwidth / 2, (length + barwidth * 2) / 2);
709  G4VSolid *box2 = new G4Box("bar1", 1 * mm / 2, 1 * mm / 2, (length + barwidth * 2) / 2 + 1 * mm);
710  G4VSolid *bar = new G4SubtractionSolid("HollowBar", box1, box2);
711  return bar;
712 }