Belle II Software  release-05-01-25
MicrotpcCreator.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Martin Ritter, Igal Jaegle *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <beast/microtpc/geometry/MicrotpcCreator.h>
12 #include <beast/microtpc/simulation/SensitiveDetector.h>
13 
14 #include <geometry/Materials.h>
15 #include <geometry/CreatorFactory.h>
16 #include <framework/gearbox/GearDir.h>
17 #include <framework/logging/Logger.h>
18 
19 #include <boost/format.hpp>
20 #include <boost/foreach.hpp>
21 #include <boost/algorithm/string.hpp>
22 
23 #include <G4LogicalVolume.hh>
24 #include <G4PVPlacement.hh>
25 
26 //Shapes
27 #include <G4Box.hh>
28 #include "G4SubtractionSolid.hh"
29 #include <G4UserLimits.hh>
30 #include "G4Tubs.hh"
31 
32 //Visualization
33 #include "G4Colour.hh"
34 #include <G4VisAttributes.hh>
35 
36 using namespace std;
37 using namespace boost;
38 
39 namespace Belle2 {
46  namespace microtpc {
47 
48  // Register the creator
50  geometry::CreatorFactory<MicrotpcCreator> MicrotpcFactory("MICROTPCCreator");
51 
52  MicrotpcCreator::MicrotpcCreator(): m_sensitive(0)
53  {
55  }
56 
57  MicrotpcCreator::~MicrotpcCreator()
58  {
59  if (m_sensitive) delete m_sensitive;
60  }
61 
62  void MicrotpcCreator::create(const GearDir& content, G4LogicalVolume& topVolume, geometry::GeometryTypes /* type */)
63  {
64  G4String symbol;
65  G4double a, z;
66  G4double density, fractionmass;
67  G4int ncomponents, natoms;
68 
69  G4Element* H = new G4Element("Hydrogen", symbol = "H" , z = 1., a = 1.00794 * CLHEP::g / CLHEP::mole);
70  G4Element* He = new G4Element("Helium", symbol = "He" , z = 2., a = 4.002602 * CLHEP::g / CLHEP::mole);
71  G4Element* C = new G4Element("Carbon", symbol = "C" , z = 6., a = 12.01 * CLHEP::g / CLHEP::mole);
72  G4Element* O = new G4Element("Oxygen", symbol = "O", z = 8., a = 16.00 * CLHEP::g / CLHEP::mole);
73  G4Element* Si = new G4Element("Silicon", symbol = "Si" , z = 14., a = 28.09 * CLHEP::g / CLHEP::mole);
74  G4Element* Cl = new G4Element("Chlore", symbol = "Cl" , z = 17., a = 35.453 * CLHEP::g / CLHEP::mole);
75  G4Element* Cu = new G4Element("Copper", symbol = "Cu" , z = 29., a = 63.546 * CLHEP::g / CLHEP::mole);
76  G4Element* Zn = new G4Element("Zinc", symbol = "Zn" , z = 30., a = 65.38 * CLHEP::g / CLHEP::mole);
77 
78  //Helium 4
79  G4Material* gas_4He = new G4Material("gas_4He", density = 0.0001664 * CLHEP::g / CLHEP::cm3, ncomponents = 1, kStateGas,
80  293.15 * CLHEP::kelvin, 1.*CLHEP::atmosphere);
81  gas_4He->AddElement(He, natoms = 1);
82  //C02
83  G4Material* gas_CO2 = new G4Material("gas_CO2", density = 0.001842 * CLHEP::g / CLHEP::cm3, ncomponents = 2, kStateGas,
84  293.15 * CLHEP::kelvin, 1.*CLHEP::atmosphere);
85  gas_CO2->AddElement(C, natoms = 1);
86  gas_CO2->AddElement(O, natoms = 2);
87 
88  //70/30 - 4He/ CO2
89  G4Material* gasmix_4HeCO2 = new G4Material("gasmix_4HeCO2", density = 0.00066908 * CLHEP::g / CLHEP::cm3, ncomponents = 2,
90  kStateGas, 293.15 * CLHEP::kelvin, 1.*CLHEP::atmosphere);
91  gasmix_4HeCO2->AddMaterial(gas_4He, fractionmass = 17.409 * CLHEP::perCent);
92  gasmix_4HeCO2->AddMaterial(gas_CO2, fractionmass = 82.591 * CLHEP::perCent);
93 
94  //c8h7cl
95  G4Material* TPC_ParylenC = new G4Material("TPC_ParylenC", density = 1.298 * CLHEP::g / CLHEP::cm3, ncomponents = 3);
96  TPC_ParylenC->AddElement(H, fractionmass = 0.050908 * CLHEP::perCent);
97  TPC_ParylenC->AddElement(C, fractionmass = 0.693276 * CLHEP::perCent);
98  TPC_ParylenC->AddElement(Cl, fractionmass = 0.255816 * CLHEP::perCent);
99 
100  //G10
101  G4Material* TPC_G10 = new G4Material("TPC_G10", density = 1.700 * CLHEP::g / CLHEP::cm3, ncomponents = 4);
102  TPC_G10->AddElement(Si, natoms = 1);
103  TPC_G10->AddElement(O , natoms = 2);
104  TPC_G10->AddElement(C , natoms = 3);
105  TPC_G10->AddElement(H , natoms = 3);
106 
107  //Cu - copper
108  G4Material* metalCu = new G4Material("MetalCopper", density = 8.960 * CLHEP::g / CLHEP::cm3, ncomponents = 1);
109  metalCu->AddElement(Cu, 1);
110 
111  //Copper screen
112  G4Material* TPC_metaCuScreen = new G4Material("TPC_metaCuScreen", density = 8.95 * CLHEP::g / CLHEP::cm3, ncomponents = 2);
113  TPC_metaCuScreen->AddElement(Cu, fractionmass = 90.*CLHEP::perCent);
114  TPC_metaCuScreen->AddElement(Zn, fractionmass = 10.*CLHEP::perCent);
115 
116 
117  //lets get the stepsize parameter with a default value of 5 µm
118  double stepSize = content.getLength("stepSize", 5 * CLHEP::um);
119 
120  //no get the array. Notice that the default framework unit is cm, so the
121  //values will be automatically converted
122  vector<double> bar = content.getArray("bar");
123  B2INFO("Contents of bar: ");
124  BOOST_FOREACH(double value, bar) {
125  B2INFO("value: " << value);
126  }
127  int detID = 0;
128  //Lets loop over all the Active nodes
129  BOOST_FOREACH(const GearDir & activeParams, content.getNodes("Active")) {
130 
131  G4double inch = 2.54 * CLHEP::cm;
132 
133  //create vessel volume inner volume will be subtracted by "inactive" gas
134  G4double dx_Vessel = activeParams.getLength("dx_Vessel") * CLHEP::cm / 2.;
135  G4double dy_Vessel = activeParams.getLength("dy_Vessel") * CLHEP::cm / 2.;
136  G4double dz_VesselEndCap = 1. / 8. / 2.*inch;
137  G4double dz_Vessel = activeParams.getLength("dz_Vessel") * CLHEP::cm / 2. + dz_VesselEndCap;
138  G4VSolid* s_Vessel = new G4Box("s_Vessel_tmp", dx_Vessel, dy_Vessel, dz_Vessel);
139 
140  G4double width = 1. / 8.*inch;
141  G4double dx_iGasTPC = (dx_Vessel - width);
142  G4double dy_iGasTPC = (dy_Vessel - width);
143  G4double dz_iGasTPC = (dz_Vessel);
144 
145  //create "inactive" gas volume
146  G4VSolid* s_iGasTPC = new G4Box("s_iGasTPC", dx_iGasTPC, dy_iGasTPC, dz_iGasTPC);
147 
148  //create subtraction ie vessel
149  s_Vessel = new G4SubtractionSolid("s_Vessel", s_Vessel, s_iGasTPC, 0, G4ThreeVector(0, 0, 0));
150 
151  G4LogicalVolume* l_Vessel = new G4LogicalVolume(s_Vessel, geometry::Materials::get("TPC_Al6061"), "l_Vessel");
152  G4LogicalVolume* l_iGasTPC = new G4LogicalVolume(s_iGasTPC, gasmix_4HeCO2, "l_iGasTPC");
153 
154  G4RotationMatrix* rotXx = new G4RotationMatrix();
155  G4double AngleX = activeParams.getAngle("AngleX");
156  G4double AngleZ = activeParams.getAngle("AngleZ");
157  rotXx->rotateX(AngleX);
158  rotXx->rotateZ(AngleZ);
159  G4ThreeVector TPCpos = G4ThreeVector(
160  activeParams.getLength("TPCpos_x") * CLHEP::cm,
161  activeParams.getLength("TPCpos_y") * CLHEP::cm,
162  activeParams.getLength("TPCpos_z") * CLHEP::cm
163  );
164 
165  new G4PVPlacement(rotXx, TPCpos, l_Vessel, "p_Vessel", &topVolume, false, 1);
166  new G4PVPlacement(rotXx, TPCpos, l_iGasTPC, "p_iGasTPC", &topVolume, false, 1);
167 
168  B2INFO("Micro-TPC-" << detID << " placed at: " << TPCpos << " mm");
169 
170  /*
171  //create endcap top and bottom
172  G4double dx_VesselEndCap = dx_Vessel;
173  G4double dy_VesselEndCap = dy_Vessel;
174  G4double dz_VesselEndCap = 1. / 8. / 2.*inch;
175  G4VSolid* s_VesselEndCap = new G4Box("s_VesselEndCap", dx_VesselEndCap, dy_VesselEndCap, dz_VesselEndCap);
176 
177  string matEndCap = activeParams.getString("MaterialEndCap");
178  G4LogicalVolume* l_VesselEndCap = new G4LogicalVolume(s_VesselEndCap, geometry::Materials::get(matEndCap), "l_VesselEndCap");
179 
180  G4double x_VesselEndCap[2] = {0, 0};
181  //G4double y_VesselEndCap[2] = {(dz_Vessel + dz_VesselEndCap)* sin(AngleX * CLHEP::deg), (-dz_VesselEndCap - dz_Vessel - 0.00001)* sin(AngleX * CLHEP::deg)};
182  //G4double z_VesselEndCap[2] = {(dz_Vessel + dz_VesselEndCap)* cos(AngleX * CLHEP::deg), (-dz_VesselEndCap - dz_Vessel - 0.00001)* cos(AngleX * CLHEP::deg)};
183  G4double y_VesselEndCap[2] = {(dz_Vessel + dz_VesselEndCap) * sin(AngleX * CLHEP::deg),
184  (-dz_VesselEndCap - dz_Vessel) * sin(AngleX * CLHEP::deg)};
185  G4double z_VesselEndCap[2] = {(dz_Vessel + dz_VesselEndCap) * cos(AngleX * CLHEP::deg),
186  (-dz_VesselEndCap - dz_Vessel) * cos(AngleX * CLHEP::deg)};
187 
188  new G4PVPlacement(rotXx, G4ThreeVector(x_VesselEndCap[0], y_VesselEndCap[0], z_VesselEndCap[0]) + TPCpos, l_VesselEndCap,
189  "p_VesselEndCapTop", &topVolume, false, 1);
190  new G4PVPlacement(rotXx, G4ThreeVector(x_VesselEndCap[1], y_VesselEndCap[1], z_VesselEndCap[1]) + TPCpos, l_VesselEndCap,
191  "p_VesselEndCapBottom", &topVolume, false, 1);
192  */
193  G4VisAttributes* orange = new G4VisAttributes(G4Colour(1, 2, 0));
194  orange->SetForceAuxEdgeVisible(true);
195  //l_VesselEndCap->SetVisAttributes(orange);
196  l_Vessel->SetVisAttributes(orange);
197 
198  G4double dx_parC1 = dx_iGasTPC;
199  G4double dy_parC1 = dy_iGasTPC;
200  G4double dz_parC1 = dz_iGasTPC;
201  G4double cwidth = 0.001 / 2. * inch;
202  G4double dx_parC2 = dx_parC1 - cwidth;
203  G4double dy_parC2 = dy_parC1 - cwidth;
204  G4double dz_parC2 = dz_parC1 - cwidth;
205  G4Box* s_parC1 = new G4Box("s_parC1", dx_parC1, dy_parC1, dz_parC1);
206  G4Box* s_parC2 = new G4Box("s_parC2", dx_parC2, dy_parC2, dz_parC2);
207  G4VSolid* s_parylenC = new G4SubtractionSolid("s_parylenC", s_parC1, s_parC2, 0, G4ThreeVector(0, 0, 0));
208  G4LogicalVolume* l_parylenC = new G4LogicalVolume(s_parylenC, TPC_ParylenC, "l_parylenC");
209  new G4PVPlacement(0, G4ThreeVector(0 * CLHEP::cm, 0 * CLHEP::cm, 0 * CLHEP::cm), l_parylenC, "p_parylenC", l_iGasTPC, false, 1);
210 
211  G4double dx_kap1 = dx_parC2;
212  G4double dy_kap1 = dy_parC2;
213  G4double dz_kap1 = dz_parC2;
214  G4double kwidth = 0.05 / 2. * CLHEP::cm;
215  G4double dx_kap2 = dx_kap1 - kwidth;
216  G4double dy_kap2 = dy_kap1 - kwidth;
217  G4double dz_kap2 = dz_kap1 - kwidth;
218  G4Box* s_kap1 = new G4Box("s_kap1", dx_kap1, dy_kap1, dz_kap1);
219  G4Box* s_kap2 = new G4Box("s_kap2", dx_kap2, dy_kap2, dz_kap2);
220  G4VSolid* s_kapton = new G4SubtractionSolid("s_kapton", s_kap1, s_kap2, 0, G4ThreeVector(0, 0, 0));
221  G4LogicalVolume* l_kapton = new G4LogicalVolume(s_kapton, geometry::Materials::get("TPC_Kapton"), "l_kapton");
222  new G4PVPlacement(0, G4ThreeVector(0 * CLHEP::cm, 0 * CLHEP::cm, 0 * CLHEP::cm), l_kapton, "p_kapton", l_iGasTPC, false, 1);
223 
224  //ring
225  G4double w = 1.4 * CLHEP::cm;
226  G4double rodx = 9.476 * CLHEP::cm;
227  G4double rody = 6.976 * CLHEP::cm;
228  G4double ridx = rodx - w;
229  G4double ridy = rody - w;
230  //rod hole position
231  G4double xrodh = ridx / 2. + w / 8.;
232  G4double yrodh = ridy / 2. + w / 8.;
233 
234  //create rods
235  G4double iR_Rod = 0.*CLHEP::mm;
236  G4double oR_Rod = 5. / 2.*CLHEP::mm;
237  G4double h_Rod = 20. / 2. * CLHEP::cm;
238  G4double sA_Rod = 0.*CLHEP::deg;
239  G4double spA_Rod = 360.*CLHEP::deg;
240  /*cout << "h_Rod " << h_Rod / CLHEP::cm
241  << " dx " << dx_kap2 / CLHEP::cm
242  << " dy " << dy_kap2 / CLHEP::cm
243  << " dz " << dz_kap2 / CLHEP::cm
244  << endl;*/
245  //G4double x_Rod[4] = {3.2 * CLHEP::cm, 3.2 * CLHEP::cm, -3.2 * CLHEP::cm, -3.2 * CLHEP::cm};
246  //G4double y_Rod[4] = {3.2 * CLHEP::cm, -3.2 * CLHEP::cm, 3.2 * CLHEP::cm, -3.2 * CLHEP::cm};
247  G4double x_Rod[4] = {xrodh, xrodh, -xrodh, -xrodh};
248  G4double y_Rod[4] = {yrodh, -yrodh, yrodh, -yrodh};
249  //G4double z_Rod = -dz_iGasTPC + h_Rod;
250  G4double z_Rod = 0. * CLHEP::cm;
251 
252  G4Tubs* s_Rod = new G4Tubs("s_Rod", iR_Rod, oR_Rod, h_Rod, sA_Rod, spA_Rod);
253  G4LogicalVolume* l_Rod = new G4LogicalVolume(s_Rod, geometry::Materials::get("G4_POLYVINYL_ACETATE"), "l_Rod");
254 
255  new G4PVPlacement(0, G4ThreeVector(x_Rod[0], y_Rod[0], z_Rod), l_Rod, "p_Rod_0", l_iGasTPC, false, 1);
256  new G4PVPlacement(0, G4ThreeVector(x_Rod[1], y_Rod[1], z_Rod), l_Rod, "p_Rod_1", l_iGasTPC, false, 1);
257  new G4PVPlacement(0, G4ThreeVector(x_Rod[2], y_Rod[2], z_Rod), l_Rod, "p_Rod_2", l_iGasTPC, false, 1);
258  new G4PVPlacement(0, G4ThreeVector(x_Rod[3], y_Rod[3], z_Rod), l_Rod, "p_Rod_3", l_iGasTPC, false, 1);
259 
260  //create the rings
261  //G4double dx_Ring = 7.4 / 2.*CLHEP::cm;
262  //G4double dy_Ring = 7.4 / 2.*CLHEP::cm;
263  G4double dx_Ring = rodx / 2.;
264  G4double dy_Ring = rody / 2.;
265  G4double dz_Ring = 0.127 / 2.*CLHEP::cm;
266 
267  G4VSolid* s_Ring = new G4Box("s_RingFilled", dx_Ring, dy_Ring, dz_Ring);
268  //G4double dx_RingHole = 5.4 / 2.*CLHEP::cm;
269  //G4double dy_RingHole = 5.4 / 2.*CLHEP::cm;
270  G4double dx_RingHole = xrodh / 2.;
271  G4double dy_RingHole = yrodh / 2.;
272  G4double dz_RingHole = dz_Ring;
273  G4VSolid* s_RingHole = new G4Box("s_RingHole", dx_RingHole, dy_RingHole, dz_RingHole);
274  s_Ring = new G4SubtractionSolid("s_Ring", s_Ring, s_RingHole, 0, G4ThreeVector(0, 0, 0));
275 
276  G4double iR_RingHoles = 0.*CLHEP::mm;
277  G4double oR_RingHoles = oR_Rod;
278  G4double h_RingHoles = dz_Ring;
279  G4double sA_RingHoles = 0.*CLHEP::deg;
280  G4double spA_RingHoles = 360.*CLHEP::deg;
281  G4VSolid* s_RingHoles = new G4Tubs("s_RingHoles", iR_RingHoles, oR_RingHoles, h_RingHoles, sA_RingHoles, spA_RingHoles);
282  char Name[400];
283  for (G4int i = 0; i < 4; i++) {
284  sprintf(Name, "s_Ring_%d", i);
285  s_Ring = new G4SubtractionSolid(Name, s_Ring, s_RingHoles, 0, G4ThreeVector(x_Rod[i], y_Rod[i], 0));
286  }
287 
288  G4LogicalVolume* l_Ring = new G4LogicalVolume(s_Ring, geometry::Materials::get("TPC_Al6061"), "l_Ring");
289  G4int RingNb = 10;
290  G4double hspacer = 1.*CLHEP::cm;
291  G4double offset = dz_iGasTPC - 5.*CLHEP::cm;
292 
293  G4double x_Ring[40];
294  G4double y_Ring[40];
295  G4double z_Ring[40];
296  for (G4int i = 0; i < RingNb; i++) {
297  x_Ring[i] = 0;
298  y_Ring[i] = 0;
299  z_Ring[i] = -dz_iGasTPC + offset + (hspacer + 2. * dz_Ring) * i;
300  //cout << "z ring # " << i << " pos. " << z_Ring[i] / CLHEP::cm << endl;
301  sprintf(Name, "p_Ring_%d", i);
302  new G4PVPlacement(0, G4ThreeVector(x_Ring[i], y_Ring[i], z_Ring[i]), l_Ring, Name, l_iGasTPC, false, 1);
303  }
304 
305  //create anode
306  G4VSolid* s_Anode = new G4Box("s_Anode", dx_Ring, dy_Ring, dz_Ring);
307  for (G4int i = 0; i < 4; i++) {
308  sprintf(Name, "s_Anode_%d", i);
309  s_Anode = new G4SubtractionSolid(Name, s_Anode, s_RingHoles, 0, G4ThreeVector(x_Rod[i], y_Rod[i], 0));
310  }
311  G4LogicalVolume* l_Anode = new G4LogicalVolume(s_Anode, geometry::Materials::get("TPC_Al6061"), "l_Anode");
312  x_Ring[10] = 0;
313  y_Ring[10] = 0;
314  z_Ring[10] = -dz_iGasTPC + offset + (hspacer + 2.*dz_Ring) * RingNb;
315  new G4PVPlacement(0, G4ThreeVector(x_Ring[RingNb], y_Ring[RingNb], z_Ring[RingNb]), l_Anode, "p_Anode", l_iGasTPC, false, 1);
316 
317  //create ring spacer
318  G4double iR_RSpacer = oR_Rod;
319  G4double oR_RSpacer = oR_Rod + 2.*CLHEP::mm;
320  G4double h_RSpacer = (z_Ring[1] - dz_Ring - (z_Ring[0] + dz_Ring)) / 2.;
321  G4double sA_RSpacer = 0.*CLHEP::deg;
322  G4double spA_RSpacer = 360.*CLHEP::deg;
323  G4Tubs* s_RSpacer = new G4Tubs("s_RSpacer1", iR_RSpacer, oR_RSpacer, h_RSpacer, sA_RSpacer, spA_RSpacer);
324  G4LogicalVolume* l_RSpacer = new G4LogicalVolume(s_RSpacer, geometry::Materials::get("G4_POLYVINYL_ACETATE"), "l_RSpacer");
325 
326  G4double x_RSpacer[40];
327  G4double y_RSpacer[40];
328  G4double z_RSpacer[40];
329  for (G4int i = 0; i < 10; i++) {
330  for (G4int k = 0; k < 4; k++) {
331  x_RSpacer[i] = x_Rod[k];
332  y_RSpacer[i] = y_Rod[k];
333  z_RSpacer[i] = z_Ring[i] + dz_Ring + h_RSpacer;
334  sprintf(Name, "p_RSpacer_%d_%d", i, k);
335  new G4PVPlacement(0, G4ThreeVector(x_RSpacer[i], y_RSpacer[i], z_RSpacer[i]), l_RSpacer, Name, l_iGasTPC, false, 1);
336  }
337  }
338 
339  //create GEM
340  G4double dx_GEM = 50. / 2.*CLHEP::mm;
341  G4double dy_GEM = 50. / 2.*CLHEP::mm;
342  G4double dz_GEM = 1.6 / 2.*CLHEP::mm;
343 
344  G4double x_GEM = 0.*CLHEP::cm;
345  G4double y_GEM = 0.*CLHEP::cm;
346  //G4double z_GEM[] = { -dz_iGasTPC + 2.*CLHEP::cm - 0.21 * CLHEP::cm - dz_GEM, -dz_iGasTPC + 2.*CLHEP::cm - dz_GEM};
347  G4double z_GEM[] = { z_Ring[0] - dz_Ring - dz_GEM, z_Ring[0] - dz_Ring - 2. * dz_GEM - 0.28 * CLHEP::cm};
348  /*cout << "ring 1 " << z_Ring[1] / CLHEP::cm << " ring 0 " << z_Ring[0] / CLHEP::cm << " gem 1 " << z_GEM[0] / CLHEP::cm << " gem 2 "
349  << z_GEM[1] / CLHEP::cm << endl;*/
350 
351  G4VSolid* s_GEM = new G4Box("s_GEM", dx_GEM, dy_GEM, dz_GEM);
352  G4LogicalVolume* l_GEM = new G4LogicalVolume(s_GEM, geometry::Materials::get("TPC_Kovar"), "l_GEM");
353  for (G4int i = 0; i < 2; i++) {
354  sprintf(Name, "p_GEM_%d", i);
355  new G4PVPlacement(0, G4ThreeVector(x_GEM, y_GEM, z_GEM[i]), l_GEM, Name, l_iGasTPC, false, 1);
356  }
357 
358  //create GEM support holder
359  G4double dx_GEMSupport = dx_Ring;
360  G4double dy_GEMSupport = dy_Ring;
361  G4double dz_GEMSupport = dz_GEM;
362  G4VSolid* s_GEMSupport = new G4Box("s_GEMSupport1", dx_GEMSupport, dy_GEMSupport, dz_GEMSupport);
363 
364  G4double iR_GEMSupportHoles = 0.*CLHEP::mm;
365  G4double oR_GEMSupportHoles = oR_Rod;
366  G4double h_GEMSupportHoles = dz_GEMSupport;
367  G4double sA_GEMSupportHoles = 0.*CLHEP::deg;
368  G4double spA_GEMSupportHoles = 360.*CLHEP::deg;
369  G4VSolid* s_GEMSupportHoles = new G4Tubs("s_GEMSupportHoles", iR_GEMSupportHoles, oR_GEMSupportHoles, h_GEMSupportHoles,
370  sA_GEMSupportHoles, spA_GEMSupportHoles);
371  s_GEMSupport = new G4SubtractionSolid("s_GEMSupport2", s_GEMSupport, s_GEM, 0, G4ThreeVector(0, 0, 0));
372  for (G4int i = 0; i < 4; i++) {
373  sprintf(Name, "s_GEMSupport_%d", i);
374  s_GEMSupport = new G4SubtractionSolid(Name, s_GEMSupport, s_GEMSupportHoles, 0, G4ThreeVector(x_Rod[i], y_Rod[i], 0));
375  }
376 
377  G4LogicalVolume* l_GEMSupport = new G4LogicalVolume(s_GEMSupport, TPC_G10, "l_GEMSupport");
378  for (G4int i = 0; i < 2; i++) {
379  sprintf(Name, "p_GEMSupport_%d", i);
380  new G4PVPlacement(0, G4ThreeVector(x_GEM, y_GEM, z_GEM[i]), l_GEMSupport, Name, l_iGasTPC, false, 1);
381  }
382  //cout <<"gem 1 " << z_GEM[0] << " gem 2 " << z_GEM[1] << " ring 22 " << z_Ring[22] << " anode " << z_Ring[23] << " dz_GEM " << dz_GEM << " dz_Ring " << dz_Ring << endl;
383  //create sensitive volume
384  G4double dx_GasTPC = 2.95 / 2. * CLHEP::cm;
385  G4double dy_GasTPC = 2.95 / 2. * CLHEP::cm;
386  G4double dz_GasTPC = (z_Ring[10] - dz_Ring - z_GEM[0] - dz_GEM) / 2.; //13.5 * CLHEP::cm;
387  cout << " dz_GasTPC " << dz_GasTPC / CLHEP::cm << endl;
388  G4Box* s_GasTPC = new G4Box("s_GasTPC", dx_GasTPC, dy_GasTPC, dz_GasTPC);
389  G4LogicalVolume* l_GasTPC = new G4LogicalVolume(s_GasTPC, gasmix_4HeCO2, "l_GasTPC", 0, m_sensitive);
390 
391  //Lets limit the Geant4 stepsize inside the volume
392  l_GasTPC->SetUserLimits(new G4UserLimits(stepSize));
393 
394  G4double x_GasTPC = 0;
395  G4double y_GasTPC = 0;
396  G4double z_GasTPC = z_GEM[0] + dz_GEM + dz_GasTPC;
397 
398  new G4PVPlacement(0, G4ThreeVector(x_GasTPC, y_GasTPC, z_GasTPC), l_GasTPC, "p_GasTPC", l_iGasTPC, false, detID);
399 
400  B2INFO("Micro-TPC-Sensitive-Volume-" << detID << " placed at: (" << TPCpos.getX() + x_GasTPC << "," << TPCpos.getY() + y_GasTPC <<
401  "," << TPCpos.getZ() + z_GasTPC << ") mm");
402 
403  //create pixel chip
404  G4double dx_PixelChip = dx_GasTPC;
405  G4double dy_PixelChip = dy_GasTPC;
406  G4double dz_PixelChip = 1. / 2.*CLHEP::mm;
407 
408  G4double x_PixelChip = 0.*CLHEP::mm;
409  G4double y_PixelChip = 0.*CLHEP::mm;
410  G4double z_PixelChip = z_GEM[1] - 0.3 * CLHEP::cm;
411 
412  G4Box* s_PixelChip = new G4Box("s_PixelChip", dx_PixelChip, dy_PixelChip, dz_PixelChip);
413  G4LogicalVolume* l_PixelChip = new G4LogicalVolume(s_PixelChip, geometry::Materials::get("G4_PLASTIC_SC_VINYLTOLUENE"),
414  "l_PixelChip");
415  new G4PVPlacement(0, G4ThreeVector(x_PixelChip, y_PixelChip, z_PixelChip), l_PixelChip, "p_PixelChip", l_iGasTPC, false, 1);
416 
417  //create cu plate
418  G4double dx_CuPlate = dx_Ring;
419  G4double dy_CuPlate = dy_Ring;
420  G4double dz_CuPlate = dz_PixelChip;
421 
422  G4VSolid* s_CuPlate = new G4Box("s_CuPlate", dx_CuPlate, dy_CuPlate, dz_CuPlate);
423  G4VSolid* s_HolesInCuPlate = new G4Tubs("HolesInCuPlate", iR_RingHoles, oR_RingHoles, dz_PixelChip, sA_RingHoles, spA_RingHoles);
424  for (G4int i = 0; i < 4; i++) {
425  sprintf(Name, "s_CuPlate_%d", i);
426  s_CuPlate = new G4SubtractionSolid(Name, s_CuPlate, s_HolesInCuPlate, 0, G4ThreeVector(x_Rod[i], y_Rod[i], 0));
427  }
428  s_CuPlate = new G4SubtractionSolid("s_CuPlate", s_CuPlate, s_PixelChip, 0, G4ThreeVector(0, 0, 0));
429 
430 
431  G4LogicalVolume* l_CuPlate = new G4LogicalVolume(s_CuPlate, TPC_metaCuScreen, "l_CuPlate");
432  new G4PVPlacement(0, G4ThreeVector(x_PixelChip, y_PixelChip, z_PixelChip), l_CuPlate, "p_CuPlate", l_iGasTPC, false, 1);
433 
434  //create pixel board
435  G4double dx_PixelBoard = dx_Ring;
436  G4double dy_PixelBoard = dy_Ring;
437  G4double dz_PixelBoard = 2.*CLHEP::mm;
438 
439  G4VSolid* s_PixelBoard = new G4Box("s_PixelBoard1", dx_PixelBoard, dy_PixelBoard, dz_PixelBoard);
440  G4VSolid* s_PixelBoardHoles = new G4Tubs("s_PixelBoardHoles", iR_RingHoles, oR_RingHoles, dz_PixelBoard, sA_RingHoles,
441  spA_RingHoles);
442  for (G4int i = 0; i < 4; i++) {
443  sprintf(Name, "s_PixelBoard_%d", i);
444  s_PixelBoard = new G4SubtractionSolid(Name, s_PixelBoard, s_PixelBoardHoles, 0, G4ThreeVector(x_Rod[i], y_Rod[i], 0));
445  }
446 
447  G4double x_PixelBoard = 0.*CLHEP::mm;
448  G4double y_PixelBoard = 0.*CLHEP::mm;
449  G4double z_PixelBoard = z_PixelChip - dz_PixelBoard - dz_PixelChip;
450 
451  G4LogicalVolume* l_PixelBoard = new G4LogicalVolume(s_PixelBoard, TPC_G10, "l_PixelBoard");
452 
453  new G4PVPlacement(0, G4ThreeVector(x_PixelBoard, y_PixelBoard, z_PixelBoard), l_PixelBoard, "p_PixelBoard", l_iGasTPC, false, 1);
454  detID++;
455  }
456  }
457  } // microtpc namespace
459 } // Belle2 namespace
Belle2::gearbox::Interface::getAngle
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
Definition: Interface.h:301
Belle2::geometry::Materials::get
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:65
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::microtpc::MicrotpcCreator::m_sensitive
SensitiveDetector * m_sensitive
SensitiveDetector micro-tpc.
Definition: MicrotpcCreator.h:36
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::gearbox::Interface::getLength
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:261
Belle2::PXD::SensitiveDetector
VXD::SensitiveDetector< PXDSimHit, PXDTrueHit > SensitiveDetector
The PXD Sensitive Detector class.
Definition: SensitiveDetector.h:36
Belle2::microtpc::MicrotpcCreator::create
virtual void create(const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Function to actually create the geometry, has to be overridden by derived classes.
Definition: MicrotpcCreator.cc:62
Belle2::geometry::GeometryTypes
GeometryTypes
Flag indiciating the type of geometry to be used.
Definition: GeometryManager.h:39
Belle2::microtpc::MicrotpcFactory
geometry::CreatorFactory< MicrotpcCreator > MicrotpcFactory("MICROTPCCreator")
Creator creates the micro-tpc geometry.