Belle II Software development
barrel.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#include <ecl/geometry/GeoECLCreator.h>
9#include "G4LogicalVolume.hh"
10#include "G4PVPlacement.hh"
11#include <G4Tubs.hh>
12#include <G4Box.hh>
13#include <G4IntersectionSolid.hh>
14#include <G4SubtractionSolid.hh>
15#include <G4Region.hh>
16#include <G4Trd.hh>
17#include <G4TwoVector.hh>
18#include <G4ExtrudedSolid.hh>
19#include <G4PVReplica.hh>
20
21#include <iostream>
22#include "CLHEP/Matrix/Vector.h"
23#include "CLHEP/Matrix/Matrix.h"
24#include "G4Vector3D.hh"
25#include "G4Point3D.hh"
26
27#include "ecl/geometry/BelleLathe.h"
28#include "ecl/geometry/BelleCrystal.h"
29#include "ecl/geometry/shapes.h"
30#include <geometry/Materials.h>
31
32using namespace std;
33using namespace Belle2;
34using namespace Belle2::geometry;
35using namespace ECL;
36
37namespace {
38 Point_t p1[] = {{0.0, 0.0}, {263.4, 0.0}, {263.4, 197.2}, {248.6, 206.6}, {212.0, 152.6}, {145.2, 199.0}, {108.5, 146.6}, {46.4, 192.1}, {7.9, 140.5}, { -50.0, 185.2}, { -90.3, 134.2}, { -143.8, 178.3}, { -170.7, 145.0}};
39 Point_t p2[] = {{0.0, 0.0}, {384.8, 0.0}, {181.9, 172.5}, {136.8, 122.3}, {90.7, 163.9}, {46.5, 115.6}, {4.1, 156.3}, { -42.5, 109.9}, { -80.9, 149.5}, { -110.9, 119.8}};
40 Point_t p3[] = {{0.0, 0.0}, {343.2, 0.0}, {209.6, 144.2}, {158.0, 98.1}, {125.8, 135.0}, {74.3, 92.4}, {46.1, 128.4}, { -6.9, 87.3}, { -32.5, 121.3}, { -67.3, 95.8}};
41 Point_t p4[] = {{0.0, 0.0}, {311.5, 0.0}, {229.5, 116.7}, {170.3, 76.5}, {150.6, 107.6}, {92.8, 71.9}, {75.0, 101.2}, {16.1, 67.5}, {1.0, 95.2}, { -37.8, 75.6}};
42 Point_t p5[] = {{0.0, 0.0}, {289.2, 0.0}, {243.1, 92.2}, {177.4, 60.9}, {166.6, 85.0}, {103.3, 57.8}, {94.3, 79.8}, {30.0, 55.5}, {22.9, 75.3}, { -19.3, 61.8}};
43 Point_t p6[] = {{0.0, 0.0}, {276.1, 0.0}, {253.3, 73.3}, {185.2, 53.4}, {180.7, 69.1}, {110.5, 51.9}, {107.5, 65.3}, {38.7, 51.8}, {36.7, 62.8}, { -7.5, 56.8}};
44 Point_t p7[] = {{0.0, 0.0}, {253.1, 0.0}, {244.8, 62.7}, {171.0, 54.0}, {170.2, 60.3}, {100.8, 55.6}, {100.3, 59.6}, {38.2, 58.1}, {38.1, 59.5}, {0.0, 60.9}};
45 Point_t p11[] = {{0.0, 0.0}, {314.1, 0.0}, {351.9, 75.6}, {312.4, 96.9}, {297.5, 69.4}, {238.2, 102.9}, {221.4, 73.2}, {163.1, 108.8}, {143.5, 77.4}, {87.1, 114.8}, {64.3, 81.7}, {9.3, 121.5}, {0.0, 108.4}};
46 Point_t* pp[] = {p1, p2, p3, p4, p5, p6, p7, p11};
47 int npp[] = {13, 10, 10, 10, 10, 10, 10, 13};
48
49 G4VSolid* get_crystal_support(int n)
50 {
51 std::vector<G4TwoVector> p; p.reserve(npp[n]);
52 for (int i = 0; i < npp[n]; i++)
53 p.push_back(G4TwoVector(pp[n][i].x, pp[n][i].y));
54
55 string name("barrel_crystal_support");
56 name += to_string(n);
57
58 G4TwoVector off(0, 0);
59 return new G4ExtrudedSolid(name, p, 1.5, off, 1, off, 1);
60 }
61}
62
63void Belle2::ECL::GeoECLCreator::barrel(G4LogicalVolume& _top)
64{
65 G4LogicalVolume* top = &_top;
66
67 // vector<cplacement_t> bp = load_placements("/ecl/data/crystal_placement_barrel.dat");
68 vector<cplacement_t> bp = load_placements(m_sap, ECLParts::barrel);
69
70 vector<cplacement_t>::iterator fp = find_if(bp.begin(), bp.end(), [](const cplacement_t& p) {
71 const int ECL_barrel_part = 1001;
72 return p.nshape == ECL_barrel_part;
73 });
74 // global transformation before placing the whole forward part in the top logical volume
75 G4Transform3D gT = (fp == bp.end()) ? G4Translate3D(0, 0, 0) : get_transform(*fp);
76 if (fp != bp.end()) bp.erase(fp); // now not needed
77
78 const bool b_crystals = true;
79 const bool b_forward_support_legs = true;
80 const bool b_backward_support_legs = true;
81 const bool b_forward_support_ring = true;
82 const bool b_backward_support_ring = true;
83 const bool b_forward_support_wall = true;
84 const bool b_backward_support_wall = true;
85 const bool b_crystal_support = true;
86 const bool b_preamplifier = true;
87 const bool b_septum_walls = true;
88 const bool b_inner_support_wall = true;
89 const bool b_support_ribs = true;
90 const bool b_outer_plates = true;
91 const bool b_forward_part5 = true;
92 const bool b_crystal_holder = true;
93 const bool b_pipe = true;
94
95 const double phi0 = M_PI / 2 - M_PI / 72;
96 const double dphi = 2 * M_PI; //2*2*M_PI/72;
97
98 const int nseg = 72;
99
100 int overlap = m_overlap;
101
102 G4LogicalVolume* sectorlogical; // tilted sector
103 {
104 double R = 1251.6;
105 double zp = 4.9, zm = 2.5;
106 // zr_t bint[] = {{-1000.8-zm, 0}, {1982.6 + zp,0}, {2288.,198.2 - zp*tand(32.982)}, {2288.,404 + 12}, {-1219.,404 + 12}, {-1219., 404 -112.6-zm*tand(52.897)-3.2}};
107 zr_t bint[] = {{ -1000.8 - zm, 0}, {1982.6 + zp, 0}, {2288., 198.2 - zp * tand(32.982)}, {2288., 1582 - R}, {2380, 1582 - R}, {2380, 404 + 12}, { -1330., 404 + 12}, { -1330., 1543 + 84 - R}, { -1219., 1543 + 84 - R}, { -1219., 404 - 112.6 - zm * tand(52.897) - 3.2}};
108 for (unsigned int i = 0; i < sizeof(bint) / sizeof(zr_t); i++) bint[i].r += R;
109 std::vector<zr_t> contourb(bint, bint + sizeof(bint) / sizeof(zr_t));
110 G4VSolid* sect0 = new BelleLathe("sect0", phi0, 2 * M_PI, contourb);
111
112 G4Vector3D n0(cos(phi0), sin(phi0), 0);
113 // shift r0 by half of septum wall thickness so from one side of the sector the wall will be completely inside the sector volume
114 G4Point3D r0 = R * n0 + 0.5 / 2 * (G4RotateZ3D(M_PI / 2) * n0), rt0 = r0 + G4RotateZ3D(M_PI / 144 - M_PI / 72) * (G4Vector3D(0, 417,
115 0)), r1 = G4RotateZ3D(2 * M_PI / 72) * r0, rt1 = G4RotateZ3D(2 * M_PI / 72) * rt0;
116 G4Transform3D t0 = G4RotateZ3D(-M_PI / 144) * G4Translate3D(-r0);
117 G4Point3D tr0 = t0 * r0, trt0 = t0 * rt0, tr1 = t0 * r1, trt1 = t0 * rt1;
118 G4Vector3D tn1 = trt1 - tr1;
119 double v0 = -(tr1.y() - tr0.y()) / tn1.y();
120 double v1 = -(tr1.y() - trt0.y()) / tn1.y();
121
122 G4Point3D u0 = tr1 + v0 * tn1, u1 = tr1 + v1 * tn1;
123 G4VSolid* sect1 = new G4Trd("sect1", -u0.x() / 2, (trt0 - u1).x() / 2, 2000, 2000, trt0.y() / 2);
124 G4IntersectionSolid* sector = new G4IntersectionSolid("sector", sect0, sect1,
125 G4Translate3D(r0)*G4RotateZ3D(M_PI / 144)*G4Translate3D(u0.x() / 2, trt0.y() / 2, (2288 - 1219.) / 2)*G4RotateX3D(-M_PI / 2));
126 sectorlogical = new G4LogicalVolume(sector, Materials::get("G4_AIR"), "ECLBarrelSectorLogical", 0, 0, 0);
127 sectorlogical->SetVisAttributes(att("air"));
128
129 // Set up region for production cuts
130 G4Region* aRegion = new G4Region("ECLBarrelSector");
131 sectorlogical->SetRegion(aRegion);
132 aRegion->AddRootLogicalVolume(sectorlogical);
133
134 for (int i = 0; i < nseg; i++) {
135 double phi = i * M_PI / 36 - M_PI / 2;
136 new G4PVPlacement(gT * G4RotateZ3D(phi), sectorlogical, suf("ECLBarrelSectorPhysical", i), top, false, i, overlap);
137 }
138 }
139
140 // phi septum wall
141 if (b_septum_walls) {
142 double zh = (0.5 - 0.001) / 2;
143 G4ThreeVector psw[] = {G4ThreeVector(-1000.8, 0, -zh), G4ThreeVector(1982.6, 0, -zh), G4ThreeVector(2288, 198.2, -zh),
144 G4ThreeVector(2288, 404, -zh), G4ThreeVector(-1219., 404, -zh), G4ThreeVector(-1219., 404 - 112.6, -zh),
145 G4ThreeVector(-1000.8, 0, zh), G4ThreeVector(1982.6, 0, zh), G4ThreeVector(2288, 198.2, zh),
146 G4ThreeVector(2288, 404, zh), G4ThreeVector(-1219., 404, zh), G4ThreeVector(-1219., 404 - 112.6, zh)
147 };
148 G4VSolid* pswsolid = new BelleCrystal("pswsolid", 6, psw);
149 G4LogicalVolume* pswlogical = new G4LogicalVolume(pswsolid, Materials::get("A5052"), "pswlogical", 0, 0, 0);
150 pswlogical->SetVisAttributes(att("alum"));
151 new G4PVPlacement(G4RotateZ3D(2.5 / 180 * M_PI)*G4Translate3D(0, 1251.6 + 0.01,
152 0)*G4RotateZ3D(1.25 / 180 * M_PI)*G4RotateY3D(-M_PI / 2), pswlogical, "phiwallphysical", sectorlogical, false, 0, overlap);
153 }
154
155 if (b_forward_support_ring) {
156 zr_t vc4[] = {{0, 1449.2}, {0, 1582}, {90, 1582}, {90, 1582 - 75.7}};
157 std::vector<zr_t> contour4(vc4, vc4 + 4);
158 G4VSolid* part4solid = new BelleLathe("part4solid", phi0, dphi, contour4);
159 G4LogicalVolume* part4logical = new G4LogicalVolume(part4solid, Materials::get("SUS304"), "part4logical", 0, 0, 0);
160 part4logical->SetVisAttributes(att("iron"));
161 new G4PVPlacement(gT * G4Translate3D(0, 0, 2290), part4logical, "ECL_BarrelSupport_part4physical", top, false, 0, overlap);
162 }
163
164 if (b_backward_support_ring) {
165 zr_t vc6[] = {{0, 1543}, { -105, 1543}, { -105, 1543 + 84}, {0, 1543 + 84}};
166 std::vector<zr_t> contour6(vc6, vc6 + 4);
167 G4VSolid* part6solid = new BelleLathe("part6solid", phi0, dphi, contour6);
168 G4LogicalVolume* part6logical = new G4LogicalVolume(part6solid, Materials::get("SUS304"), "part6logical", 0, 0, 0);
169 part6logical->SetVisAttributes(att("iron"));
170 new G4PVPlacement(gT * G4Translate3D(0, 0, -1225), part6logical, "part6physical", top, false, 0, overlap);
171 }
172
173 if (b_forward_support_wall) {
174 zr_t vc2[] = {{0, 1180.1}, {0, 1249.5}, {54.3, 1249.5}, {445.8, 1503.6}, {445.8 + 4 * sind(32.982), 1503.6 - 4 * cosd(32.982)}, {54.3 + 4 * sind(32.982 / 2), 1249.5 - 4}, {4, 1249.5 - 4}, {4, 1180.1}};
175 std::vector<zr_t> contour2(vc2, vc2 + 8);
176 G4VSolid* part2solid = new BelleLathe("part2solid", phi0, dphi, contour2);
177 G4LogicalVolume* part2logical = new G4LogicalVolume(part2solid, Materials::get("A5083"), "part2logical", 0, 0, 0);
178 part2logical->SetVisAttributes(att("alum"));
179 new G4PVPlacement(gT * G4Translate3D(0, 0, 1930), part2logical, "ECL_BarrelSupport_part2physical", top, false, 0, overlap);
180 }
181
182 if (b_backward_support_wall) {
183 zr_t vc3[] = {{0, 1180.1}, { -4, 1180.1}, { -4, 1249.5 - 4}, { -61.9 - 4 * sind(52.897 / 2), 1249.5 - 4}, { -285, 1539.1 - 4 * sind(52.897 / 2)}, { -285, 1618.8}, { -285 + 4, 1618.8}, { -285 + 4, 1539.1}, { -61.9, 1249.5}, {0, 1249.5}};
184 std::vector<zr_t> contour3(vc3, vc3 + 10);
185 G4VSolid* part3solid = new BelleLathe("part3solid", phi0, dphi, contour3);
186 G4LogicalVolume* part3logical = new G4LogicalVolume(part3solid, Materials::get("A5083"), "part3logical", 0, 0, 0);
187 part3logical->SetVisAttributes(att("alum"));
188 new G4PVPlacement(gT * G4Translate3D(0, 0, -940), part3logical, "ECL_BarrelSupport_part3physical", top, false, 0, overlap);
189 }
190
191 if (b_inner_support_wall) {
192 G4VSolid* part1solid = new G4Tubs("part1solid", 1250.1, 1250.1 + 1.5, (988.5 + 1972.5) / 2, phi0, dphi);
193 G4LogicalVolume* part1logical = new G4LogicalVolume(part1solid, Materials::get("A5083"), "part1logical", 0, 0, 0);
194 part1logical->SetVisAttributes(att("alum2"));
195 new G4PVPlacement(gT * G4Translate3D(0, 0, (-988.5 + 1972.5) / 2), part1logical, "ECL_BarrelSupport_part1physical", top, false, 0,
196 overlap);
197 }
198
199 // cppcheck-suppress knownConditionTrueFalse
200 if (b_support_ribs || b_outer_plates || b_forward_part5) {
201 // double zh = (1219.+2288.)/2, dz = (-1219.+2288.)/2;
202 double zh = (1330. + 2380.) / 2, dz = (-1330. + 2380.) / 2;
203
204 if (b_support_ribs) {
205 G4ThreeVector vc9[] = {G4ThreeVector(0, 0, -zh), G4ThreeVector(25, 0, -zh), G4ThreeVector(25, 24.5 - 25.0 * tand(2.5), -zh), G4ThreeVector(0, 24.5, -zh),
206 G4ThreeVector(0, 0, zh), G4ThreeVector(25, 0, zh), G4ThreeVector(25, 24.5 - 25.0 * tand(2.5), zh), G4ThreeVector(0, 24.5, zh)
207 };
208 G4VSolid* part9solid = new BelleCrystal("part9solid", 4, vc9);
209 G4LogicalVolume* part9logical = new G4LogicalVolume(part9solid, Materials::get("SUS304"), "part9logical", 0, 0, 0);
210 part9logical->SetVisAttributes(att("silv"));
211 G4Transform3D tpart9a = G4RotateZ3D(2.5 / 180 * M_PI) * G4Translate3D(0, 1251.6,
212 0) * G4RotateZ3D(1.25 / 180 * M_PI) * G4Translate3D(0.5 / 2, 404 - 25 - 3.7 + 0.2, dz);
213 G4Transform3D tpart9b = G4RotateZ3D(-2.5 / 180 * M_PI) * G4Translate3D(0, 1251.6,
214 0) * G4RotateZ3D(1.25 / 180 * M_PI) * G4Translate3D(-0.5 / 2, 404 - 25 - 3.7 + 0.5, dz) * G4RotateY3D(M_PI);
215 new G4PVPlacement(tpart9a, part9logical, "part9aphysical", sectorlogical, false, 0, overlap);
216 new G4PVPlacement(tpart9b, part9logical, "part9bphysical", sectorlogical, false, 0, overlap);
217 }
218
219 if (b_outer_plates) {
220 G4VSolid* part10solid = new G4Box("part10solid", 143. / 2, 8. / 2, zh);
221 G4LogicalVolume* part10logical = new G4LogicalVolume(part10solid, Materials::get("SUS304"), "part10logical", 0, 0, 0);
222 part10logical->SetVisAttributes(att("iron2"));
223 G4Transform3D tpart10 = G4Translate3D(0, 1251.6, 0) * G4Translate3D(-404 * tand(1.25), 404 - 1.1,
224 dz) * G4RotateZ3D(0.3 / 180 * M_PI);
225 new G4PVPlacement(tpart10, part10logical, "part10physical", sectorlogical, false, 0, overlap);
226 }
227
228 // G4VSolid *part5solid = new G4Box("part5solid", 60./2, 45./2, 90./2);
229 // G4LogicalVolume* part5logical = new G4LogicalVolume(part5solid, Materials::get("SUS304"), "part5logical", 0, 0, 0);
230 // part5logical->SetVisAttributes(att("iron2"));
231 // new G4PVPlacement(G4RotateZ3D(2.796/180*M_PI)*G4Translate3D(0,1582+45./2,2380.-90./2), part5logical, "part5physical", sectorlogical, false, 1, overlap);
232
233
234 if (b_forward_part5) { // slice the element to fit into the sector
235 double R = 1251.6, phi1 = phi0 + 1.25 * M_PI / 180, phi2 = (2.796 + 90 - 5) / 180 * M_PI;
236 G4Vector3D n0(cos(phi0), sin(phi0), 0), n1(cos(phi1), sin(phi1), 0), n2(cos(phi2), sin(phi2), 0);
237 // shift r0 by half of septum wall thickness so from one side of the sector the wall will be completely inside the sector volume
238 G4Point3D r0 = R * n0 + 0.5 / 2 * (G4RotateZ3D(M_PI / 2) * n0);
239
240 // n2*(r0 + t*n1 - n2*1582) = 0;
241 double t0 = -n2 * (r0 - n2 * 1582) / (n2 * n1);
242 double t1 = -n2 * (r0 - n2 * (1582 + 45)) / (n2 * n1);
243
244 G4Point3D x0 = r0 + t0 * n1;
245 G4Point3D x1 = (t1 - t0) * n1;
246
247 Point_t c5a[] = {{0, 0}, {30 * cosd(5 - 2.796), -30 * sind(5 - 2.796)}, {30 * cosd(5 - 2.796) + 45 * cos(phi2), -30 * sind(5 - 2.796) + 45 * sin(phi2)}, {x1.x(), x1.y()}};
248 G4ThreeVector vc5a[8];
249 for (int i = 0; i < 4; i++) vc5a[i] = G4ThreeVector(c5a[i].x, c5a[i].y, -90. / 2);
250 for (int i = 0; i < 4; i++) vc5a[i + 4] = G4ThreeVector(c5a[i].x, c5a[i].y, 90. / 2);
251 G4VSolid* part5asolid = new BelleCrystal("part5asolid", 4, vc5a);
252 G4LogicalVolume* part5alogical = new G4LogicalVolume(part5asolid, Materials::get("SUS304"), "part5alogical", 0, 0, 0);
253 part5alogical->SetVisAttributes(att("iron2"));
254 new G4PVPlacement(G4RotateZ3D(2 * M_PI / 72)*G4Translate3D(x0.x(), x0.y(), 2380. - 90. / 2), part5alogical, "part5aphysical",
255 sectorlogical, false, 0, overlap);
256
257 Point_t c5b[] = {{ -30 * cosd(5 - 2.796), 30 * sind(5 - 2.796)}, {0, 0}, {x1.x(), x1.y()}, { -30 * cosd(5 - 2.796) + 44.8 * cos(phi2), 30 * sind(5 - 2.796) + 44.8 * sin(phi2)}};
258 G4ThreeVector vc5b[8];
259 for (int i = 0; i < 4; i++) vc5b[i] = G4ThreeVector(c5b[i].x, c5b[i].y, -90. / 2);
260 for (int i = 0; i < 4; i++) vc5b[i + 4] = G4ThreeVector(c5b[i].x, c5b[i].y, 90. / 2);
261 G4VSolid* part5bsolid = new BelleCrystal("part5bsolid", 4, vc5b);
262 G4LogicalVolume* part5blogical = new G4LogicalVolume(part5bsolid, Materials::get("SUS304"), "part5blogical", 0, 0, 0);
263 part5blogical->SetVisAttributes(att("iron2"));
264 new G4PVPlacement(G4Translate3D(x0.x(), x0.y(), 2380. - 90. / 2), part5blogical, "part5bphysical", sectorlogical, false, 0,
265 overlap);
266 }
267
268 }
269
270 if (b_forward_support_legs) {
271 G4ThreeVector vc11a[] = {G4ThreeVector(0, 0, -63. / 2), G4ThreeVector(35, 24.5, -63. / 2), G4ThreeVector(35, 158 - 35, -63. / 2), G4ThreeVector(0, 158 - 35, -63. / 2),
272 G4ThreeVector(0, 0, 63. / 2), G4ThreeVector(35, 24.5, 63. / 2), G4ThreeVector(35, 158 - 35, 63. / 2), G4ThreeVector(0, 158 - 35, 63. / 2)
273 };
274 G4VSolid* part11asolid = new BelleCrystal("part11asolid", 4, vc11a);
275 G4VSolid* part11bsolid = new G4Box("part11bsolid", 63. / 2, 35. / 2, 100. / 2);
276 G4LogicalVolume* part11alogical = new G4LogicalVolume(part11asolid, Materials::get("SUS304"), "part11alogical", 0, 0, 0);
277 part11alogical->SetVisAttributes(att("iron2"));
278 G4LogicalVolume* part11blogical = new G4LogicalVolume(part11bsolid, Materials::get("SUS304"), "part11blogical", 0, 0, 0);
279 part11blogical->SetVisAttributes(att("iron"));
280
281 double Ro = 158.4;
282 zr_t vsf[] = {{0, 0}, {35, 24.5}, {35, 158 - 35}, {100, 158 - 35}, {100, Ro}, {0, Ro}};
283 for (zr_t* it = vsf; it != vsf + 6; it++) {it->r += 1668 - 158;}
284 std::vector<zr_t> csf(vsf, vsf + 6);
285 G4VSolid* sf = new BelleLathe("sf", 0, 2 * M_PI, csf);
286 G4LogicalVolume* sfl = new G4LogicalVolume(sf, Materials::get("G4_AIR"), "supportfwd", 0, 0, 0);
287 sfl->SetVisAttributes(att("air"));
288 new G4PVPlacement(gT * G4Translate3D(0, 0, 2380), sfl, "supportfwdphysical", top, false, 0, overlap);
289
290 G4VSolid* sfs = new BelleLathe("sfs", -M_PI / 72, 2 * M_PI / 72, csf);
291 G4LogicalVolume* sfsl = new G4LogicalVolume(sfs, Materials::get("G4_AIR"), "supportfwdsector", 0, 0, 0);
292 sfsl->SetVisAttributes(att("air"));
293
294 new G4PVPlacement(G4Translate3D(1668 - 158, 0, 0)*G4RotateZ3D(-M_PI / 2)*G4RotateY3D(-M_PI / 2), part11alogical, "part11aphysical",
295 sfsl, false, 0, overlap);
296 new G4PVPlacement(G4Translate3D(1668 - 158, 0, 0)*G4RotateZ3D(-M_PI / 2)*G4Translate3D(0, (158. - 35.) + 35. / 2, 100. / 2),
297 part11blogical, "part11bphysical", sfsl, false, 0, overlap);
298 new G4PVReplica("supportfwdrep", sfsl, sfl, kPhi, nseg, 2 * M_PI / 72, (2.796 - 2.5)*M_PI / 180);
299 }
300
301 if (b_backward_support_legs) {
302 G4VSolid* part12asolid = new G4Box("part12asolid", 90. / 2, (118. - 35.) / 2, 35. / 2);
303 G4VSolid* part12bsolid = new G4Box("part12bsolid", 90. / 2, 35. / 2, 120. / 2);
304 G4LogicalVolume* part12alogical = new G4LogicalVolume(part12asolid, Materials::get("SUS304"), "part12alogical", 0, 0, 0);
305 part12alogical->SetVisAttributes(att("iron2"));
306 G4LogicalVolume* part12blogical = new G4LogicalVolume(part12bsolid, Materials::get("SUS304"), "part12blogical", 0, 0, 0);
307 part12blogical->SetVisAttributes(att("iron"));
308
309 double Rb = 118.7;
310 zr_t vsb[] = {{0, 0}, {0, Rb}, { -120, Rb}, { -120, 118 - 35}, { -35, 118 - 35}, { -35, 0}};
311 for (zr_t* it = vsb; it != vsb + 6; it++) {it->r += 1668 - 118;}
312 std::vector<zr_t> csb(vsb, vsb + 6);
313 G4VSolid* sb = new BelleLathe("sb", 0, 2 * M_PI, csb);
314 G4LogicalVolume* sbl = new G4LogicalVolume(sb, Materials::get("G4_AIR"), "supportbkw", 0, 0, 0);
315 sbl->SetVisAttributes(att("air"));
316 new G4PVPlacement(gT * G4Translate3D(0, 0, -1330), sbl, "supportbkwphysical", top, false, 0, overlap);
317
318 G4VSolid* sbs = new BelleLathe("sbs", -M_PI / 72, 2 * M_PI / 72, csb);
319 G4LogicalVolume* sbsl = new G4LogicalVolume(sbs, Materials::get("G4_AIR"), "supportbkwsector", 0, 0, 0);
320 sbsl->SetVisAttributes(att("air"));
321
322 new G4PVPlacement(G4Translate3D(1668 - 118, 0, 0)*G4RotateZ3D(-M_PI / 2)*G4Translate3D(0, (118. - 35.) / 2, -35. / 2),
323 part12alogical, "part12aphysical", sbsl, false, 0, overlap);
324 new G4PVPlacement(G4Translate3D(1668 - 118, 0, 0)*G4RotateZ3D(-M_PI / 2)*G4Translate3D(0, (118. - 35.) + 35. / 2, -120. / 2),
325 part12blogical, "part12bphysical", sbsl, false, 0, overlap);
326
327 new G4PVReplica("supportbkwrep", sbsl, sbl, kPhi, nseg, 2 * M_PI / 72, (2.796 - 2.5)*M_PI / 180);
328 }
329
330 if (b_septum_walls) {
331 struct zwall_t { double zlow, zup;};
332 zwall_t zs[] = {{ -682.1, -883.9}, { -445.9, -571.7}, { -220.8, -274.2}, {0, 0}, {220.8, 274.2}, {445.9, 571.7}, {682.1, 883.9}, {936.6, 1220.5}, {1217.1, 1591.2}, {1532., 2007.4}};
333
334 const double dz = 0.5 / 2; // half of theta fin thickness
335
336 G4Vector3D n0(sind(90 + 2.5 + 1.25), -cosd(90 + 2.5 + 1.25), 0); // normal vector of the left sector wall pointing inside the sector
337 G4Point3D r0 = G4Point3D(-1251.6 * sind(2.5), 0, 0) + dz * n0; // point in the left sector wall shifted by phi fin
338 G4Vector3D n1(-sind(90 - 2.5 + 1.25), cosd(90 - 2.5 + 1.25),
339 0); // normal vector of the right sector wall pointing inside the sector
340 G4Point3D r1 = G4Point3D(1251.6 * sind(2.5), 0, 0) + dz * n1; // point in the right sector wall shifted by phi fin
341
342 G4Vector3D n2(0, 1, 0); G4Point3D r2(0, 0, 0), r3(0, 310, 0);
343
344 for (unsigned int i = 0; i < sizeof(zs) / sizeof(zwall_t); i++) {
345 double th = atan2(404, -(zs[i].zlow - zs[i].zup));
346
347 G4Vector3D nf(0, -cos(th), sin(th));
348 // take into account finite thickness of the theta fin
349 G4Point3D rf(0, 0, copysign(dz / sin(th), cos(th)));
350
351 // calculate three plane intersection point
352 auto inter = [](const G4Vector3D & l_n0, const G4Point3D & l_r0,
353 const G4Vector3D & l_n1, const G4Point3D & l_r1,
354 const G4Vector3D & l_n2, const G4Point3D & l_r2) -> G4Point3D {
355 CLHEP::HepMatrix A(3, 3);
356 CLHEP::HepVector B(3);
357 A[0][0] = l_n0.x(), A[0][1] = l_n0.y(), A[0][2] = l_n0.z();
358 A[1][0] = l_n1.x(), A[1][1] = l_n1.y(), A[1][2] = l_n1.z();
359 A[2][0] = l_n2.x(), A[2][1] = l_n2.y(), A[2][2] = l_n2.z();
360
361 B[0] = l_r0 * l_n0;
362 B[1] = l_r1 * l_n1;
363 B[2] = l_r2 * l_n2;
364
365 CLHEP::HepVector r = A.inverse() * B;
366 G4Point3D res(r[0], r[1], r[2]);
367 return res;
368 };
369
370 G4Transform3D tfin(G4RotateX3D(-th + M_PI / 2)), tfini(G4RotateX3D(th - M_PI / 2));
371 G4ThreeVector t0 = tfini * inter(n0, r0, n2, r2, nf, rf);
372 G4ThreeVector t1 = tfini * inter(n1, r1, n2, r2, nf, rf);
373 G4ThreeVector t2 = tfini * inter(n0, r0, n2, r3, nf, rf);
374 G4ThreeVector t3 = tfini * inter(n1, r1, n2, r3, nf, rf);
375 // G4cout<<t0<<" "<<t1<<" "<<t2<<" "<<t3<<" "<<G4RotateX3D(th-M_PI/2)*G4Point3D(0,404,zs[i].zup-zs[i].zlow)<<G4endl;
376
377 G4ThreeVector thfin[8];
378 thfin[0] = G4ThreeVector(t0.x(), t0.y(), -dz);
379 thfin[1] = G4ThreeVector(t1.x(), t1.y(), -dz);
380 thfin[2] = G4ThreeVector(t3.x(), t3.y(), -dz);
381 thfin[3] = G4ThreeVector(t2.x(), t2.y(), -dz);
382 thfin[4] = G4ThreeVector(t0.x(), t0.y(), +dz);
383 thfin[5] = G4ThreeVector(t1.x(), t1.y(), +dz);
384 thfin[6] = G4ThreeVector(t3.x(), t3.y(), +dz);
385 thfin[7] = G4ThreeVector(t2.x(), t2.y(), +dz);
386
387 G4VSolid* thfinsolid = new BelleCrystal("thfinsolid", 4, thfin);
388 G4LogicalVolume* thfinlogical = new G4LogicalVolume(thfinsolid, Materials::get("A5052"), "thfinlogical", 0, 0, 0);
389 thfinlogical->SetVisAttributes(att("iron2"));
390 new G4PVPlacement(G4Translate3D(0, 1251.6, zs[i].zlow)*tfin, thfinlogical, "thfinphysical", sectorlogical, false, 0, overlap);
391 }
392 }
393
394 if (b_pipe) {
395 double zh = (1219. + 2288.) / 2, dz = (-1219. + 2288.) / 2;
396 G4VSolid* tubec = new G4Tubs("tubec", 0, 12. / 2, zh, 0, 2 * M_PI);
397 G4VSolid* tubew = new G4Tubs("tubew", 0, 10. / 2, zh, 0, 2 * M_PI);
398 G4LogicalVolume* tubeclogical = new G4LogicalVolume(tubec, Materials::get("C1220"), "tubec", 0, 0, 0);
399 G4LogicalVolume* tubewlogical = new G4LogicalVolume(tubew, Materials::get("G4_WATER"), "tubew", 0, 0, 0);
400 new G4PVPlacement(G4Translate3D(0, 0, 0), tubewlogical, "tubewphysical", tubeclogical, false, 1, overlap);
401 tubeclogical->SetVisAttributes(att("iron2"));
402 new G4PVPlacement(G4Translate3D(25, 1640, dz), tubeclogical, "tubecphysical", sectorlogical, false, 0, overlap);
403 new G4PVPlacement(G4Translate3D(-35, 1640, dz), tubeclogical, "tubecphysical", sectorlogical, false, 1, overlap);
404 }
405
406 if (b_preamplifier) {
407 for (vector<cplacement_t>::const_iterator it = bp.begin(); it != bp.end(); ++it) {
408 G4Transform3D twc = get_transform(*it);
409 int indx = it - bp.begin();
410 auto pv = new G4PVPlacement(twc * G4TranslateZ3D(300 / 2 + 0.250 + get_pa_box_height() / 2), get_preamp(),
411 suf("phys_barrel_preamplifier", indx),
412 sectorlogical, false, 72 + 9 * (indx / 2) + (indx % 2), 0);
413 if (overlap)pv->CheckOverlaps(1000);
414 }
415 }
416
417 if (b_crystal_holder) {
418 G4VSolid* holder0 = new G4Box("holder0", 19. / 2, 38. / 2, 6. / 2);
419 G4VSolid* holder1 = new G4Box("holder1", 7. / 2, 26. / 2, 7. / 2);
420 G4VSolid* holder = new G4SubtractionSolid("holder", holder0, holder1);
421 G4LogicalVolume* holderlogical = new G4LogicalVolume(holder, Materials::get("A5052"), "holderlogical", 0, 0, 0);
422 holderlogical->SetVisAttributes(att("holder"));
423 for (vector<cplacement_t>::const_iterator it = bp.begin(); it != bp.end(); ++it) {
424 G4Transform3D twc = get_transform(*it);
425 int indx = it - bp.begin();
426 auto pv = new G4PVPlacement(twc * G4TranslateZ3D(300 / 2 + 0.250 + get_pa_box_height() + 38. / 2)*G4RotateZ3D(M_PI / 2)*G4RotateX3D(
427 M_PI / 2), holderlogical, "holderphysical", sectorlogical, false, indx, 0);
428 if (overlap)pv->CheckOverlaps(1000);
429 }
430 }
431
432 if (b_crystals) {
433 // vector<shape_t*> cryst = load_shapes("/ecl/data/crystal_shape_barrel.dat");
434 vector<shape_t*> cryst = load_shapes(m_sap, ECLParts::barrel);
435 vector<G4LogicalVolume*> wrapped_crystals;
436 for (auto it = cryst.begin(); it != cryst.end(); it++) {
437 shape_t* s = *it;
438 wrapped_crystals.push_back(wrapped_crystal(s, "barrel", 0.17 - 0.0325));
439 }
440
441 for (vector<cplacement_t>::const_iterator it = bp.begin(); it != bp.end(); ++it) {
442 const cplacement_t& t = *it;
443 auto s = find_if(cryst.begin(), cryst.end(), [&t](const shape_t* shape) {return shape->nshape == t.nshape;});
444 if (s == cryst.end()) continue;
445
446 G4Transform3D twc = get_transform(t);
447 int indx = it - bp.begin();
448 new G4PVPlacement(twc, wrapped_crystals[s - cryst.begin()], suf("ECLBarrelWrappedCrystal_Physical", indx), sectorlogical, false,
449 72 + 9 * (indx / 2) + (indx % 2), overlap);
450 }
451
452 for (shape_t* shape : cryst) {
453 delete shape;
454 }
455 }
456
457 if (b_crystal_support) {
458 G4LogicalVolume* tl[8];
459 for (int i = 0; i < 8; i++) {
460 G4VSolid* t = get_crystal_support(i);
461 tl[i] = new G4LogicalVolume(t, Materials::get("SUS304"), "crystal_support_logical", 0, 0, 0);
462 tl[i]->SetVisAttributes(att("iron2"));
463 }
464
465 double offset[] = { -945, -607, -305, -45, 45, 305, 607, 909, 1240, 1628, 2040};
466 const int ns[] = {8, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1};
467 const double offsetb[] = {263.4 - 210 - 30, 27.4, 10.6, 16.1, 26.2, 21.7, 35, 22 + 240};
468 bool flip[] = {1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1};
469 for (int i = 0; i < 11; i++) {
470 G4Transform3D tflip = flip[i] ? G4RotateY3D(-M_PI / 2) : G4RotateY3D(M_PI / 2);
471 G4Transform3D tr0(G4RotateZ3D(2.5 / 180 * M_PI)*G4Translate3D(0, 1251.6,
472 0)*G4RotateZ3D(1.25 / 180 * M_PI)*G4Translate3D(25 + 3. / 2 + 0.5 / 2, 404 - 25 - 3.7 + 24.5 - 25.0 * tand(2.5) - 0.5,
473 offset[i])*tflip * G4Translate3D(-offsetb[ns[i] - 1], 0, 0)*G4RotateX3D(M_PI));
474 new G4PVPlacement(tr0, tl[ns[i] - 1], "crystal_support_physical", sectorlogical, false, 0, overlap);
475 G4Transform3D tr1(G4RotateZ3D(-2.5 / 180 * M_PI)*G4Translate3D(0, 1251.6,
476 0)*G4RotateZ3D(1.25 / 180 * M_PI)*G4Translate3D(-25 - 3. / 2 - 0.5 / 2, 404 - 25 - 3.7 + 24.5 - 25.0 * tand(2.5) - 0.5,
477 offset[i])*tflip * G4Translate3D(-offsetb[ns[i] - 1], 0, 0)*G4RotateX3D(M_PI));
478 new G4PVPlacement(tr1, tl[ns[i] - 1], "crystal_support_physical", sectorlogical, false, 1, overlap);
479 }
480 }
481
482}
double R
typedef autogenerated by FFTW
a Belle crystal in Geant4
Definition: BelleCrystal.h:37
BelleLathe class.
Definition: BelleLathe.h:67
void barrel(G4LogicalVolume &)
Make the ECL barrel and then place elements inside it.
Definition: barrel.cc:63
double get_pa_box_height() const
Getter for preamplifier box height (hard-coded to be 2)
Definition: GeoECLCreator.h:88
const G4VisAttributes * att(const std::string &n) const
Define visual attributes.
const ECLCrystalsShapeAndPosition * m_sap
pointer to a storage with crystal shapes and positions
Definition: GeoECLCreator.h:91
G4LogicalVolume * get_preamp() const
Get Logical volume of preamplifier.
G4LogicalVolume * wrapped_crystal(const shape_t *s, const std::string &endcap, double wrapthickness)
Wrapped crystal.
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
Common code concerning the geometry representation of the detector.
Definition: CreatorBase.h:25
Abstract base class for different kinds of events.
STL namespace.
struct for Point
Definition: BelleCrystal.h:31
placement struct
Definition: shapes.h:49
simple struct with z and r coordinates
Definition: BelleLathe.h:25
double r
r coordinate
Definition: BelleLathe.h:27