Belle II Software  release-06-01-15
GeoCryostatCreator.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <ir/geometry/GeoCryostatCreator.h>
10 #include <ir/simulation/SensitiveDetector.h>
11 
12 #include <geometry/Materials.h>
13 #include <geometry/CreatorFactory.h>
14 #include <geometry/utilities.h>
15 #include <framework/gearbox/Unit.h>
16 
17 #include <cmath>
18 #include <boost/format.hpp>
19 #include <boost/foreach.hpp>
20 #include <boost/algorithm/string.hpp>
21 
22 #include <G4LogicalVolume.hh>
23 #include <G4PVPlacement.hh>
24 
25 //Shapes
26 #include <G4Tubs.hh>
27 #include <G4Polycone.hh>
28 #include <G4EllipticalTube.hh>
29 #include <G4UnionSolid.hh>
30 #include <G4IntersectionSolid.hh>
31 #include <G4SubtractionSolid.hh>
32 #include <G4UserLimits.hh>
33 
34 using namespace std;
35 using namespace boost;
36 
37 namespace Belle2 {
44  using namespace geometry;
45 
46  namespace ir {
47 
48  //-----------------------------------------------------------------
49  // Register the Creator
50  //-----------------------------------------------------------------
51 
52  geometry::CreatorFactory<GeoCryostatCreator> GeoCryostatFactory("CryostatCreator");
53 
54  //-----------------------------------------------------------------
55  // Implementation
56  //-----------------------------------------------------------------
57 
58  GeoCryostatCreator::GeoCryostatCreator()
59  {
60  m_sensitive = new SensitiveDetector();
61  }
62 
63  GeoCryostatCreator::~GeoCryostatCreator()
64  {
65  delete m_sensitive;
66  }
67 
68  void GeoCryostatCreator::createGeometry(G4LogicalVolume& topVolume, GeometryTypes)
69  {
70 
71  //###### L side index ######
72  //
73  // +- A1spc1+A1spc2
74  // +- A2wal1
75  // +- A3wal1
76  // +- A3wal2
77  // +- A4mag1
78  // +- A4mag2
79  // +- A4mag3
80  // +- A4mag4
81  //
82  // +- B1spc1+B1spc2
83  // +- B2wal1
84  // +- B3wal1
85  // +- B3wal2
86  // +- B4mag1
87  // +- B4mag2
88  // +- B4mag3
89  // +- B4mag4
90  //
91  // +- C1wal1
92  // +- C2spc1
93  // +- C3wal1
94  // +- C4spc1
95  // +- C5wal1
96  // +- C6spc1
97  // +- C7lyr1
98  // +- C7lyr2
99  // +- C7lyr3
100  // +- C7lyr4
101  // +- C7lyr5
102  // +- C2spc2
103  // +- C3wal2
104  // +- C4spc2
105  // +- C5wal2
106  // +- C6spc2
107  // +- C7wal1
108  // +- C5wal3
109  // +- C5wal4
110  // +- C3wal3
111  // +- C2spc3
112  // +- C1wal2
113  //
114  //###### R side index ######
115  //
116  // +- D1spc1
117  // +- D2wal1
118  // +- D3wal1
119  // +- D3wal2
120  // +- D4mag1
121  // +- D4mag2
122  // +- D4mag3
123  //
124  // +- E1spc1
125  // +- E2wal1
126  // +- E3wal1
127  // +- E4mag1
128  // +- E4mag2
129  // +- E4mag3
130  //
131  // +- F1wal1
132  // +- F2spc1
133  // +- F3wal1
134  // +- F4spc1
135  // +- F5wal1
136  // +- F6spc1
137  // +- F7lyr1
138  // +- F7lyr2
139  // +- F7lyr3
140  // +- F7lyr4
141  // +- F7lyr5
142  // +- F3wal2
143  // +- F3wal3
144  // +- F3wal4
145  // +- F1wal2
146 
147  double stepMax = 5.0 * Unit::mm;
148  int flag_limitStep = int(m_config.getParameter("LimitStepLength"));
149 
150  const double unitFactor = Unit::cm / Unit::mm;
151 
152  double crossingAngleHER = m_config.getParameter("CrossingAngle.HER", 0.0415);
153  double crossingAngleLER = m_config.getParameter("CrossingAngle.LER", -0.0415);
154 
155  G4Transform3D transform_HER = G4Translate3D(0., 0., 0.);
156  transform_HER = transform_HER * G4RotateY3D(crossingAngleHER);
157 
158  G4Transform3D transform_LER = G4Translate3D(0., 0., 0.);
159  transform_LER = transform_LER * G4RotateY3D(crossingAngleLER);
160 
161  map<string, CryostatElement> elements;
162 
163  //--------------
164  //- Bounding shapes
165 
166  // right bounding shape 1
167  CryostatElement tubeR;
168  std::string prep = "TubeR.";
169 
170  const int TubeR_N = int(m_config.getParameter(prep + "N"));
171 
172  std::vector<double> TubeR_Z(TubeR_N);
173  std::vector<double> TubeR_R(TubeR_N);
174  std::vector<double> TubeR_r(TubeR_N);
175 
176  for (int i = 0; i < TubeR_N; ++i) {
177  ostringstream ossZID;
178  ossZID << "Z" << i;
179 
180  ostringstream ossRID;
181  ossRID << "R" << i;
182 
183  ostringstream ossrID;
184  ossrID << "r" << i;
185 
186  TubeR_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
187  TubeR_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
188  TubeR_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
189  }
190 
191  tubeR.transform = G4Translate3D(0., 0., 0.);
192  tubeR.geo = new G4Polycone("geo_TubeR_name", 0, 2 * M_PI, TubeR_N, &(TubeR_Z[0]), &(TubeR_r[0]), &(TubeR_R[0]));
193  tubeR.logi = NULL;
194  elements["TubeR"] = tubeR;
195 
196  // right bounding shape 2
197  CryostatElement tubeR2;
198  prep = "TubeR2.";
199  const int TubeR2_N = int(m_config.getParameter(prep + "N"));
200 
201  std::vector<double> TubeR2_Z(TubeR2_N);
202  std::vector<double> TubeR2_R(TubeR2_N);
203  std::vector<double> TubeR2_r(TubeR2_N);
204 
205  for (int i = 0; i < TubeR2_N; ++i) {
206  ostringstream ossZID;
207  ossZID << "Z" << i;
208 
209  ostringstream ossRID;
210  ossRID << "R" << i;
211 
212  ostringstream ossrID;
213  ossrID << "r" << i;
214 
215  TubeR2_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
216  TubeR2_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
217  TubeR2_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
218  }
219 
220  tubeR2.transform = G4Translate3D(0., 0., 0.);
221  tubeR2.geo = new G4Polycone("geo_TubeR2_name", 0, 2 * M_PI, TubeR2_N, &(TubeR2_Z[0]), &(TubeR2_r[0]), &(TubeR2_R[0]));
222  tubeR2.logi = NULL;
223  elements["TubeR2"] = tubeR2;
224 
225  // left bounding shape
226  CryostatElement tubeL;
227  prep = "TubeL.";
228  const int TubeL_N = int(m_config.getParameter(prep + "N"));
229 
230  std::vector<double> TubeL_Z(TubeL_N);
231  std::vector<double> TubeL_R(TubeL_N);
232  std::vector<double> TubeL_r(TubeL_N);
233 
234  for (int i = 0; i < TubeL_N; ++i) {
235  ostringstream ossZID;
236  ossZID << "Z" << i;
237 
238  ostringstream ossRID;
239  ossRID << "R" << i;
240 
241  ostringstream ossrID;
242  ossrID << "r" << i;
243 
244  TubeL_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
245  TubeL_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
246  TubeL_r[i] = m_config.getParameter(prep + ossrID.str()) * unitFactor;
247  }
248 
249  tubeL.transform = G4Translate3D(0., 0., 0.);
250  tubeL.geo = new G4Polycone("geo_TubeL_name", 0, 2 * M_PI, TubeL_N, &(TubeL_Z[0]), &(TubeL_r[0]), &(TubeL_R[0]));
251  tubeL.logi = NULL;
252  elements["TubeL"] = tubeL;
253 
254  //--------------
255  // Special cases with complex geometry
256 
257  //--------------
258  //- A1spc1 and B1spc1
259 
260  // space containing all structures around right HER beam pipe, part 1
261  CryostatElement A1spc1;
262  prep = "A1spc1.";
263  const int A1spc1_N = int(m_config.getParameter(prep + "N"));
264 
265  std::vector<double> A1spc1_Z(A1spc1_N);
266  std::vector<double> A1spc1_r(A1spc1_N);
267  std::vector<double> A1spc1_R(A1spc1_N);
268 
269  for (int i = 0; i < A1spc1_N; ++i) {
270  ostringstream ossZID;
271  ossZID << "Z" << i;
272 
273  ostringstream ossRID;
274  ossRID << "R" << i;
275 
276  ostringstream ossrID;
277  ossrID << "r" << i;
278 
279  A1spc1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
280  A1spc1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
281  A1spc1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
282  }
283 
284  A1spc1.transform = transform_HER;
285  G4Polycone* geo_A1spc1xx = new G4Polycone("geo_A1spc1xx_name", 0, 2 * M_PI, A1spc1_N, &(A1spc1_Z[0]), &(A1spc1_r[0]),
286  &(A1spc1_R[0]));
287 
288  // space containing all structures around right HER beam pipe, part 2
289  CryostatElement A1spc2;
290  prep = "A1spc2.";
291  const int A1spc2_N = int(m_config.getParameter(prep + "N"));
292 
293  std::vector<double> A1spc2_Z(A1spc2_N);
294  std::vector<double> A1spc2_R(A1spc2_N);
295  std::vector<double> A1spc2_r(A1spc2_N);
296 
297  for (int i = 0; i < A1spc2_N; ++i) {
298  ostringstream ossZID;
299  ossZID << "Z" << i;
300 
301  ostringstream ossRID;
302  ossRID << "R" << i;
303 
304  ostringstream ossrID;
305  ossrID << "r" << i;
306 
307  A1spc2_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
308  A1spc2_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
309  A1spc2_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
310  }
311 
312  A1spc2.transform = transform_HER;
313  G4Polycone* geo_A1spc2xx = new G4Polycone("geo_A1spc2xx_name", 0, 2 * M_PI, A1spc2_N, &(A1spc2_Z[0]), &(A1spc2_r[0]),
314  &(A1spc2_R[0]));
315 
316  // space containing all structures around right LER beam pipe, part 1
317  CryostatElement B1spc1;
318  prep = "B1spc1.";
319  const int B1spc1_N = int(m_config.getParameter(prep + "N"));
320 
321  std::vector<double> B1spc1_Z(B1spc1_N);
322  std::vector<double> B1spc1_R(B1spc1_N);
323  std::vector<double> B1spc1_r(B1spc1_N);
324 
325  for (int i = 0; i < B1spc1_N; ++i) {
326  ostringstream ossZID;
327  ossZID << "Z" << i;
328 
329  ostringstream ossRID;
330  ossRID << "R" << i;
331 
332  ostringstream ossrID;
333  ossrID << "r" << i;
334 
335  B1spc1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
336  B1spc1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
337  B1spc1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
338  }
339 
340  B1spc1.transform = transform_LER;
341  G4Polycone* geo_B1spc1xx = new G4Polycone("geo_B1spc1xx_name", 0, 2 * M_PI, B1spc1_N, &(B1spc1_Z[0]), &(B1spc1_r[0]),
342  &(B1spc1_R[0]));
343 
344  // space containing all structures around right LER beam pipe, part 2
345  CryostatElement B1spc2;
346  prep = "B1spc2.";
347  const int B1spc2_N = int(m_config.getParameter(prep + "N"));
348 
349  std::vector<double> B1spc2_Z(B1spc2_N);
350  std::vector<double> B1spc2_R(B1spc2_N);
351  std::vector<double> B1spc2_r(B1spc2_N);
352 
353  for (int i = 0; i < B1spc2_N; ++i) {
354  ostringstream ossZID;
355  ossZID << "Z" << i;
356 
357  ostringstream ossRID;
358  ossRID << "R" << i;
359 
360  ostringstream ossrID;
361  ossrID << "r" << i;
362 
363  B1spc2_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
364  B1spc2_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
365  B1spc2_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
366  }
367 
368  B1spc2.transform = transform_LER;
369  G4Polycone* geo_B1spc2xx = new G4Polycone("geo_B1spc2xx_name", 0, 2 * M_PI, B1spc2_N, &(B1spc2_Z[0]), &(B1spc2_r[0]),
370  &(B1spc2_R[0]));
371 
372  // final cut
373  B1spc2.geo = new G4IntersectionSolid("geo_B1spc2_name", geo_B1spc2xx, elements["TubeR2"].geo, B1spc2.transform.inverse());
374  B1spc2.logi = NULL;
375 
376  G4IntersectionSolid* geo_B1spc1x = new G4IntersectionSolid("geo_B1spc1x_name", geo_B1spc1xx, elements["TubeR"].geo,
377  B1spc1.transform.inverse());
378  B1spc1.geo = new G4UnionSolid("geo_B1spc1_name", geo_B1spc1x, B1spc2.geo);
379 
380  A1spc2.geo = new G4IntersectionSolid("geo_A1spc2_name", geo_A1spc2xx, elements["TubeR2"].geo, A1spc2.transform.inverse());
381  A1spc2.logi = NULL;
382 
383  G4IntersectionSolid* geo_A1spc1xy = new G4IntersectionSolid("geo_A1spc1xy_name", geo_A1spc1xx, elements["TubeR"].geo,
384  A1spc1.transform.inverse());
385  G4UnionSolid* geo_A1spc1x = new G4UnionSolid("geo_A1spc1x_name", geo_A1spc1xy, A1spc2.geo);
386  A1spc1.geo = new G4SubtractionSolid("geo_A1spc1_name", geo_A1spc1x, B1spc1.geo, A1spc1.transform.inverse()*B1spc1.transform);
387 
388  string strMat_A1spc1 = m_config.getParameterStr("A1spc1.Material");
389  G4Material* mat_A1spc1 = Materials::get(strMat_A1spc1);
390  A1spc1.logi = new G4LogicalVolume(A1spc1.geo, mat_A1spc1, "logi_A1spc1_name");
391  if (flag_limitStep)
392  A1spc1.logi->SetUserLimits(new G4UserLimits(stepMax));
393 
394  //put volume
395  setColor(*A1spc1.logi, "#CC0000");
396  //setVisibility(*A1spc1.logi, false);
397  new G4PVPlacement(A1spc1.transform, A1spc1.logi, "phys_A1spc1_name", &topVolume, false, 0);
398 
399  string strMat_B1spc1 = m_config.getParameterStr("B1spc1.Material");
400  G4Material* mat_B1spc1 = Materials::get(strMat_B1spc1);
401  B1spc1.logi = new G4LogicalVolume(B1spc1.geo, mat_B1spc1, "logi_B1spc1_name");
402  if (flag_limitStep)
403  B1spc1.logi->SetUserLimits(new G4UserLimits(stepMax));
404 
405  //put volume
406  setColor(*B1spc1.logi, "#CC0000");
407  //setVisibility(*B1spc1.logi, false);
408  new G4PVPlacement(B1spc1.transform, B1spc1.logi, "phys_B1spc1_name", &topVolume, false, 0);
409 
410  elements["A1spc1"] = A1spc1;
411  elements["A1spc2"] = A1spc2;
412  elements["B1spc1"] = B1spc1;
413  elements["B1spc2"] = B1spc2;
414 
415  //--------------
416  //- C1wal1
417 
418  //get parameters from .xml file
419  CryostatElement C1wal1;
420  prep = "C1wal1.";
421  const int C1wal1_N = m_config.getParameter(prep + "N");
422 
423  std::vector<double> C1wal1_Z(C1wal1_N);
424  std::vector<double> C1wal1_R(C1wal1_N);
425  std::vector<double> C1wal1_r(C1wal1_N);
426 
427  for (int i = 0; i < C1wal1_N; ++i) {
428  ostringstream ossZID;
429  ossZID << "Z" << i;
430 
431  ostringstream ossRID;
432  ossRID << "R" << i;
433 
434  ostringstream ossrID;
435  ossrID << "r" << i;
436 
437  C1wal1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
438  C1wal1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
439  C1wal1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
440  }
441 
442  C1wal1.transform = G4Translate3D(0., 0., 0.);
443 
444  //define geometry
445  G4Polycone* geo_C1wal1xxx = new G4Polycone("geo_C1wal1xxx_name", 0, 2 * M_PI, C1wal1_N, &(C1wal1_Z[0]), &(C1wal1_r[0]),
446  &(C1wal1_R[0]));
447  G4IntersectionSolid* geo_C1wal1xx = new G4IntersectionSolid("geo_C1wal1xx_name", geo_C1wal1xxx, elements["TubeR"].geo,
448  elements["TubeR"].transform);
449  G4SubtractionSolid* geo_C1wal1x = new G4SubtractionSolid("geo_C1wal1x_name", geo_C1wal1xx, elements["A1spc1"].geo,
450  elements["A1spc1"].transform);
451  C1wal1.geo = new G4SubtractionSolid("geo_C1wal1_name", geo_C1wal1x, elements["B1spc1"].geo, elements["B1spc1"].transform);
452 
453  string strMat_C1wal1 = m_config.getParameterStr(prep + "Material");
454  G4Material* mat_C1wal1 = Materials::get(strMat_C1wal1);
455  C1wal1.logi = new G4LogicalVolume(C1wal1.geo, mat_C1wal1, "logi_C1wal1_name");
456 
457  //put volume
458  setColor(*C1wal1.logi, "#CC0000");
459  setVisibility(*C1wal1.logi, false);
460  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), C1wal1.logi, "phys_C1wal1_name", &topVolume, false, 0);
461 
462  elements["C1wal1"] = C1wal1;
463 
464  //--------------
465  //- D1spc1 and E1spc1
466 
467  // space containing all structures around left HER beam pipe
468  CryostatElement D1spc1;
469  prep = "D1spc1.";
470  const int D1spc1_N = m_config.getParameter(prep + "N");
471 
472  std::vector<double> D1spc1_Z(D1spc1_N);
473  std::vector<double> D1spc1_r(D1spc1_N);
474  std::vector<double> D1spc1_R(D1spc1_N);
475 
476  for (int i = 0; i < D1spc1_N; ++i) {
477  ostringstream ossZID;
478  ossZID << "Z" << i;
479 
480  ostringstream ossRID;
481  ossRID << "R" << i;
482 
483  ostringstream ossrID;
484  ossrID << "r" << i;
485 
486  D1spc1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
487  D1spc1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
488  D1spc1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
489  }
490 
491  D1spc1.transform = transform_HER;
492  G4Polycone* geo_D1spc1xx = new G4Polycone("geo_D1spc1xx_name", 0, 2 * M_PI, D1spc1_N, &(D1spc1_Z[0]), &(D1spc1_r[0]),
493  &(D1spc1_R[0]));
494 
495  // space containing all structures around left LER beam pipe
496  CryostatElement E1spc1;
497  prep = "E1spc1.";
498  const int E1spc1_N = int(m_config.getParameter(prep + "N"));
499 
500  std::vector<double> E1spc1_Z(E1spc1_N);
501  std::vector<double> E1spc1_R(E1spc1_N);
502  std::vector<double> E1spc1_r(E1spc1_N);
503 
504  for (int i = 0; i < E1spc1_N; ++i) {
505  ostringstream ossZID;
506  ossZID << "Z" << i;
507 
508  ostringstream ossRID;
509  ossRID << "R" << i;
510 
511  ostringstream ossrID;
512  ossrID << "r" << i;
513 
514  E1spc1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
515  E1spc1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
516  E1spc1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
517  }
518 
519  E1spc1.transform = transform_LER;
520  G4Polycone* geo_E1spc1xx = new G4Polycone("geo_E1spc1xx_name", 0, 2 * M_PI, E1spc1_N, &(E1spc1_Z[0]), &(E1spc1_r[0]),
521  &(E1spc1_R[0]));
522 
523  // final cut
524  G4IntersectionSolid* geo_D1spc1x = new G4IntersectionSolid("geo_D1spc1x_name", geo_D1spc1xx, elements["TubeL"].geo,
525  D1spc1.transform.inverse());
526  E1spc1.geo = new G4IntersectionSolid("geo_E1spc1_name", geo_E1spc1xx, elements["TubeL"].geo, E1spc1.transform.inverse());
527  D1spc1.geo = new G4SubtractionSolid("geo_D1spc1_name", geo_D1spc1x, E1spc1.geo, D1spc1.transform.inverse()*E1spc1.transform);
528 
529  string strMat_D1spc1 = m_config.getParameterStr("D1spc1.Material");
530  G4Material* mat_D1spc1 = Materials::get(strMat_D1spc1);
531  D1spc1.logi = new G4LogicalVolume(D1spc1.geo, mat_D1spc1, "logi_D1spc1_name");
532  if (flag_limitStep)
533  D1spc1.logi->SetUserLimits(new G4UserLimits(stepMax));
534 
535  //put volume
536  setColor(*D1spc1.logi, "#CC0000");
537  //setVisibility(*D1spc1.logi, false);
538  new G4PVPlacement(D1spc1.transform, D1spc1.logi, "phys_D1spc1_name", &topVolume, false, 0);
539 
540  string strMat_E1spc1 = m_config.getParameterStr(prep + "Material");
541  G4Material* mat_E1spc1 = Materials::get(strMat_E1spc1);
542  E1spc1.logi = new G4LogicalVolume(E1spc1.geo, mat_E1spc1, "logi_E1spc1_name");
543  if (flag_limitStep)
544  E1spc1.logi->SetUserLimits(new G4UserLimits(stepMax));
545 
546  //put volume
547  setColor(*E1spc1.logi, "#CC0000");
548  //setVisibility(*E1spc1.logi, false);
549  new G4PVPlacement(E1spc1.transform, E1spc1.logi, "phys_E1spc1_name", &topVolume, false, 0);
550 
551  elements["E1spc1"] = E1spc1;
552  elements["D1spc1"] = D1spc1;
553 
554 
555  //--------------
556  //- F1wal1
557 
558  //get parameters from .xml file
559  CryostatElement F1wal1;
560  prep = "F1wal1.";
561  const int F1wal1_N = int(m_config.getParameter(prep + "N"));
562 
563  std::vector<double> F1wal1_Z(F1wal1_N);
564  std::vector<double> F1wal1_R(F1wal1_N);
565  std::vector<double> F1wal1_r(F1wal1_N);
566 
567  for (int i = 0; i < F1wal1_N; ++i) {
568  ostringstream ossZID;
569  ossZID << "Z" << i;
570 
571  ostringstream ossRID;
572  ossRID << "R" << i;
573 
574  ostringstream ossrID;
575  ossrID << "r" << i;
576 
577  F1wal1_Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
578  F1wal1_R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
579  F1wal1_r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
580  }
581 
582  F1wal1.transform = G4Translate3D(0., 0., 0.);
583 
584  //define geometry
585  G4Polycone* geo_F1wal1xxx = new G4Polycone("geo_F1wal1xxx_name", 0, 2 * M_PI, F1wal1_N, &(F1wal1_Z[0]), &(F1wal1_r[0]),
586  &(F1wal1_R[0]));
587  G4IntersectionSolid* geo_F1wal1xx = new G4IntersectionSolid("geo_F1wal1xx_name", geo_F1wal1xxx, elements["TubeL"].geo,
588  elements["TubeL"].transform);
589  G4SubtractionSolid* geo_F1wal1x = new G4SubtractionSolid("geo_F1wal1x_name", geo_F1wal1xx, elements["D1spc1"].geo,
590  elements["D1spc1"].transform);
591  F1wal1.geo = new G4SubtractionSolid("geo_F1wal1_name", geo_F1wal1x, elements["E1spc1"].geo, elements["E1spc1"].transform);
592 
593  string strMat_F1wal1 = m_config.getParameterStr(prep + "Material");
594  G4Material* mat_F1wal1 = Materials::get(strMat_F1wal1);
595  F1wal1.logi = new G4LogicalVolume(F1wal1.geo, mat_F1wal1, "logi_F1wal1_name");
596 
597  //put volume
598  setColor(*F1wal1.logi, "#CC0000");
599  setVisibility(*F1wal1.logi, false);
600  new G4PVPlacement(F1wal1.transform, F1wal1.logi, "phys_F1wal1_name", &topVolume, false, 0);
601 
602  elements["F1wal1"] = F1wal1;
603 
604 
605  //--------------
606  //- Rest of elements with typical geometry
607  std::vector<std::string> straightSections;
608  boost::split(straightSections, m_config.getParameterStr("Straight"), boost::is_any_of(" "));
609  for (const auto& name : straightSections) {
610  prep = name + ".";
611 
612  CryostatElement polycone;
613 
614  int N = int(m_config.getParameter(prep + "N"));
615 
616  std::vector<double> Z(N);
617  std::vector<double> R(N);
618  std::vector<double> r(N);
619 
620  for (int i = 0; i < N; ++i) {
621  ostringstream ossZID;
622  ossZID << "Z" << i;
623 
624  ostringstream ossRID;
625  ossRID << "R" << i;
626 
627  ostringstream ossrID;
628  ossrID << "r" << i;
629 
630  Z[i] = m_config.getParameter(prep + ossZID.str()) * unitFactor;
631  R[i] = m_config.getParameter(prep + ossRID.str()) * unitFactor;
632  r[i] = m_config.getParameter(prep + ossrID.str(), 0.0) * unitFactor;
633  }
634 
635  polycone.transform = G4Translate3D(0.0, 0.0, 0.0);
636 
637  //define geometry
638  string motherVolume = m_config.getParameterStr(prep + "MotherVolume");
639  string subtract = m_config.getParameterStr(prep + "Subtract", "");
640  string intersect = m_config.getParameterStr(prep + "Intersect", "");
641 
642  string geo_polyconexx_name = "geo_" + name + "xx_name";
643  string geo_polyconex_name = "geo_" + name + "x_name";
644  string geo_polycone_name = "geo_" + name + "_name";
645 
646  G4VSolid* geo_polyconexx, *geo_polycone;
647 
648  if (subtract != "" && intersect != "") {
649  geo_polyconexx = new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
650  G4VSolid* geo_polyconex = new G4SubtractionSolid(geo_polyconex_name, geo_polyconexx, elements[subtract].geo,
651  elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[subtract].transform);
652  geo_polycone = new G4IntersectionSolid(geo_polycone_name, geo_polyconex, elements[intersect].geo,
653  elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[intersect].transform);
654  } else if (subtract != "") {
655  geo_polyconexx = new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
656  geo_polycone = new G4SubtractionSolid(geo_polycone_name, geo_polyconexx, elements[subtract].geo,
657  elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[subtract].transform);
658  } else if (intersect != "") {
659  geo_polyconexx = new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
660  geo_polycone = new G4IntersectionSolid(geo_polycone_name, geo_polyconexx, elements[intersect].geo,
661  elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[intersect].transform);
662  } else
663  geo_polycone = new G4Polycone(geo_polycone_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
664 
665  polycone.geo = geo_polycone;
666 
667  // define logical volume
668  string strMat_polycone = m_config.getParameterStr(prep + "Material");
669  G4Material* mat_polycone = Materials::get(strMat_polycone);
670  string logi_polycone_name = "logi_" + name + "_name";
671  polycone.logi = new G4LogicalVolume(polycone.geo, mat_polycone, logi_polycone_name);
672  setColor(*polycone.logi, "#CC0000");
673  setVisibility(*polycone.logi, false);
674 
675  //put volume
676  string phys_polycone_name = "phys_" + name + "_name";
677  new G4PVPlacement(polycone.transform, polycone.logi, phys_polycone_name, elements[motherVolume].logi, false, 0);
678 
679  //to use it later in "intersect" and "subtract"
680  polycone.transform = polycone.transform * elements[motherVolume].transform;
681 
682  elements[name] = polycone;
683  }
684 
685  // RVC connection structure (simplified shape)
686  G4Tubs* geo_rvcR = new G4Tubs("geo_rvcR", 60, 60 + 60, (620 - 560) / 2., 0, 2 * M_PI);
687  G4LogicalVolume* logi_rvcR = new G4LogicalVolume(geo_rvcR, Materials::get("SUS316L"), "logi_rvcR_name");
688  new G4PVPlacement(0, G4ThreeVector(0, 0, (620 + 560) / 2.), logi_rvcR, "phys_rvcR_name", &topVolume, false, 0);
689 
690  G4Tubs* geo_rvcL = new G4Tubs("geo_rvcL", 60, 60 + 60, (-560 - (-620)) / 2., 0, 2 * M_PI);
691  G4LogicalVolume* logi_rvcL = new G4LogicalVolume(geo_rvcL, Materials::get("SUS316L"), "logi_rvcL_name");
692  new G4PVPlacement(0, G4ThreeVector(0, 0, (-620 - 560) / 2.), logi_rvcL, "phys_rvcL_name", &topVolume, false, 0);
693 
694  // Added 10 Nov 2018
695  // Elliptical inner surface around QC1LE
696  G4EllipticalTube* geo_elp_QC1LEx = new G4EllipticalTube("geo_elp_QC1LEx", 10.5, 13.5, (-675 - (-1225)) / 2.); //in mm
697  G4IntersectionSolid* geo_elp_QC1LE = new G4IntersectionSolid("geo_elp_QC1LE", elements["D2wal1"].geo, geo_elp_QC1LEx,
698  G4Translate3D(0, 0, (-675 - 1225) / 2.));
699  G4LogicalVolume* logi_elp_QC1LE = new G4LogicalVolume(geo_elp_QC1LE, Materials::get("Vacuum"), "logi_elp_QC1LE_name");
700  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1LE, "phys_elp_QC1LE_name", elements["D2wal1"].logi, false, 0);
701  // Elliptical inner surface around QC1LP
702  G4EllipticalTube* geo_elp_QC1LPx = new G4EllipticalTube("geo_elp_QC1LPx", 10.5, 13.5, (-675 - (-1225)) / 2.); //in mm
703  G4IntersectionSolid* geo_elp_QC1LP = new G4IntersectionSolid("geo_elp_QC1LP", elements["E2wal1"].geo, geo_elp_QC1LPx,
704  G4Translate3D(0, 0, (-675 - 1225) / 2.));
705  G4LogicalVolume* logi_elp_QC1LP = new G4LogicalVolume(geo_elp_QC1LP, Materials::get("Vacuum"), "logi_elp_QC1LP_name");
706  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1LP, "phys_elp_QC1LP_name", elements["E2wal1"].logi, false, 0);
707  // Elliptical inner surface around QC1RE
708  G4EllipticalTube* geo_elp_QC1REx = new G4EllipticalTube("geo_elp_QC1REx", 10.5, 13.5, (1225 - 675) / 2.); //in mm
709  G4IntersectionSolid* geo_elp_QC1RE = new G4IntersectionSolid("geo_elp_QC1RE", elements["A2wal1"].geo, geo_elp_QC1REx,
710  G4Translate3D(0, 0, (1225 + 675) / 2.));
711  G4LogicalVolume* logi_elp_QC1RE = new G4LogicalVolume(geo_elp_QC1RE, Materials::get("Vacuum"), "logi_elp_QC1RE_name");
712  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1RE, "phys_elp_QC1RE_name", elements["A2wal1"].logi, false, 0);
713  // Elliptical inner surface around QC1RP
714  G4EllipticalTube* geo_elp_QC1RPx = new G4EllipticalTube("geo_elp_QC1RPx", 10.5, 13.5, (1225 - 675) / 2.); //in mm
715  G4IntersectionSolid* geo_elp_QC1RP = new G4IntersectionSolid("geo_elp_QC1RP", elements["B2wal1"].geo, geo_elp_QC1RPx,
716  G4Translate3D(0, 0, (1225 + 675) / 2.));
717  G4LogicalVolume* logi_elp_QC1RP = new G4LogicalVolume(geo_elp_QC1RP, Materials::get("Vacuum"), "logi_elp_QC1RP_name");
718  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1RP, "phys_elp_QC1RP_name", elements["B2wal1"].logi, false, 0);
719 
720 
721  //---------------------------
722  // for dose simulation
723  //---------------------------
724 
725  /*
726  logi_A1spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 101));
727  logi_A1spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 102));
728  logi_A2wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 103));
729  logi_A3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 104));
730  logi_A3wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 105));
731  logi_A4mag1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 106));
732  logi_A4mag2p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 107));
733  logi_A4mag2p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 108));
734  logi_A4mag2p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 109));
735  logi_A4mag2p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 110));
736  logi_A4mag3p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 111));
737  logi_A4mag3p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 112));
738  logi_A4mag4p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 113));
739  logi_A4mag4p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 114));
740  logi_A4mag4p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 115));
741  logi_A4mag4p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 116));
742  logi_A4mag4p5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 117));
743  logi_A4mag4p6 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 118));
744  logi_A4mag4p7 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 119));
745  logi_A4mag4p8 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 120));
746  logi_A4mag4p9 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 121));
747  logi_B1spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 122));
748  logi_B1spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 123));
749  logi_B2wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 124));
750  logi_B3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 125));
751  logi_B3wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 126));
752  logi_B4mag1p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 127));
753  logi_B4mag1p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 128));
754  logi_B4mag1p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 129));
755  logi_B4mag2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 130));
756  logi_B4mag3p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 131));
757  logi_B4mag3p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 132));
758  logi_B4mag3p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 133));
759  logi_B4mag3p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 134));
760  logi_B4mag3p5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 135));
761  logi_B4mag3p6 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 136));
762  logi_B4mag4p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 137));
763  logi_B4mag4p7 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 138));
764  logi_B4mag4p8 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 139));
765  logi_B4mag4p9 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 140));
766  logi_C1wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 141));
767  logi_C1wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 142));
768  logi_C2spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 143));
769  logi_C2spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 144));
770  logi_C2spc3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 145));
771  logi_C3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 146));
772  logi_C3wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 147));
773  logi_C4spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 148));
774  logi_C4spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 149));
775  logi_C5wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 150));
776  logi_C5wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 151));
777  logi_C5wal3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 152));
778  logi_C6spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 153));
779  logi_C6spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 154));
780  logi_C7wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 155));
781  logi_C7lyr1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 156));
782  logi_C7lyr2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 157));
783  logi_C7lyr3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 158));
784  logi_C7lyr4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 159));
785  logi_C7lyr5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 160));
786  logi_D1spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 161));
787  logi_D2wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 162));
788  logi_D3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 163));
789  logi_D3wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 164));
790  logi_D4mag1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 165));
791  logi_D4mag2p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 166));
792  logi_D4mag2p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 167));
793  logi_D4mag2p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 168));
794  logi_D4mag2p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 169));
795  logi_D4mag3p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 170));
796  logi_D4mag3p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 171));
797  logi_D4mag3p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 172));
798  logi_D4mag3p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 173));
799  logi_D4mag3p5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 174));
800  logi_D4mag3p6 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 175));
801  logi_E1spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 176));
802  logi_E2wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 177));
803  logi_E3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 178));
804  logi_E4mag1p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 179));
805  logi_E4mag1p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 180));
806  logi_E4mag1p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 181));
807  logi_E4mag2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 182));
808  logi_E4mag3p1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 183));
809  logi_E4mag3p2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 184));
810  logi_E4mag3p3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 185));
811  logi_E4mag3p4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 186));
812  logi_E4mag3p5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 187));
813  logi_F1wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 188));
814  logi_F1wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 189));
815  logi_F2spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 190));
816  logi_F2spc2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 191));
817  logi_F2spc3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 192));
818  logi_F3wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 193));
819  logi_F3wal2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 194));
820  logi_F3wal3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 195));
821  logi_F4spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 196));
822  logi_F5wal1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 197));
823  logi_F6spc1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 198));
824  logi_F7lyr1 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 199));
825  logi_F7lyr2 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 200));
826  logi_F7lyr3 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 201));
827  logi_F7lyr4 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 202));
828  logi_F7lyr5 ->SetSensitiveDetector(new BkgSensitiveDetector("IR", 203));
829  */
830 
831  }
832  }
834 }
The IR Sensitive Detector class.
int intersect(const TRGCDCLpar &lp1, const TRGCDCLpar &lp2, CLHEP::HepVector &v1, CLHEP::HepVector &v2)
intersection
Definition: Lpar.cc:249
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition: utilities.cc:105
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition: utilities.cc:97
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
The struct for CryostatElement.
G4LogicalVolume * logi
Logical volume.
G4VSolid * geo
Solid volume.
G4Transform3D transform
Transformation.