Belle II Software development
GeoEKLMCreator.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/* Own header. */
10#include <klm/eklm/geometry/GeoEKLMCreator.h>
11
12/* KLM headers. */
13#include <klm/eklm/geometry/G4TriangularPrism.h>
14#include <klm/simulation/SensitiveDetector.h>
15
16/* Basf2 headers. */
17#include <geometry/CreatorFactory.h>
18#include <geometry/Materials.h>
19#include <geometry/utilities.h>
20
21/* Geant4 headers. */
22#include <G4Box.hh>
23#include <G4Polyhedra.hh>
24#include <G4PVPlacement.hh>
25#include <G4Region.hh>
26#include <G4Tubs.hh>
27#include <G4UnionSolid.hh>
28
29/* CLHEP headers. */
30#include <CLHEP/Units/SystemOfUnits.h>
31
32/* C++ headers. */
33#include <cmath>
34#include <string>
35
36using namespace Belle2;
37
38static const char MemErr[] = "Memory allocation error.";
39
40/* Register the creator */
41geometry::CreatorFactory<EKLM::GeoEKLMCreator> GeoEKLMFactory("EKLMCreator");
42
43/******************************* CONSTRUCTORS ********************************/
44
46{
47 m_Materials.air = nullptr;
48 m_CurVol.section = 1;
49 m_GeoDat = nullptr;
50 m_TransformData = nullptr;
51 m_Solids.plane = nullptr;
52 m_Solids.psheet = nullptr;
53 m_LogVol.psheet = nullptr;
54 m_LogVol.strip = nullptr;
55 m_Solids.groove = nullptr;
56 m_LogVol.groove = nullptr;
57 m_LogVol.scint = nullptr;
58 m_LogVol.segmentsup = nullptr;
60 m_Sensitive = nullptr;
61}
62
64{
65 delete m_TransformData;
66 if (m_Solids.plane != nullptr)
68 if (m_Sensitive != nullptr)
70}
71
72/***************************** MEMORY ALLOCATION *****************************/
73
75{
76 int i, nDiff;
77 m_Solids.plane =
78 static_cast<G4VSolid**>(malloc(m_GeoDat->getNPlanes() * sizeof(G4VSolid*)));
79 if (m_Solids.plane == nullptr)
80 B2FATAL(MemErr);
81 m_Solids.plasticSheetElement =
82 static_cast<G4VSolid**>(malloc(m_GeoDat->getNStrips() * sizeof(G4VSolid*)));
83 if (m_Solids.plasticSheetElement == nullptr)
84 B2FATAL(MemErr);
85 m_Solids.psheet =
86 static_cast<G4VSolid**>(malloc(m_GeoDat->getNSegments() * sizeof(G4VSolid*)));
87 if (m_Solids.psheet == nullptr)
88 B2FATAL(MemErr);
89 m_LogVol.psheet = static_cast<G4LogicalVolume**>(malloc(m_GeoDat->getNSegments() * sizeof(G4LogicalVolume*)));
90 if (m_LogVol.psheet == nullptr)
91 B2FATAL(MemErr);
92 m_LogVol.segment =
93 static_cast<G4LogicalVolume**>(malloc(m_GeoDat->getNSegments() *
94 sizeof(G4LogicalVolume*)));
95 if (m_LogVol.segment == nullptr)
96 B2FATAL(MemErr);
97 m_Solids.stripSegment =
98 static_cast<G4VSolid**>(malloc(m_GeoDat->getNSegments() * sizeof(G4VSolid*)));
99 if (m_Solids.stripSegment == nullptr)
100 B2FATAL(MemErr);
101 m_LogVol.stripSegment =
102 static_cast<G4LogicalVolume**>(malloc(m_GeoDat->getNSegments() *
103 sizeof(G4LogicalVolume*)));
104 if (m_LogVol.stripSegment == nullptr)
105 B2FATAL(MemErr);
106 nDiff = m_GeoDat->getNStripsDifferentLength();
107 m_Solids.strip = static_cast<G4VSolid**>(malloc(nDiff * sizeof(G4VSolid*)));
108 if (m_Solids.strip == nullptr)
109 B2FATAL(MemErr);
110 m_LogVol.strip = static_cast<G4LogicalVolume**>(malloc(nDiff * sizeof(G4LogicalVolume*)));
111 if (m_LogVol.strip == nullptr)
112 B2FATAL(MemErr);
113 m_Solids.groove = static_cast<G4VSolid**>(malloc(nDiff * sizeof(G4VSolid*)));
114 if (m_Solids.groove == nullptr)
115 B2FATAL(MemErr);
116 m_LogVol.groove = static_cast<G4LogicalVolume**>(malloc(nDiff * sizeof(G4LogicalVolume*)));
117 if (m_LogVol.groove == nullptr)
118 B2FATAL(MemErr);
119 m_LogVol.scint = static_cast<G4LogicalVolume**>(malloc(nDiff * sizeof(G4LogicalVolume*)));
120 if (m_LogVol.scint == nullptr)
121 B2FATAL(MemErr);
122 m_LogVol.segmentsup =
123 static_cast<G4LogicalVolume*** >(malloc(m_GeoDat->getNPlanes() *
124 sizeof(G4LogicalVolume**)));
125 if (m_LogVol.segmentsup == nullptr)
126 B2FATAL(MemErr);
127 for (i = 0; i < m_GeoDat->getNPlanes(); i++) {
128 m_LogVol.segmentsup[i] =
129 static_cast<G4LogicalVolume**>(malloc((m_GeoDat->getNSegments() + 1) *
130 sizeof(G4LogicalVolume*)));
131 if (m_LogVol.segmentsup[i] == nullptr)
132 B2FATAL(MemErr);
133 }
134 for (i = 0; i < m_GeoDat->getNSegments(); i++)
135 m_LogVol.psheet[i] = nullptr;
136}
137
139{
140 try {
141 m_Sensitive = new KLM::SensitiveDetector("EKLMSensitiveStrip",
143 } catch (std::bad_alloc& ba) {
144 B2FATAL(MemErr);
145 }
146}
147
149{
150 int i;
151 free(m_Solids.plane);
152 free(m_Solids.plasticSheetElement);
153 free(m_Solids.psheet);
154 free(m_LogVol.psheet);
155 free(m_LogVol.segment);
156 free(m_Solids.stripSegment);
157 free(m_LogVol.stripSegment);
158 free(m_Solids.strip);
159 free(m_LogVol.strip);
160 free(m_Solids.groove);
161 free(m_LogVol.groove);
162 free(m_LogVol.scint);
163 for (i = 0; i < m_GeoDat->getNPlanes(); i++)
164 free(m_LogVol.segmentsup[i]);
165 free(m_LogVol.segmentsup);
166}
167
172
173/********************************** XML DATA *********************************/
174
176{
178 m_Materials.polyethylene = geometry::Materials::get("EKLMPolyethylene");
179 m_Materials.polystyrene = geometry::Materials::get("EKLMPolystyrene");
180 m_Materials.polystyrol = geometry::Materials::get("EKLMPolystyrol");
181 m_Materials.gel = geometry::Materials::get("EKLMGel");
182 m_Materials.iron = geometry::Materials::get("EKLMIron");
183 m_Materials.duralumin = geometry::Materials::get("EKLMDuralumin");
184 m_Materials.silicon = geometry::Materials::get("EKLMSilicon");
185}
186
187/*************************** CREATION OF SOLIDS ******************************/
188
190{
191 const EKLMGeometry::EndcapStructureGeometry* sectionStructureGeometry =
192 m_GeoDat->getEndcapStructureGeometry();
193 const EKLMGeometry::ElementPosition* sectionPos =
194 m_GeoDat->getSectionPosition();
195 const double z[2] = { -sectionPos->getLength() / 2,
196 sectionPos->getLength() / 2
197 };
198 const double rMin[2] = {0, 0};
199 const double rMax[2] = {sectionPos->getOuterR(), sectionPos->getOuterR()};
200 G4Polyhedra* op = nullptr;
201 G4Tubs* tb = nullptr;
202 try {
203 op = new G4Polyhedra("Section_Octagonal_Prism",
204 sectionStructureGeometry->getPhi(),
205 360. * CLHEP::deg,
206 sectionStructureGeometry->getNSides(),
207 2, z, rMin, rMax);
208 } catch (std::bad_alloc& ba) {
209 B2FATAL(MemErr);
210 }
211 /* Subtraction tube has slightly larger Z size. */
212 try {
213 tb = new G4Tubs("Section_Tube", 0, sectionPos->getInnerR(),
214 sectionPos->getLength() / 2.0 + 1.0 * CLHEP::mm,
215 0.0, 360.0 * CLHEP::deg);
216 } catch (std::bad_alloc& ba) {
217 B2FATAL(MemErr);
218 }
219 try {
220 m_Solids.section = new G4SubtractionSolid("Section", op, tb);
221 } catch (std::bad_alloc& ba) {
222 B2FATAL(MemErr);
223 }
224}
225
226G4LogicalVolume*
228{
229 G4LogicalVolume* logicLayer = nullptr;
230 try {
231 logicLayer = new G4LogicalVolume(m_Solids.layer, m_Materials.air, name);
232 } catch (std::bad_alloc& ba) {
233 B2FATAL(MemErr);
234 }
235 geometry::setVisibility(*logicLayer, false);
236 return logicLayer;
237}
238
240{
241 const EKLMGeometry::ElementPosition* layerPos = m_GeoDat->getLayerPosition();
242 try {
243 m_Solids.layer =
244 new G4Tubs("Layer", layerPos->getInnerR(), layerPos->getOuterR(),
245 layerPos->getLength() / 2.0, 0.0, 360. * CLHEP::deg);
246 } catch (std::bad_alloc& ba) {
247 B2FATAL(MemErr);
248 }
249}
250
251G4LogicalVolume*
253{
254 G4LogicalVolume* logicSector = nullptr;
255 try {
256 logicSector = new G4LogicalVolume(m_Solids.sector, m_Materials.air, name);
257 } catch (std::bad_alloc& ba) {
258 B2FATAL(MemErr);
259 }
260 geometry::setVisibility(*logicSector, false);
261 return logicSector;
262}
263
265{
266 const EKLMGeometry::ElementPosition* sectorPos =
267 m_GeoDat->getSectorPosition();
268 try {
269 m_Solids.sector =
270 new G4Tubs("Sector", sectorPos->getInnerR(), sectorPos->getOuterR(),
271 0.5 * sectorPos->getLength(), 0.0, 90. * CLHEP::deg);
272 } catch (std::bad_alloc& ba) {
273 B2FATAL(MemErr);
274 }
275}
276
278{
279 double lz, ang;
280 HepGeom::Transform3D t1;
281 HepGeom::Transform3D t2;
282 G4Tubs* solidCoverTube = nullptr;
283 G4Box* solidCoverBox = nullptr;
284 G4Box* box = nullptr;
285 G4IntersectionSolid* is = nullptr;
286 G4SubtractionSolid* solidCover = nullptr;
287 const EKLMGeometry::ElementPosition* sectorPos =
288 m_GeoDat->getSectorPosition();
289 const EKLMGeometry::ElementPosition* sectorSupportPos =
290 m_GeoDat->getSectorSupportPosition();
291 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
292 m_GeoDat->getSectorSupportGeometry();
293 const EKLMGeometry::ElementPosition* planePos = m_GeoDat->getPlanePosition();
294 lz = 0.5 * (sectorPos->getLength() - sectorSupportPos->getLength());
295 try {
296 solidCoverTube = new G4Tubs("Cover_Tube", sectorSupportPos->getInnerR(),
297 sectorSupportPos->getOuterR(), 0.5 * lz, 0.0,
298 90.0 * CLHEP::deg);
299 } catch (std::bad_alloc& ba) {
300 B2FATAL(MemErr);
301 }
302 try {
303 solidCoverBox = new G4Box("Cover_Box", 0.5 * sectorSupportPos->getOuterR(),
304 0.5 * sectorSupportPos->getOuterR(), 0.5 * lz);
305 } catch (std::bad_alloc& ba) {
306 B2FATAL(MemErr);
307 }
308 try {
309 box = new G4Box("Cover_SubtractionBox", 0.5 * sectorSupportPos->getOuterR(),
310 0.5 * sectorSupportPos->getOuterR(), lz);
311 } catch (std::bad_alloc& ba) {
312 B2FATAL(MemErr);
313 }
314 t1 = HepGeom::Translate3D(
315 0.5 * planePos->getOuterR() + sectorSupportPos->getX(),
316 0.5 * planePos->getOuterR() + sectorSupportPos->getY(), 0.);
317 ang = sectorSupportGeometry->getCornerAngle();
318 t2 = HepGeom::Translate3D(
319 sectorSupportPos->getX() +
320 0.5 * sectorSupportPos->getOuterR() * cos(ang) -
321 0.5 * sectorSupportPos->getOuterR() * sin(ang),
322 sectorSupportPos->getOuterR() -
323 sectorSupportGeometry->getDeltaLY() +
324 0.5 * sectorSupportPos->getOuterR() * cos(ang) +
325 0.5 * sectorSupportPos->getOuterR() * sin(ang),
326 0.) * HepGeom::RotateZ3D(ang);
327 try {
328 is = new G4IntersectionSolid("Cover_Intersection",
329 solidCoverTube, solidCoverBox, t1);
330 } catch (std::bad_alloc& ba) {
331 B2FATAL(MemErr);
332 }
333 try {
334 solidCover = new G4SubtractionSolid("Cover", is, box, t2);
335 } catch (std::bad_alloc& ba) {
336 B2FATAL(MemErr);
337 }
338 try {
339 m_LogVol.cover =
340 new G4LogicalVolume(solidCover, m_Materials.duralumin, "Cover");
341 } catch (std::bad_alloc& ba) {
342 B2FATAL(MemErr);
343 }
344 geometry::setVisibility(*m_LogVol.cover, false);
345 geometry::setColor(*m_LogVol.cover, "#ff000022");
346}
347
349{
350 double x;
351 G4Box* res = nullptr;
352 const EKLMGeometry::ElementPosition* sectorSupportPos =
353 m_GeoDat->getSectorSupportPosition();
354 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
355 m_GeoDat->getSectorSupportGeometry();
356 x = sqrt(sectorSupportPos->getOuterR() * sectorSupportPos->getOuterR() -
357 sectorSupportPos->getY() * sectorSupportPos->getY());
358 t = HepGeom::Translate3D(0.5 * (x + sectorSupportGeometry->getCorner3().x()),
359 sectorSupportPos->getY() +
360 0.5 * sectorSupportGeometry->getThickness(), 0.);
361 try {
362 res = new G4Box("SectorSupport_BoxX",
363 0.5 * (x - sectorSupportGeometry->getCorner3().x()),
364 0.5 * sectorSupportGeometry->getThickness(),
365 0.5 * sectorSupportPos->getLength());
366 } catch (std::bad_alloc& ba) {
367 B2FATAL(MemErr);
368 }
369 return res;
370}
371
373{
374 G4Box* res = nullptr;
375 const EKLMGeometry::ElementPosition* sectorSupportPos =
376 m_GeoDat->getSectorSupportPosition();
377 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
378 m_GeoDat->getSectorSupportGeometry();
379 t = HepGeom::Translate3D(sectorSupportPos->getX() +
380 0.5 * sectorSupportGeometry->getThickness(),
381 0.5 * (sectorSupportGeometry->getCorner4().y() +
382 sectorSupportGeometry->getCorner1A().y()),
383 0.) * HepGeom::RotateZ3D(90. * CLHEP::deg);
384 try {
385 res = new G4Box("SectorSupport_BoxY",
386 0.5 * (sectorSupportGeometry->getCorner1A().y() -
387 sectorSupportGeometry->getCorner4().y()),
388 0.5 * sectorSupportGeometry->getThickness(),
389 0.5 * sectorSupportPos->getLength());
390 } catch (std::bad_alloc& ba) {
391 B2FATAL(MemErr);
392 }
393 return res;
394}
395
397{
398 double dx;
399 double dy;
400 G4Box* res = nullptr;
401 const EKLMGeometry::ElementPosition* sectorSupportPos =
402 m_GeoDat->getSectorSupportPosition();
403 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
404 m_GeoDat->getSectorSupportGeometry();
405 t = HepGeom::Translate3D(
406 0.5 * (sectorSupportGeometry->getCorner1A().x() +
407 sectorSupportGeometry->getCorner1B().x() +
408 sectorSupportGeometry->getThickness() *
409 sin(sectorSupportGeometry->getCornerAngle())),
410 0.5 * (sectorSupportGeometry->getCorner1A().y() +
411 sectorSupportGeometry->getCorner1B().y() -
412 sectorSupportGeometry->getThickness() *
413 cos(sectorSupportGeometry->getCornerAngle())),
414 0.) * HepGeom::RotateZ3D(sectorSupportGeometry->getCornerAngle());
415 dx = sectorSupportGeometry->getCorner1B().x() -
416 sectorSupportGeometry->getCorner1A().x();
417 dy = sectorSupportGeometry->getCorner1B().y() -
418 sectorSupportGeometry->getCorner1B().y();
419 try {
420 res = new G4Box("SectorSupport_BoxTop", 0.5 * sqrt(dx * dx + dy * dy),
421 0.5 * sectorSupportGeometry->getThickness(),
422 0.5 * sectorSupportPos->getLength());
423 } catch (std::bad_alloc& ba) {
424 B2FATAL(MemErr);
425 }
426 return res;
427}
428
430{
431 double ang1;
432 double ang2;
433 G4Tubs* res = nullptr;
434 const EKLMGeometry::ElementPosition* sectorSupportPos =
435 m_GeoDat->getSectorSupportPosition();
436 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
437 m_GeoDat->getSectorSupportGeometry();
438 ang1 = atan2(sectorSupportGeometry->getCorner3().y(),
439 sectorSupportGeometry->getCorner3().x());
440 ang2 = atan2(sectorSupportGeometry->getCorner4().y(),
441 sectorSupportGeometry->getCorner4().x());
442 try {
443 res = new G4Tubs("SectorSupport_InnerTube", sectorSupportPos->getInnerR(),
444 sectorSupportPos->getInnerR() +
445 sectorSupportGeometry->getThickness(),
446 0.5 * sectorSupportPos->getLength(),
447 ang1 * CLHEP::rad, (ang2 - ang1) * CLHEP::rad);
448 } catch (std::bad_alloc& ba) {
449 B2FATAL(MemErr);
450 }
451 return res;
452}
453
455{
456 double x;
457 double ang1;
458 double ang2;
459 double r;
460 G4Tubs* res = nullptr;
461 const EKLMGeometry::ElementPosition* sectorSupportPos =
462 m_GeoDat->getSectorSupportPosition();
463 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
464 m_GeoDat->getSectorSupportGeometry();
465 r = sectorSupportPos->getOuterR() - sectorSupportGeometry->getThickness();
466 x = sqrt(r * r - sectorSupportPos->getY() * sectorSupportPos->getY());
467 ang1 = atan2(sectorSupportPos->getY(), x);
468 ang2 = atan2(sectorSupportGeometry->getCorner1B().y(),
469 sectorSupportGeometry->getCorner1B().x());
470 try {
471 res = new G4Tubs("SectorSupport_OuterTube", r,
472 sectorSupportPos->getOuterR(),
473 0.5 * sectorSupportPos->getLength(),
474 ang1 * CLHEP::rad, (ang2 - ang1) * CLHEP::rad);
475 } catch (std::bad_alloc& ba) {
476 B2FATAL(MemErr);
477 }
478 return res;
479}
480
482{
483 double lx;
484 double x;
485 G4Tubs* solidCorner1Tube = nullptr;
486 G4Box* solidCorner1Box1 = nullptr;
487 G4Box* solidCorner1Box2 = nullptr;
488 G4IntersectionSolid* is1 = nullptr;
489 G4IntersectionSolid* solidCorner1 = nullptr;
490 HepGeom::Transform3D t1;
491 HepGeom::Transform3D t2;
492 const EKLMGeometry::ElementPosition* sectorSupportPos =
493 m_GeoDat->getSectorSupportPosition();
494 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
495 m_GeoDat->getSectorSupportGeometry();
496 lx = sectorSupportGeometry->getCornerX() +
497 sectorSupportGeometry->getCorner1LX() -
498 sectorSupportGeometry->getThickness();
499 try {
500 solidCorner1Tube = new G4Tubs(
501 "SectorSupport_Corner1_Tube", 0.,
502 sectorSupportPos->getOuterR() - sectorSupportGeometry->getThickness(),
503 0.5 * sectorSupportGeometry->getCorner1Thickness(),
504 0., 90. * CLHEP::deg);
505 } catch (std::bad_alloc& ba) {
506 B2FATAL(MemErr);
507 }
508 try {
509 solidCorner1Box1 = new G4Box(
510 "SectorSupport_Corner1_Box1", 0.5 * lx,
511 0.5 * sectorSupportPos->getOuterR(),
512 0.5 * sectorSupportGeometry->getCorner1Thickness());
513 } catch (std::bad_alloc& ba) {
514 B2FATAL(MemErr);
515 }
516 try {
517 solidCorner1Box2 =
518 new G4Box("SectorSupport_Corner1_Box2",
519 0.5 * (lx / cos(sectorSupportGeometry->getCornerAngle()) +
520 sectorSupportGeometry->getCorner1Width() *
521 tan(sectorSupportGeometry->getCornerAngle())),
522 0.5 * sectorSupportGeometry->getCorner1Width(),
523 0.5 * sectorSupportGeometry->getCorner1Thickness());
524 } catch (std::bad_alloc& ba) {
525 B2FATAL(MemErr);
526 }
527 x = sectorSupportPos->getX() + 0.5 * (sectorSupportGeometry->getCornerX() +
528 sectorSupportGeometry->getCorner1LX() +
529 sectorSupportGeometry->getThickness());
530 t1 = HepGeom::Translate3D(x, 0.5 * sectorSupportPos->getOuterR(), 0.);
531 t2 = HepGeom::Translate3D(
532 x, sectorSupportGeometry->getCorner1AInner().y() -
533 0.5 * sectorSupportGeometry->getCorner1Width() /
534 cos(sectorSupportGeometry->getCornerAngle()) +
535 0.5 * lx * tan(sectorSupportGeometry->getCornerAngle()), 0.) *
536 HepGeom::RotateZ3D(sectorSupportGeometry->getCornerAngle());
537 try {
538 is1 = new G4IntersectionSolid("SectorSupport_Corner1_Intersection1",
539 solidCorner1Tube, solidCorner1Box1, t1);
540 } catch (std::bad_alloc& ba) {
541 B2FATAL(MemErr);
542 }
543 try {
544 solidCorner1 = new G4IntersectionSolid("SectorSupport_Corner1", is1,
545 solidCorner1Box2, t2);
546 } catch (std::bad_alloc& ba) {
547 B2FATAL(MemErr);
548 }
549 try {
550 m_LogVol.sectorsup.corn1 =
551 new G4LogicalVolume(solidCorner1, m_Materials.duralumin, "Corner1");
552 } catch (std::bad_alloc& ba) {
553 B2FATAL(MemErr);
554 }
555 geometry::setVisibility(*m_LogVol.sectorsup.corn1, true);
556 geometry::setColor(*m_LogVol.sectorsup.corn1, "#ff0000ff");
557}
558
560{
561 G4TriangularPrism* solidCorner2Prism = nullptr;
562 G4SubtractionSolid* solidCorner2 = nullptr;
563 HepGeom::Transform3D t1;
564 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
565 m_GeoDat->getSectorSupportGeometry();
566 try {
567 solidCorner2Prism =
568 new G4TriangularPrism("SectorSupport_Corner2_Prism",
569 sectorSupportGeometry->getCorner2LY(),
570 90. * CLHEP::deg,
571 sectorSupportGeometry->getCorner2LX(),
572 180. * CLHEP::deg,
573 0.5 * sectorSupportGeometry->getCorner2Thickness());
574 } catch (std::bad_alloc& ba) {
575 B2FATAL(MemErr);
576 }
577 t1 = HepGeom::Translate3D(-sectorSupportGeometry->getCorner2Inner().x(),
578 -sectorSupportGeometry->getCorner2Inner().y(), 0);
579 try {
580 solidCorner2 = new G4SubtractionSolid("SectorSupport_Corner2",
581 solidCorner2Prism->getSolid(),
582 m_Solids.sectorsup.otube, t1);
583 } catch (std::bad_alloc& ba) {
584 B2FATAL(MemErr);
585 }
586 delete solidCorner2Prism;
587 try {
588 m_LogVol.sectorsup.corn2 =
589 new G4LogicalVolume(solidCorner2, m_Materials.duralumin, "Corner2");
590 } catch (std::bad_alloc& ba) {
591 B2FATAL(MemErr);
592 }
593 geometry::setVisibility(*m_LogVol.sectorsup.corn2, true);
594 geometry::setColor(*m_LogVol.sectorsup.corn2, "#ff0000ff");
595}
596
598{
599 G4TriangularPrism* solidCorner3Prism = nullptr;
600 G4SubtractionSolid* solidCorner3 = nullptr;
601 HepGeom::Transform3D t1;
602 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
603 m_GeoDat->getSectorSupportGeometry();
604 try {
605 solidCorner3Prism =
606 new G4TriangularPrism("SectorSupport_Corner3_Prism",
607 sectorSupportGeometry->getCorner3LX(), 0.,
608 sectorSupportGeometry->getCorner3LY(),
609 90. * CLHEP::deg,
610 0.5 * sectorSupportGeometry->getCorner3Thickness());
611 } catch (std::bad_alloc& ba) {
612 B2FATAL(MemErr);
613 }
614 t1 = HepGeom::Translate3D(-sectorSupportGeometry->getCorner3Prism().x(),
615 -sectorSupportGeometry->getCorner3Prism().y(), 0.);
616 try {
617 solidCorner3 = new G4SubtractionSolid("SectorSupport_Corner3",
618 solidCorner3Prism->getSolid(),
619 m_Solids.sectorsup.itube, t1);
620 } catch (std::bad_alloc& ba) {
621 B2FATAL(MemErr);
622 }
623 delete solidCorner3Prism;
624 try {
625 m_LogVol.sectorsup.corn3 =
626 new G4LogicalVolume(solidCorner3, m_Materials.duralumin, "Corner3");
627 } catch (std::bad_alloc& ba) {
628 B2FATAL(MemErr);
629 }
630 geometry::setVisibility(*m_LogVol.sectorsup.corn3, true);
631 geometry::setColor(*m_LogVol.sectorsup.corn3, "#ff0000ff");
632}
633
635{
636 G4TriangularPrism* solidCorner4Prism = nullptr;
637 G4SubtractionSolid* solidCorner4 = nullptr;
638 HepGeom::Transform3D t1;
639 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
640 m_GeoDat->getSectorSupportGeometry();
641 try {
642 solidCorner4Prism =
643 new G4TriangularPrism("SectorSupport_Corner4_Prism",
644 sectorSupportGeometry->getCorner4LX(), 0.,
645 sectorSupportGeometry->getCorner4LY(),
646 90. * CLHEP::deg,
647 0.5 * sectorSupportGeometry->getCorner4Thickness());
648 } catch (std::bad_alloc& ba) {
649 B2FATAL(MemErr);
650 }
651 t1 = HepGeom::Translate3D(-sectorSupportGeometry->getCorner4Prism().x(),
652 -sectorSupportGeometry->getCorner4Prism().y(), 0.);
653 try {
654 solidCorner4 = new G4SubtractionSolid("SectorSupport_Corner4",
655 solidCorner4Prism->getSolid(),
656 m_Solids.sectorsup.itube, t1);
657 } catch (std::bad_alloc& ba) {
658 B2FATAL(MemErr);
659 }
660 delete solidCorner4Prism;
661 try {
662 m_LogVol.sectorsup.corn4 =
663 new G4LogicalVolume(solidCorner4, m_Materials.duralumin, "Corner4");
664 } catch (std::bad_alloc& ba) {
665 B2FATAL(MemErr);
666 }
667 geometry::setVisibility(*m_LogVol.sectorsup.corn4, true);
668 geometry::setColor(*m_LogVol.sectorsup.corn4, "#ff0000ff");
669}
670
672{
673 G4Box* solidBoxX;
674 G4Box* solidBoxY;
675 G4Box* solidBoxTop;
676 G4Tubs* solidLimitationTube = nullptr;
677 G4UnionSolid* us1 = nullptr;
678 G4UnionSolid* us2 = nullptr;
679 G4UnionSolid* us3 = nullptr;
680 G4UnionSolid* us4 = nullptr;
681 G4IntersectionSolid* solidSectorSupport = nullptr;
682 HepGeom::Transform3D tbx;
683 HepGeom::Transform3D tby;
684 HepGeom::Transform3D tbt;
685 const EKLMGeometry::ElementPosition* sectorSupportPos =
686 m_GeoDat->getSectorSupportPosition();
687 solidBoxX = createSectorSupportBoxX(tbx);
688 solidBoxY = createSectorSupportBoxY(tby);
689 solidBoxTop = createSectorSupportBoxTop(tbt);
690 m_Solids.sectorsup.otube = createSectorSupportOuterTube();
691 m_Solids.sectorsup.itube = createSectorSupportInnerTube();
692 try {
693 solidLimitationTube = new G4Tubs("SectorSupport_LimitationTube",
694 0., sectorSupportPos->getOuterR(),
695 0.5 * sectorSupportPos->getLength(),
696 0., 90.*CLHEP::deg);
697 } catch (std::bad_alloc& ba) {
698 B2FATAL(MemErr);
699 }
700 try {
701 us1 = new G4UnionSolid("SectorSupport_Union1",
702 m_Solids.sectorsup.itube, solidBoxY, tby);
703 } catch (std::bad_alloc& ba) {
704 B2FATAL(MemErr);
705 }
706 try {
707 us2 = new G4UnionSolid("SectorSupport_Union2",
708 us1, solidBoxX, tbx);
709 } catch (std::bad_alloc& ba) {
710 B2FATAL(MemErr);
711 }
712 try {
713 us3 = new G4UnionSolid("SectorSupport_Union3", us2,
714 m_Solids.sectorsup.otube,
715 HepGeom::Translate3D(0., 0., 0.));
716 } catch (std::bad_alloc& ba) {
717 B2FATAL(MemErr);
718 }
719 try {
720 us4 = new G4UnionSolid("SectorSupport_Union4",
721 us3, solidBoxTop, tbt);
722 } catch (std::bad_alloc& ba) {
723 B2FATAL(MemErr);
724 }
725 try {
726 solidSectorSupport =
727 new G4IntersectionSolid("SectorSupport", us4, solidLimitationTube,
728 HepGeom::Translate3D(0., 0., 0.));
729 } catch (std::bad_alloc& ba) {
730 B2FATAL(MemErr);
731 }
732 try {
733 m_LogVol.sectorsup.supp =
734 new G4LogicalVolume(solidSectorSupport, m_Materials.duralumin, "Support");
735 } catch (std::bad_alloc& ba) {
736 B2FATAL(MemErr);
737 }
738 geometry::setVisibility(*m_LogVol.sectorsup.supp, true);
739 geometry::setColor(*m_LogVol.sectorsup.supp, "#ff0000ff");
740}
741
743{
744 const EKLMGeometry::ElementPosition* layerPos = m_GeoDat->getLayerPosition();
745 const EKLMGeometry::ElementPosition* sectorSupportPos =
746 m_GeoDat->getSectorSupportPosition();
747 try {
748 m_Solids.subtractionBox =
749 new G4Box("SubractionBox", 0.5 * sectorSupportPos->getOuterR(),
750 0.5 * sectorSupportPos->getOuterR(), layerPos->getLength());
751 } catch (std::bad_alloc& ba) {
752 B2FATAL(MemErr);
753 }
754}
755
756G4SubtractionSolid* EKLM::GeoEKLMCreator::
757cutSolidCorner(const char* name, G4VSolid* solid, G4Box* subtractionBox,
758 const HepGeom::Transform3D& transf, bool largerAngles,
759 double x1, double y1, double x2, double y2)
760{
761 double ang;
762 ang = atan2(y2 - y1, x2 - x1);
763 return cutSolidCorner(name, solid, subtractionBox, transf, largerAngles,
764 x1, y1, ang);
765}
766
767G4SubtractionSolid* EKLM::GeoEKLMCreator::
768cutSolidCorner(const char* name, G4VSolid* solid, G4Box* subtractionBox,
769 const HepGeom::Transform3D& transf, bool largerAngles,
770 double x, double y, double ang)
771{
772 double lx, ly;
773 HepGeom::Transform3D t;
774 G4SubtractionSolid* ss = nullptr;
775 lx = subtractionBox->GetXHalfLength();
776 ly = subtractionBox->GetYHalfLength();
777 if (largerAngles)
778 t = HepGeom::Translate3D(x + lx * cos(ang) - ly * sin(ang),
779 y + lx * sin(ang) + ly * cos(ang), 0) *
780 HepGeom::RotateZ3D(ang);
781 else
782 t = HepGeom::Translate3D(x + lx * cos(ang) + ly * sin(ang),
783 y + lx * sin(ang) - ly * cos(ang), 0) *
784 HepGeom::RotateZ3D(ang);
785 try {
786 ss = new G4SubtractionSolid(name, solid, subtractionBox, transf * t);
787 } catch (std::bad_alloc& ba) {
788 B2FATAL(MemErr);
789 }
790 return ss;
791}
792
794{
795 double box_x;
796 double box_y;
797 HepGeom::Transform3D t;
798 HepGeom::Transform3D t1;
799 char name[128];
800 G4Tubs* tb = nullptr;
801 G4IntersectionSolid* is = nullptr;
802 G4SubtractionSolid* ss1, *ss2, *ss3, *ss4;
803 const EKLMGeometry::ElementPosition* sectorSupportPos =
804 m_GeoDat->getSectorSupportPosition();
805 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
806 m_GeoDat->getSectorSupportGeometry();
807 const EKLMGeometry::ElementPosition* planePos = m_GeoDat->getPlanePosition();
808 /* Basic solids. */
809 snprintf(name, 128, "Plane_%d_Tube", n + 1);
810 try {
811 tb = new G4Tubs(name, planePos->getInnerR(), planePos->getOuterR(),
812 0.5 * planePos->getLength(), 0.0, 90.0 * CLHEP::deg);
813 } catch (std::bad_alloc& ba) {
814 B2FATAL(MemErr);
815 }
816 snprintf(name, 128, "Plane_%d_Box", n + 1);
817 box_x = sectorSupportPos->getX() + sectorSupportGeometry->getThickness();
818 box_y = sectorSupportPos->getY() + sectorSupportGeometry->getThickness();
819 /* Calculate transformations for boolean solids. */
820 t1 = HepGeom::Translate3D(m_Solids.subtractionBox->GetXHalfLength() + box_x,
821 m_Solids.subtractionBox->GetXHalfLength() + box_y,
822 0.);
823 /* For rotated plane. */
824 if (n == 0) {
825 t = HepGeom::Rotate3D(180. * CLHEP::deg,
826 HepGeom::Vector3D<double>(1., 1., 0.));
827 t1 = t * t1;
828 } else
829 t = HepGeom::Translate3D(0, 0, 0);
830 /* Boolean solids. */
831 snprintf(name, 128, "Plane_%d_Intersection", n + 1);
832 try {
833 is = new G4IntersectionSolid(name, tb, m_Solids.subtractionBox, t1);
834 } catch (std::bad_alloc& ba) {
835 B2FATAL(MemErr);
836 }
837 snprintf(name, 128, "Plane_%d_Subtraction_1", n + 1);
838 ss1 = cutSolidCorner(name, is, m_Solids.subtractionBox, t, true,
839 sectorSupportGeometry->getCorner1AInner().x(),
840 sectorSupportGeometry->getCorner1AInner().y(),
841 sectorSupportGeometry->getCornerAngle());
842 snprintf(name, 128, "Plane_%d_Subtraction_2", n + 1);
843 ss2 = cutSolidCorner(
844 name, ss1, m_Solids.subtractionBox, t, false,
845 sectorSupportGeometry->getCorner2Inner().x() -
846 sectorSupportGeometry->getCorner2LX(),
847 sectorSupportGeometry->getCorner2Inner().y(),
848 sectorSupportGeometry->getCorner2Inner().x(),
849 sectorSupportGeometry->getCorner2Inner().y() +
850 sectorSupportGeometry->getCorner2LY());
851 snprintf(name, 128, "Plane_%d_Subtraction_3", n + 1);
852 ss3 = cutSolidCorner(
853 name, ss2, m_Solids.subtractionBox, t, false,
854 sectorSupportGeometry->getCorner3Prism().x(),
855 sectorSupportGeometry->getCorner3Prism().y() +
856 sectorSupportGeometry->getCorner3LY(),
857 sectorSupportGeometry->getCorner3Prism().x() +
858 sectorSupportGeometry->getCorner3LX(),
859 sectorSupportGeometry->getCorner3Prism().y());
860 snprintf(name, 128, "Plane_%d_Subtraction_4", n + 1);
861 ss4 = cutSolidCorner(
862 name, ss3, m_Solids.subtractionBox, t, true,
863 sectorSupportGeometry->getCorner4Prism().x() +
864 sectorSupportGeometry->getCorner4LX(),
865 sectorSupportGeometry->getCorner4Prism().y(),
866 sectorSupportGeometry->getCorner4Prism().x(),
867 sectorSupportGeometry->getCorner4Prism().y() +
868 sectorSupportGeometry->getCorner4LY());
869 snprintf(name, 128, "Plane_%d", n + 1);
870 m_Solids.plane[n] = ss4;
871}
872
874createSegmentSupportLogicalVolume(int iPlane, int iSegmentSupport)
875{
876 HepGeom::Transform3D t1, t2;
877 G4Box* topBox = nullptr;
878 G4Box* midBox = nullptr;
879 G4Box* botBox = nullptr;
880 G4UnionSolid* us = nullptr;
881 G4UnionSolid* solidSegmentSupport = nullptr;
882 std::string segmentSupportName =
883 "SegmentSupport_" + std::to_string(iSegmentSupport) +
884 "_Plane_" + std::to_string(iPlane);
885 const EKLMGeometry::SegmentSupportPosition* segmentSupportPos =
886 m_GeoDat->getSegmentSupportPosition(iPlane, iSegmentSupport);
887 const EKLMGeometry::SegmentSupportGeometry* segmentSupportGeometry =
888 m_GeoDat->getSegmentSupportGeometry();
889 try {
890 topBox = new G4Box("BoxTop_" + segmentSupportName,
891 0.5 * (segmentSupportPos->getLength() -
892 segmentSupportPos->getDeltaLLeft() -
893 segmentSupportPos->getDeltaLRight()),
894 0.5 * segmentSupportGeometry->getTopWidth(),
895 0.5 * segmentSupportGeometry->getTopThickness());
896 } catch (std::bad_alloc& ba) {
897 B2FATAL(MemErr);
898 }
899 try {
900 midBox = new G4Box("BoxMiddle_" + segmentSupportName,
901 0.5 * (segmentSupportPos->getLength() -
902 segmentSupportPos->getDeltaLLeft() -
903 segmentSupportPos->getDeltaLRight()),
904 0.5 * segmentSupportGeometry->getMiddleWidth(),
905 0.5 * segmentSupportGeometry->getMiddleThickness());
906 } catch (std::bad_alloc& ba) {
907 B2FATAL(MemErr);
908 }
909 try {
910 botBox = new G4Box("BoxBottom_" + segmentSupportName,
911 0.5 * segmentSupportPos->getLength(),
912 0.5 * segmentSupportGeometry->getTopWidth(),
913 0.5 * segmentSupportGeometry->getTopThickness());
914 } catch (std::bad_alloc& ba) {
915 B2FATAL(MemErr);
916 }
917 t1 = HepGeom::Translate3D(
918 0., 0., 0.5 * (segmentSupportGeometry->getMiddleThickness() +
919 segmentSupportGeometry->getTopThickness()));
920 t2 = HepGeom::Translate3D(
921 0.5 * (segmentSupportPos->getDeltaLRight() -
922 segmentSupportPos->getDeltaLLeft()), 0.,
923 -0.5 * (segmentSupportGeometry->getMiddleThickness() +
924 segmentSupportGeometry->getTopThickness()));
925 try {
926 us = new G4UnionSolid("Union1_" + segmentSupportName, midBox, topBox, t1);
927 } catch (std::bad_alloc& ba) {
928 B2FATAL(MemErr);
929 }
930 try {
931 solidSegmentSupport = new G4UnionSolid(segmentSupportName, us, botBox, t2);
932 } catch (std::bad_alloc& ba) {
933 B2FATAL(MemErr);
934 }
935 try {
936 m_LogVol.segmentsup[iPlane - 1][iSegmentSupport - 1] =
937 new G4LogicalVolume(solidSegmentSupport, m_Materials.duralumin,
938 segmentSupportName);
939 } catch (std::bad_alloc& ba) {
940 B2FATAL(MemErr);
941 }
942 geometry::setVisibility(*m_LogVol.segmentsup[iPlane - 1][iSegmentSupport - 1],
943 true);
944 geometry::setColor(*m_LogVol.segmentsup[iPlane - 1][iSegmentSupport - 1],
945 "#ff0000ff");
946}
947
949unifySolids(G4VSolid** solids, HepGeom::Transform3D* transf,
950 int nSolids, const std::string& name)
951{
952 G4UnionSolid** u;
953 G4DisplacedSolid* d;
954 G4VSolid** solidArray;
955 HepGeom::Transform3D* inverseTransf;
956 HepGeom::Transform3D t;
957 char str[128];
958 /* cppcheck-suppress variableScope */
959 int n, nUnions, i, i1, i2, k, k1, k2, l, dl;
960 if (nSolids <= 1)
961 B2FATAL("Number of solids to be unified must be greater than 1.");
962 try {
963 inverseTransf = new HepGeom::Transform3D[nSolids];
964 } catch (std::bad_alloc& ba) {
965 B2FATAL(MemErr);
966 }
967 for (i = 0; i < nSolids; i++)
968 inverseTransf[i] = transf[i].inverse();
969 n = nSolids;
970 nUnions = 0;
971 while (n > 1) {
972 if (n % 2 == 0)
973 n = n / 2;
974 else
975 n = n / 2 + 1;
976 nUnions = nUnions + n;
977 }
978 u = static_cast<G4UnionSolid**>(malloc(sizeof(G4UnionSolid*) * nUnions));
979 if (u == nullptr)
980 B2FATAL(MemErr);
981 n = nSolids;
982 i2 = 0;
983 solidArray = solids;
984 k1 = 0;
985 k2 = nSolids;
986 dl = 1;
987 while (n > 1) {
988 i1 = i2;
989 if (n % 2 == 0)
990 n = n / 2;
991 else
992 n = n / 2 + 1;
993 i2 = i1 + n;
994 k = k1;
995 l = 0;
996 for (i = i1; i < i2; i++) {
997 if (k != k2 - 1) {
998 /* Unify k and k + 1 -> i */
999 t = inverseTransf[l] * transf[l + dl];
1000 try {
1001 snprintf(str, 128, "_Union_%d", i + 1);
1002 u[i] = new G4UnionSolid(name + str, solidArray[k],
1003 solidArray[k + 1], t);
1004 } catch (std::bad_alloc& ba) {
1005 B2FATAL(MemErr);
1006 }
1007 } else {
1008 /* Copy k -> i */
1009 u[i] = static_cast<G4UnionSolid*>(solids[k]);
1010 }
1011 k = k + 2;
1012 l = l + dl * 2;
1013 }
1014 solidArray = reinterpret_cast<G4VSolid**>(u);
1015 k1 = i1;
1016 k2 = i2;
1017 dl = dl * 2;
1018 }
1019 d = new G4DisplacedSolid(name + "_Displaced", u[nUnions - 1], transf[0]);
1020 free(u);
1021 delete[] inverseTransf;
1022 return d;
1023}
1024
1026{
1027 int i, m, nStrip;
1028 /* cppcheck-suppress variableScope */
1029 double ly;
1030 char name[128];
1031 G4VSolid** elements;
1032 HepGeom::Transform3D* t;
1033 const EKLMGeometry::PlasticSheetGeometry* plasticSheetGeometry =
1034 m_GeoDat->getPlasticSheetGeometry();
1035 const EKLMGeometry::StripGeometry* stripGeometry =
1036 m_GeoDat->getStripGeometry();
1037 nStrip = m_ElementNumbers->getNStripsSegment();
1038 elements = new G4VSolid*[nStrip];
1039 t = new HepGeom::Transform3D[nStrip];
1040 /* Transformations. */
1041 for (i = 0; i < nStrip; i++) {
1042 m = nStrip * iSegment + i;
1043 m_GeoDat->getSheetTransform(&(t[i]), m);
1044 }
1045 /* Sheet elements. */
1046 for (i = 0; i < nStrip; i++) {
1047 snprintf(name, 128, "PlasticSheet_%d_Element_%d", iSegment + 1, i + 1);
1048 ly = stripGeometry->getWidth();
1049 if (i == 0 || i == nStrip - 1)
1050 ly = ly - plasticSheetGeometry->getDeltaL();
1051 m = nStrip * iSegment + i;
1052 const EKLMGeometry::ElementPosition* stripPos =
1053 m_GeoDat->getStripPosition(m + 1);
1054 try {
1055 m_Solids.plasticSheetElement[m] =
1056 new G4Box(name, 0.5 * stripPos->getLength(), 0.5 * ly,
1057 0.5 * plasticSheetGeometry->getWidth());
1058 } catch (std::bad_alloc& ba) {
1059 B2FATAL(MemErr);
1060 }
1061 elements[i] = m_Solids.plasticSheetElement[m];
1062 }
1063 /* Union. */
1064 snprintf(name, 128, "PlasticSheet_%d", iSegment + 1);
1065 m_Solids.psheet[iSegment] = unifySolids(elements, t, nStrip, name);
1066 try {
1067 m_LogVol.psheet[iSegment] =
1068 new G4LogicalVolume(m_Solids.psheet[iSegment],
1069 m_Materials.polystyrol, name);
1070 } catch (std::bad_alloc& ba) {
1071 B2FATAL(MemErr);
1072 }
1073 geometry::setVisibility(*m_LogVol.psheet[iSegment], false);
1074 geometry::setColor(*m_LogVol.psheet[iSegment], "#00ff00ff");
1075 delete[] elements;
1076 delete[] t;
1077}
1078
1080{
1081 /* cppcheck-suppress variableScope */
1082 int i, m, nStrip;
1083 char name[128];
1084 G4VSolid** strips;
1085 HepGeom::Transform3D* t;
1086 nStrip = m_ElementNumbers->getNStripsSegment();
1087 strips = new G4VSolid*[nStrip];
1088 t = new HepGeom::Transform3D[nStrip];
1089 for (i = 0; i < nStrip; i++) {
1090 m = nStrip * iSegment + i;
1091 m_GeoDat->getStripTransform(&(t[i]), m);
1092 strips[i] = m_Solids.strip[m_GeoDat->getStripLengthIndex(m)];
1093 }
1094 snprintf(name, 128, "StripSegment_%d", iSegment + 1);
1095 m_Solids.stripSegment[iSegment] = unifySolids(strips, t, nStrip, name);
1096 try {
1097 m_LogVol.stripSegment[iSegment] =
1098 new G4LogicalVolume(m_Solids.stripSegment[iSegment], m_Materials.air,
1099 name);
1100 } catch (std::bad_alloc& ba) {
1101 B2FATAL(MemErr);
1102 }
1103 geometry::setVisibility(*m_LogVol.stripSegment[iSegment], false);
1104 geometry::setColor(*m_LogVol.stripSegment[iSegment], "#00ff00ff");
1105 delete[] strips;
1106 delete[] t;
1107}
1108
1110{
1111 double z;
1112 char name[128];
1113 G4UnionSolid* u1, *u2;
1114 HepGeom::Transform3D t;
1115 const EKLMGeometry::PlasticSheetGeometry* plasticSheetGeometry =
1116 m_GeoDat->getPlasticSheetGeometry();
1117 const EKLMGeometry::StripGeometry* stripGeometry =
1118 m_GeoDat->getStripGeometry();
1119 z = 0.5 * (stripGeometry->getThickness() + plasticSheetGeometry->getWidth());
1120 snprintf(name, 128, "Segment_%d_Union_1", iSegment + 1);
1121 t = HepGeom::Translate3D(0, 0, -z);
1122 try {
1123 u1 = new G4UnionSolid(name, m_Solids.stripSegment[iSegment],
1124 m_Solids.psheet[iSegment], t);
1125 } catch (std::bad_alloc& ba) {
1126 B2FATAL(MemErr);
1127 }
1128 snprintf(name, 128, "Segment_%d", iSegment + 1);
1129 t = HepGeom::Translate3D(0, 0, z);
1130 try {
1131 u2 = new G4UnionSolid(name, u1, m_Solids.psheet[iSegment], t);
1132 } catch (std::bad_alloc& ba) {
1133 B2FATAL(MemErr);
1134 }
1135 try {
1136 m_LogVol.segment[iSegment] =
1137 new G4LogicalVolume(u2, m_Materials.air, name);
1138 } catch (std::bad_alloc& ba) {
1139 B2FATAL(MemErr);
1140 }
1141 geometry::setVisibility(*m_LogVol.segment[iSegment], false);
1142 geometry::setColor(*m_LogVol.segment[iSegment], "#00ff00ff");
1143}
1144
1146{
1147 int iPos;
1148 char name[128];
1149 const EKLMGeometry::ElementPosition* stripPos;
1150 const EKLMGeometry::StripGeometry* stripGeometry =
1151 m_GeoDat->getStripGeometry();
1152 iPos = m_GeoDat->getStripPositionIndex(iStrip);
1153 stripPos = m_GeoDat->getStripPosition(iPos + 1);
1154 snprintf(name, 128, "Strip_%d", iStrip + 1);
1155 try {
1156 m_Solids.strip[iStrip] = new G4Box(name, 0.5 * stripPos->getLength(),
1157 0.5 * stripGeometry->getWidth(),
1158 0.5 * stripGeometry->getThickness());
1159 } catch (std::bad_alloc& ba) {
1160 B2FATAL(MemErr);
1161 }
1162 try {
1163 m_LogVol.strip[iStrip] =
1164 new G4LogicalVolume(m_Solids.strip[iStrip], m_Materials.polystyrene,
1165 name);
1166 } catch (std::bad_alloc& ba) {
1167 B2FATAL(MemErr);
1168 }
1169 geometry::setVisibility(*m_LogVol.strip[iStrip], true);
1170 geometry::setColor(*m_LogVol.strip[iStrip], "#ffffffff");
1171}
1172
1174{
1175 int iPos;
1176 char name[128];
1177 const EKLMGeometry::ElementPosition* stripPos;
1178 const EKLMGeometry::StripGeometry* stripGeometry =
1179 m_GeoDat->getStripGeometry();
1180 iPos = m_GeoDat->getStripPositionIndex(iStrip);
1181 stripPos = m_GeoDat->getStripPosition(iPos + 1);
1182 snprintf(name, 128, "Groove_%d", iStrip + 1);
1183 try {
1184 m_Solids.groove[iStrip] = new G4Box(name, 0.5 * stripPos->getLength(),
1185 0.5 * stripGeometry->getGrooveWidth(),
1186 0.5 * stripGeometry->getGrooveDepth());
1187 } catch (std::bad_alloc& ba) {
1188 B2FATAL(MemErr);
1189 }
1190 try {
1191 m_LogVol.groove[iStrip] =
1192 new G4LogicalVolume(m_Solids.groove[iStrip], m_Materials.gel, name);
1193 } catch (std::bad_alloc& ba) {
1194 B2FATAL(MemErr);
1195 }
1196 geometry::setVisibility(*m_LogVol.groove[iStrip], true);
1197 geometry::setColor(*m_LogVol.groove[iStrip], "#00ff00ff");
1198}
1199
1201{
1202 int iPos;
1203 char name[128];
1204 const EKLMGeometry::ElementPosition* stripPos;
1205 const EKLMGeometry::StripGeometry* stripGeometry =
1206 m_GeoDat->getStripGeometry();
1207 HepGeom::Transform3D t;
1208 G4Box* b;
1209 G4SubtractionSolid* scintillatorSolid;
1210 iPos = m_GeoDat->getStripPositionIndex(iStrip);
1211 stripPos = m_GeoDat->getStripPosition(iPos + 1);
1212 snprintf(name, 128, "StripSensitive_%d_Box", iStrip + 1);
1213 try {
1214 b = new G4Box(name,
1215 0.5 * stripPos->getLength() -
1216 stripGeometry->getNoScintillationThickness(),
1217 0.5 * stripGeometry->getWidth() -
1218 stripGeometry->getNoScintillationThickness(),
1219 0.5 * stripGeometry->getThickness() -
1220 stripGeometry->getNoScintillationThickness());
1221 } catch (std::bad_alloc& ba) {
1222 B2FATAL(MemErr);
1223 }
1224 snprintf(name, 128, "StripSensitive_%d", iStrip + 1);
1225 t = HepGeom::Translate3D(0., 0., 0.5 * (stripGeometry->getThickness() -
1226 stripGeometry->getGrooveDepth()));
1227 try {
1228 scintillatorSolid =
1229 new G4SubtractionSolid(name, b, m_Solids.groove[iStrip], t);
1230 } catch (std::bad_alloc& ba) {
1231 B2FATAL(MemErr);
1232 }
1233 try {
1234 m_LogVol.scint[iStrip] =
1235 new G4LogicalVolume(scintillatorSolid, m_Materials.polystyrene,
1236 name, 0, m_Sensitive, 0);
1237 } catch (std::bad_alloc& ba) {
1238 B2FATAL(MemErr);
1239 }
1240 geometry::setVisibility(*m_LogVol.scint[iStrip], false);
1241 geometry::setColor(*m_LogVol.scint[iStrip], "#ffffffff");
1242}
1243
1245{
1246 G4Box* box = nullptr;
1247 G4SubtractionSolid* ss1, *ss2, *ss3, *solidDetailA;
1248 double lx, ly;
1249 const EKLMGeometry::ShieldGeometry* shieldGeometry =
1250 m_GeoDat->getShieldGeometry();
1251 const EKLMGeometry::ShieldDetailGeometry* detailA =
1252 shieldGeometry->getDetailA();
1253 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1254 lx = detailA->getLengthX() / 2;
1255 ly = detailA->getLengthY() / 2;
1256 try {
1257 box = new G4Box("ShieldDetailA_Box", lx, ly,
1258 shieldGeometry->getThickness() / 2);
1259 } catch (std::bad_alloc& ba) {
1260 B2FATAL(MemErr);
1261 }
1262 ss1 = cutSolidCorner("ShieldDetailA_Subtraction_1", box,
1263 m_Solids.subtractionBox, t, false,
1264 detailA->getPoint(0)->getX() - lx,
1265 detailA->getPoint(0)->getY() - ly,
1266 detailA->getPoint(1)->getX() - lx,
1267 detailA->getPoint(1)->getY() - ly);
1268 ss2 = cutSolidCorner("ShieldDetailA_Subtraction_2", ss1,
1269 m_Solids.subtractionBox, t, true,
1270 detailA->getPoint(3)->getX() - lx,
1271 detailA->getPoint(3)->getY() - ly,
1272 detailA->getPoint(2)->getX() - lx,
1273 detailA->getPoint(2)->getY() - ly);
1274 ss3 = cutSolidCorner("ShieldDetailA_Subtraction_3", ss2,
1275 m_Solids.subtractionBox, t, false,
1276 detailA->getPoint(3)->getX() - lx,
1277 detailA->getPoint(3)->getY() - ly,
1278 detailA->getPoint(4)->getX() - lx,
1279 detailA->getPoint(4)->getY() - ly);
1280 solidDetailA = cutSolidCorner("ShieldDetailA", ss3,
1281 m_Solids.subtractionBox, t, false,
1282 detailA->getPoint(5)->getX() - lx,
1283 detailA->getPoint(5)->getY() - ly,
1284 detailA->getPoint(6)->getX() - lx,
1285 detailA->getPoint(6)->getY() - ly);
1286 try {
1287 m_LogVol.shield.detailA =
1288 new G4LogicalVolume(solidDetailA, m_Materials.polyethylene,
1289 "ShieldDetailA");
1290 } catch (std::bad_alloc& ba) {
1291 B2FATAL(MemErr);
1292 }
1293 geometry::setVisibility(*m_LogVol.shield.detailA, true);
1294 geometry::setColor(*m_LogVol.shield.detailA, "#00ff00ff");
1295}
1296
1298{
1299 G4Box* box = nullptr;
1300 G4SubtractionSolid* ss1, *solidDetailB;
1301 double lx, ly;
1302 const EKLMGeometry::ShieldGeometry* shieldGeometry =
1303 m_GeoDat->getShieldGeometry();
1304 const EKLMGeometry::ShieldDetailGeometry* detailB =
1305 shieldGeometry->getDetailB();
1306 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1307 lx = detailB->getLengthX() / 2;
1308 ly = detailB->getLengthY() / 2;
1309 try {
1310 box = new G4Box("ShieldDetailB_Box", lx, ly,
1311 shieldGeometry->getThickness() / 2);
1312 } catch (std::bad_alloc& ba) {
1313 B2FATAL(MemErr);
1314 }
1315 ss1 = cutSolidCorner("ShieldDetailB_Subtraction_1", box,
1316 m_Solids.subtractionBox, t, false,
1317 detailB->getPoint(0)->getX() - lx,
1318 detailB->getPoint(0)->getY() - ly,
1319 detailB->getPoint(1)->getX() - lx,
1320 detailB->getPoint(1)->getY() - ly);
1321 solidDetailB = cutSolidCorner("ShieldDetailB", ss1,
1322 m_Solids.subtractionBox, t, false,
1323 detailB->getPoint(2)->getX() - lx,
1324 detailB->getPoint(2)->getY() - ly,
1325 detailB->getPoint(3)->getX() - lx,
1326 detailB->getPoint(3)->getY() - ly);
1327 try {
1328 m_LogVol.shield.detailB =
1329 new G4LogicalVolume(solidDetailB, m_Materials.polyethylene,
1330 "ShieldDetailB");
1331 } catch (std::bad_alloc& ba) {
1332 B2FATAL(MemErr);
1333 }
1334 geometry::setVisibility(*m_LogVol.shield.detailB, true);
1335 geometry::setColor(*m_LogVol.shield.detailB, "#00ff00ff");
1336}
1337
1339{
1340 G4Box* box = nullptr;
1341 G4SubtractionSolid* ss1, *ss2, *ss3, *solidDetailC;
1342 double lx, ly;
1343 const EKLMGeometry::ShieldGeometry* shieldGeometry =
1344 m_GeoDat->getShieldGeometry();
1345 const EKLMGeometry::ShieldDetailGeometry* detailC =
1346 shieldGeometry->getDetailC();
1347 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1348 lx = detailC->getLengthX() / 2;
1349 ly = detailC->getLengthY() / 2;
1350 try {
1351 box = new G4Box("ShieldDetailC_Box", lx, ly,
1352 shieldGeometry->getThickness() / 2);
1353 } catch (std::bad_alloc& ba) {
1354 B2FATAL(MemErr);
1355 }
1356 ss1 = cutSolidCorner("ShieldDetailC_Subtraction_1", box,
1357 m_Solids.subtractionBox, t, false,
1358 detailC->getPoint(0)->getX() - lx,
1359 detailC->getPoint(0)->getY() - ly,
1360 detailC->getPoint(1)->getX() - lx,
1361 detailC->getPoint(1)->getY() - ly);
1362 ss2 = cutSolidCorner("ShieldDetailC_Subtraction_2", ss1,
1363 m_Solids.subtractionBox, t, true,
1364 detailC->getPoint(3)->getX() - lx,
1365 detailC->getPoint(3)->getY() - ly,
1366 detailC->getPoint(2)->getX() - lx,
1367 detailC->getPoint(2)->getY() - ly);
1368 ss3 = cutSolidCorner("ShieldDetailC_Subtraction_3", ss2,
1369 m_Solids.subtractionBox, t, false,
1370 detailC->getPoint(3)->getX() - lx,
1371 detailC->getPoint(3)->getY() - ly,
1372 detailC->getPoint(4)->getX() - lx,
1373 detailC->getPoint(4)->getY() - ly);
1374 solidDetailC = cutSolidCorner("ShieldDetailC", ss3,
1375 m_Solids.subtractionBox, t, false,
1376 detailC->getPoint(5)->getX() - lx,
1377 detailC->getPoint(5)->getY() - ly,
1378 detailC->getPoint(6)->getX() - lx,
1379 detailC->getPoint(6)->getY() - ly);
1380 try {
1381 m_LogVol.shield.detailC =
1382 new G4LogicalVolume(solidDetailC, m_Materials.polyethylene,
1383 "ShieldDetailC");
1384 } catch (std::bad_alloc& ba) {
1385 B2FATAL(MemErr);
1386 }
1387 geometry::setVisibility(*m_LogVol.shield.detailC, true);
1388 geometry::setColor(*m_LogVol.shield.detailC, "#00ff00ff");
1389}
1390
1392{
1393 G4TriangularPrism* solidDetailDPrism;
1394 const EKLMGeometry::ShieldGeometry* shieldGeometry =
1395 m_GeoDat->getShieldGeometry();
1396 try {
1397 const EKLMGeometry::ShieldDetailGeometry* detailD =
1398 shieldGeometry->getDetailD();
1399 solidDetailDPrism =
1400 new G4TriangularPrism("ShieldDetailD_Prism",
1401 detailD->getLengthX(), 0.,
1402 detailD->getLengthY(), 90. * CLHEP::deg,
1403 shieldGeometry->getThickness() / 2);
1404 } catch (std::bad_alloc& ba) {
1405 B2FATAL(MemErr);
1406 }
1407 try {
1408 m_LogVol.shield.detailD =
1409 new G4LogicalVolume(solidDetailDPrism->getSolid(),
1410 m_Materials.polyethylene, "ShieldDetailD");
1411 } catch (std::bad_alloc& ba) {
1412 B2FATAL(MemErr);
1413 }
1414 geometry::setVisibility(*m_LogVol.shield.detailD, true);
1415 geometry::setColor(*m_LogVol.shield.detailD, "#00ff00ff");
1416 delete solidDetailDPrism;
1417}
1418
1420{
1421 int i, j, n;
1422 HepGeom::Transform3D t;
1423 /* Section, layer, sector. */
1437 /* Plane. */
1439 for (i = 0; i < m_GeoDat->getNPlanes(); i++) {
1441 /* Segment support. */
1442 for (j = 1; j <= m_GeoDat->getNSegments() + 1; j++)
1444 }
1445 /* Strips. */
1446 n = m_GeoDat->getNStripsDifferentLength();
1447 for (i = 0; i < n; i++) {
1451 }
1452 /* Plastic sheet elements. */
1453 for (i = 0; i < m_GeoDat->getNSegments(); i++)
1455 /* Strip segments. */
1456 for (i = 0; i < m_GeoDat->getNSegments(); i++)
1458 /* Segments. */
1459 for (i = 0; i < m_GeoDat->getNSegments(); i++)
1461 /* Shield layer details. */
1466}
1467
1468/************************** CREATION OF VOLUMES ******************************/
1469
1470G4LogicalVolume*
1471EKLM::GeoEKLMCreator::createSection(G4LogicalVolume* topVolume) const
1472{
1473 G4LogicalVolume* logicSection = nullptr;
1474 const HepGeom::Transform3D* t;
1475 std::string sectionName = "Section_" + std::to_string(m_CurVol.section);
1476 try {
1477 logicSection = new G4LogicalVolume(m_Solids.section, m_Materials.iron,
1478 sectionName);
1479 } catch (std::bad_alloc& ba) {
1480 B2FATAL(MemErr);
1481 }
1482 geometry::setVisibility(*logicSection, true);
1483 geometry::setColor(*logicSection, "#ffffff22");
1484 t = m_TransformData->getSectionTransform(m_CurVol.section);
1485 try {
1486 new G4PVPlacement(*t, logicSection, sectionName, topVolume, false,
1487 m_CurVol.section, false);
1488 } catch (std::bad_alloc& ba) {
1489 B2FATAL(MemErr);
1490 }
1491 return logicSection;
1492}
1493
1495createLayer(G4LogicalVolume* section) const
1496{
1497 G4LogicalVolume* logicLayer;
1498 const HepGeom::Transform3D* t;
1499 std::string layerName = "Layer_" + std::to_string(m_CurVol.layer) +
1500 "_" + section->GetName();
1501 logicLayer = createLayerLogicalVolume(layerName.c_str());
1502 t = m_TransformData->getLayerTransform(m_CurVol.section, m_CurVol.layer);
1503 try {
1504 new G4PVPlacement(*t, logicLayer, logicLayer->GetName(), section, false,
1505 m_CurVol.layer, false);
1506 } catch (std::bad_alloc& ba) {
1507 B2FATAL(MemErr);
1508 }
1509 return logicLayer;
1510}
1511
1513createSector(G4LogicalVolume* layer) const
1514{
1515 G4LogicalVolume* logicSector;
1516 const HepGeom::Transform3D* t;
1517 std::string sectorName = "Sector_" + std::to_string(m_CurVol.sector) +
1518 "_" + layer->GetName();
1519 logicSector = createSectorLogicalVolume(sectorName.c_str());
1520 t = m_TransformData->getSectorTransform(m_CurVol.section, m_CurVol.layer,
1521 m_CurVol.sector);
1522 try {
1523 new G4PVPlacement(*t, logicSector, logicSector->GetName(), layer, false,
1524 m_CurVol.sector, false);
1525 } catch (std::bad_alloc& ba) {
1526 B2FATAL(MemErr);
1527 }
1528 return logicSector;
1529}
1530
1532createSectorCover(int iCover, G4LogicalVolume* sector) const
1533{
1534 double z;
1535 HepGeom::Transform3D t;
1536 const EKLMGeometry::ElementPosition* sectorPos =
1537 m_GeoDat->getSectorPosition();
1538 const EKLMGeometry::ElementPosition* sectorSupportPos =
1539 m_GeoDat->getSectorSupportPosition();
1540 z = 0.25 * (sectorPos->getLength() + sectorSupportPos->getLength());
1541 if (iCover == 2)
1542 z = -z;
1543 t = HepGeom::Translate3D(0., 0., z);
1544 try {
1545 G4LogicalVolume* lv = m_LogVol.cover;
1546 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1547 false, 1, false);
1548 } catch (std::bad_alloc& ba) {
1549 B2FATAL(MemErr);
1550 }
1551}
1552
1554createSectorSupportCorner1(G4LogicalVolume* sector) const
1555{
1556 HepGeom::Transform3D t;
1557 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1558 m_GeoDat->getSectorSupportGeometry();
1559 t = HepGeom::Translate3D(0., 0., sectorSupportGeometry->getCorner1Z());
1560 try {
1561 G4LogicalVolume* lv = m_LogVol.sectorsup.corn1;
1562 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1563 false, 1, false);
1564 } catch (std::bad_alloc& ba) {
1565 B2FATAL(MemErr);
1566 }
1567}
1568
1570createSectorSupportCorner2(G4LogicalVolume* sector) const
1571{
1572 HepGeom::Transform3D t;
1573 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1574 m_GeoDat->getSectorSupportGeometry();
1575 t = HepGeom::Translate3D(sectorSupportGeometry->getCorner2Inner().x(),
1576 sectorSupportGeometry->getCorner2Inner().y(),
1577 sectorSupportGeometry->getCorner2Z());
1578 try {
1579 G4LogicalVolume* lv = m_LogVol.sectorsup.corn2;
1580 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1581 false, 1, false);
1582 } catch (std::bad_alloc& ba) {
1583 B2FATAL(MemErr);
1584 }
1585}
1586
1588createSectorSupportCorner3(G4LogicalVolume* sector) const
1589{
1590 HepGeom::Transform3D t;
1591 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1592 m_GeoDat->getSectorSupportGeometry();
1593 t = HepGeom::Translate3D(sectorSupportGeometry->getCorner3Prism().x(),
1594 sectorSupportGeometry->getCorner3Prism().y(),
1595 sectorSupportGeometry->getCorner3Z());
1596 try {
1597 G4LogicalVolume* lv = m_LogVol.sectorsup.corn3;
1598 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1599 false, 1, false);
1600 } catch (std::bad_alloc& ba) {
1601 B2FATAL(MemErr);
1602 }
1603}
1604
1606createSectorSupportCorner4(G4LogicalVolume* sector) const
1607{
1608 HepGeom::Transform3D t;
1609 const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1610 m_GeoDat->getSectorSupportGeometry();
1611 t = HepGeom::Translate3D(sectorSupportGeometry->getCorner4Prism().x(),
1612 sectorSupportGeometry->getCorner4Prism().y(),
1613 sectorSupportGeometry->getCorner4Z());
1614 try {
1615 G4LogicalVolume* lv = m_LogVol.sectorsup.corn4;
1616 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1617 false, 1, false);
1618 } catch (std::bad_alloc& ba) {
1619 B2FATAL(MemErr);
1620 }
1621}
1622
1624createSectorSupport(G4LogicalVolume* sector) const
1625{
1626 HepGeom::Transform3D t;
1627 const EKLMGeometry::ElementPosition* sectorSupportPos =
1628 m_GeoDat->getSectorSupportPosition();
1629 t = HepGeom::Translate3D(0., 0., sectorSupportPos->getZ());
1630 try {
1631 G4LogicalVolume* lv = m_LogVol.sectorsup.supp;
1632 new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1633 false, 1, false);
1634 } catch (std::bad_alloc& ba) {
1635 B2FATAL(MemErr);
1636 }
1637}
1638
1639G4LogicalVolume*
1640EKLM::GeoEKLMCreator::createPlane(G4LogicalVolume* sector) const
1641{
1642 G4LogicalVolume* logicPlane = nullptr;
1643 const HepGeom::Transform3D* t;
1644 std::string planeName =
1645 "Plane_" + std::to_string(m_CurVol.plane) + "_" + sector->GetName();
1646 try {
1647 logicPlane = new G4LogicalVolume(m_Solids.plane[m_CurVol.plane - 1],
1648 m_Materials.air, planeName);
1649 } catch (std::bad_alloc& ba) {
1650 B2FATAL(MemErr);
1651 }
1652 geometry::setVisibility(*logicPlane, false);
1653 t = m_TransformData->getPlaneTransform(m_CurVol.section, m_CurVol.layer,
1654 m_CurVol.sector, m_CurVol.plane);
1655 try {
1656 new G4PVPlacement(*t, logicPlane, planeName, sector, false,
1657 m_CurVol.plane, false);
1658 } catch (std::bad_alloc& ba) {
1659 B2FATAL(MemErr);
1660 }
1661 return logicPlane;
1662}
1663
1665createSegmentSupport(int iSegmentSupport, G4LogicalVolume* plane) const
1666{
1667 HepGeom::Transform3D t;
1668 G4LogicalVolume* lv =
1669 m_LogVol.segmentsup[m_CurVol.plane - 1][iSegmentSupport - 1];
1670 const EKLMGeometry::SegmentSupportPosition* segmentSupportPos =
1671 m_GeoDat->getSegmentSupportPosition(m_CurVol.plane, iSegmentSupport);
1672 t = (*m_TransformData->getPlaneDisplacement(m_CurVol.section, m_CurVol.layer,
1673 m_CurVol.sector, m_CurVol.plane)) *
1674 HepGeom::Translate3D(
1675 0.5 * (segmentSupportPos->getDeltaLLeft() -
1676 segmentSupportPos->getDeltaLRight()) +
1677 segmentSupportPos->getX(), segmentSupportPos->getY(),
1678 segmentSupportPos->getZ()) *
1679 HepGeom::RotateX3D(180.0 * CLHEP::deg);
1680 try {
1681 new G4PVPlacement(t, lv, lv->GetName() + "_" + plane->GetName(), plane,
1682 false, 1, false);
1683 } catch (std::bad_alloc& ba) {
1684 B2FATAL(MemErr);
1685 }
1686}
1687
1688void EKLM::GeoEKLMCreator::createPlasticSheet(int iSheetPlane, int iSheet) const
1689{
1690 double z;
1691 HepGeom::Transform3D t;
1692 const EKLMGeometry::PlasticSheetGeometry* plasticSheetGeometry =
1693 m_GeoDat->getPlasticSheetGeometry();
1694 const EKLMGeometry::StripGeometry* stripGeometry =
1695 m_GeoDat->getStripGeometry();
1696 std::string sheetName =
1697 "Sheet_" + std::to_string(iSheet) +
1698 "_SheetPlane_" + std::to_string(iSheetPlane);
1699 z = 0.5 * (stripGeometry->getThickness() + plasticSheetGeometry->getWidth());
1700 if (iSheetPlane == 2)
1701 z = -z;
1702 t = HepGeom::Translate3D(0, 0, z);
1703 try {
1704 new G4PVPlacement(t, m_LogVol.psheet[iSheet - 1], sheetName,
1705 m_LogVol.segment[iSheet - 1], false, (iSheetPlane - 1) *
1706 m_GeoDat->getNSegments() + iSheet, false);
1707 } catch (std::bad_alloc& ba) {
1708 B2FATAL(MemErr);
1709 }
1710}
1711
1713{
1714 HepGeom::Transform3D t;
1715 std::string segmentName = "StripSegment_" + std::to_string(iSegment);
1716 t = HepGeom::Translate3D(0, 0, 0);
1717 try {
1718 new G4PVPlacement(t, m_LogVol.stripSegment[iSegment - 1], segmentName,
1719 m_LogVol.segment[iSegment - 1], false, iSegment, false);
1720 } catch (std::bad_alloc& ba) {
1721 B2FATAL(MemErr);
1722 }
1723}
1724
1725void EKLM::GeoEKLMCreator::createSegment(G4LogicalVolume* plane) const
1726{
1727 HepGeom::Transform3D t;
1728 std::string segmentName =
1729 "Segment_" + std::to_string(m_CurVol.segment) + "_" + plane->GetName();
1730 t = (*m_TransformData->getPlaneDisplacement(m_CurVol.section, m_CurVol.layer,
1731 m_CurVol.sector, m_CurVol.plane)) *
1732 (*m_TransformData->getSegmentTransform(
1733 m_CurVol.section, m_CurVol.layer, m_CurVol.sector, m_CurVol.plane,
1734 m_CurVol.segment));
1735 try {
1736 new G4PVPlacement(t, m_LogVol.segment[m_CurVol.segment - 1], segmentName,
1737 plane, false, m_CurVol.segment, false);
1738 } catch (std::bad_alloc& ba) {
1739 B2FATAL(MemErr);
1740 }
1741}
1742
1743void EKLM::GeoEKLMCreator::createStrip(G4LogicalVolume* segment) const
1744{
1745 int n;
1746 HepGeom::Transform3D t, t2;
1747 G4LogicalVolume* lv;
1748 n = m_GeoDat->getStripLengthIndex(m_CurVol.strip - 1);
1749 m_GeoDat->getStripTransform(&t, m_CurVol.strip - 1);
1750 t2 = t * HepGeom::RotateX3D(180.0 * CLHEP::deg);
1751 lv = m_LogVol.strip[n];
1752 try {
1753 new G4PVPlacement(t2, lv, lv->GetName(), segment, false, m_CurVol.strip,
1754 false);
1755 } catch (std::bad_alloc& ba) {
1756 B2FATAL(MemErr);
1757 }
1758}
1759
1761{
1762 HepGeom::Transform3D t;
1763 G4LogicalVolume* lv;
1764 G4LogicalVolume* lvm;
1765 const EKLMGeometry::StripGeometry* stripGeometry =
1766 m_GeoDat->getStripGeometry();
1767 t = HepGeom::Translate3D(0., 0., 0.5 * (stripGeometry->getThickness() -
1768 stripGeometry->getGrooveDepth()));
1769 lvm = m_LogVol.strip[iStrip];
1770 lv = m_LogVol.groove[iStrip];
1771 try {
1772 new G4PVPlacement(t, lv, lv->GetName(), lvm, false, 1, false);
1773 } catch (std::bad_alloc& ba) {
1774 B2FATAL(MemErr);
1775 }
1776}
1777
1779{
1780 HepGeom::Transform3D t;
1781 G4LogicalVolume* lv;
1782 G4LogicalVolume* lvm;
1783 t = HepGeom::Translate3D(0., 0., 0.);
1784 lvm = m_LogVol.strip[iStrip];
1785 lv = m_LogVol.scint[iStrip];
1786 try {
1787 new G4PVPlacement(t, lv, lv->GetName(), lvm, false, 1, false);
1788 } catch (std::bad_alloc& ba) {
1789 B2FATAL(MemErr);
1790 }
1791}
1792
1793void EKLM::GeoEKLMCreator::createShield(G4LogicalVolume* sector) const
1794{
1795 HepGeom::Transform3D ta, tb, tc, td, te;
1796 G4LogicalVolume* lv;
1797 double lx, ly;
1798 const double asqrt2 = 1.0 / sqrt(2.0);
1799 const EKLMGeometry::ShieldGeometry* shieldGeometry =
1800 m_GeoDat->getShieldGeometry();
1801 lx = shieldGeometry->getDetailB()->getLengthX() / 2;
1802 ly = shieldGeometry->getDetailB()->getLengthY() / 2;
1803 ta = HepGeom::Translate3D(shieldGeometry->getDetailACenter()->getX(),
1804 shieldGeometry->getDetailACenter()->getY(), 0) *
1805 HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1806 tb = HepGeom::Translate3D(shieldGeometry->getDetailBCenter()->getX(),
1807 shieldGeometry->getDetailBCenter()->getY(), 0) *
1808 HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1809 tc = HepGeom::Translate3D(shieldGeometry->getDetailCCenter()->getX(),
1810 shieldGeometry->getDetailCCenter()->getY(), 0) *
1811 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1812 HepGeom::RotateY3D(180.0 * CLHEP::deg);
1813 td = HepGeom::Translate3D(
1814 shieldGeometry->getDetailBCenter()->getX() + asqrt2 * (-lx - ly),
1815 shieldGeometry->getDetailBCenter()->getY() + asqrt2 * (lx - ly), 0) *
1816 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1817 HepGeom::RotateX3D(180.0 * CLHEP::deg);
1818 te = HepGeom::Translate3D(
1819 shieldGeometry->getDetailBCenter()->getX() + asqrt2 * (lx - ly),
1820 shieldGeometry->getDetailBCenter()->getY() + asqrt2 * (-lx - ly), 0) *
1821 HepGeom::RotateZ3D(135.0 * CLHEP::deg);
1822 lv = m_LogVol.shield.detailA;
1823 try {
1824 new G4PVPlacement(ta, lv, lv->GetName(), sector, false, 1, false);
1825 } catch (std::bad_alloc& ba) {
1826 B2FATAL(MemErr);
1827 }
1828 lv = m_LogVol.shield.detailB;
1829 try {
1830 new G4PVPlacement(tb, lv, lv->GetName(), sector, false, 1, false);
1831 } catch (std::bad_alloc& ba) {
1832 B2FATAL(MemErr);
1833 }
1834 lv = m_LogVol.shield.detailC;
1835 try {
1836 new G4PVPlacement(tc, lv, lv->GetName(), sector, false, 1, false);
1837 } catch (std::bad_alloc& ba) {
1838 B2FATAL(MemErr);
1839 }
1840 lv = m_LogVol.shield.detailD;
1841 try {
1842 new G4PVPlacement(td, lv, lv->GetName(), sector, false, 1, false);
1843 } catch (std::bad_alloc& ba) {
1844 B2FATAL(MemErr);
1845 }
1846 try {
1847 new G4PVPlacement(te, lv, "ShieldDetailE", sector, false, 1, false);
1848 } catch (std::bad_alloc& ba) {
1849 B2FATAL(MemErr);
1850 }
1851}
1852
1853bool EKLM::GeoEKLMCreator::detectorLayer(int section, int layer) const
1854{
1855 return ((section == 1 && layer <= m_GeoDat->getNDetectorLayers(1)) ||
1856 (section == 2 && layer <= m_GeoDat->getNDetectorLayers(2)));
1857}
1858
1859void EKLM::GeoEKLMCreator::create(G4LogicalVolume& topVolume)
1860{
1861 /* cppcheck-suppress variableScope */
1862 int i, j, imin, imax;
1863 G4LogicalVolume* section, *layer, *sector, *plane;
1865 createSolids();
1866 /* Create physical volumes which are used only once. */
1867 for (i = 0; i < m_GeoDat->getNStripsDifferentLength(); i++) {
1870 }
1871 for (i = 0; i < m_GeoDat->getNSegments(); i++) {
1872 imin = i * m_ElementNumbers->getNStripsSegment();
1873 imax = (i + 1) * m_ElementNumbers->getNStripsSegment();
1874 for (m_CurVol.strip = imin + 1; m_CurVol.strip <= imax; m_CurVol.strip++)
1875 createStrip(m_LogVol.stripSegment[i]);
1876 }
1877 for (i = 1; i <= m_GeoDat->getNSegments(); i++) {
1878 for (j = 1; j <= 2; j++)
1879 createPlasticSheet(j, i);
1881 }
1882 /* Create other volumes. */
1883 /* Set up region for production cuts. */
1884 G4Region* aRegion = 0;
1885 for (m_CurVol.section = 1; m_CurVol.section <= m_GeoDat->getNSections();
1886 m_CurVol.section++) {
1887 section = createSection(&topVolume);
1888 /* Assign same region to each section. */
1889 if (not aRegion) aRegion = new G4Region("EKLMEnvelope");
1890 section->SetRegion(aRegion);
1891 aRegion->AddRootLogicalVolume(section);
1892 for (m_CurVol.layer = 1; m_CurVol.layer <= m_GeoDat->getNLayers();
1893 m_CurVol.layer++) {
1894 layer = createLayer(section);
1895 for (m_CurVol.sector = 1; m_CurVol.sector <= m_GeoDat->getNSectors();
1896 m_CurVol.sector++) {
1897 sector = createSector(layer);
1898 createSectorSupport(sector);
1903 for (i = 1; i <= 2; i++)
1904 createSectorCover(i, sector);
1905 if (detectorLayer(m_CurVol.section, m_CurVol.layer)) {
1906 /* Detector layer. */
1907 for (m_CurVol.plane = 1; m_CurVol.plane <= m_GeoDat->getNPlanes();
1908 m_CurVol.plane++) {
1909 plane = createPlane(sector);
1910 for (i = 1; i <= m_GeoDat->getNSegments() + 1; i++)
1911 createSegmentSupport(i, plane);
1912 for (m_CurVol.segment = 1;
1913 m_CurVol.segment <= m_GeoDat->getNSegments();
1914 m_CurVol.segment++)
1915 createSegment(plane);
1916 }
1917 } else {
1918 /* Shield layer. */
1919 createShield(sector);
1920 }
1921 }
1922 }
1923 }
1924}
1925
1927 G4LogicalVolume& topVolume,
1929{
1930 (void)content;
1931 (void)type;
1933 try {
1936 } catch (std::bad_alloc& ba) {
1937 B2FATAL(MemErr);
1938 }
1939 newVolumes();
1940 newSensitive();
1941 create(topVolume);
1942}
1943
1944void EKLM::GeoEKLMCreator::createFromDB(const std::string& name,
1945 G4LogicalVolume& topVolume,
1947{
1948 (void)name;
1949 (void)type;
1951 try {
1954 } catch (std::bad_alloc& ba) {
1955 B2FATAL(MemErr);
1956 }
1957 newVolumes();
1958 newSensitive();
1959 create(topVolume);
1960}
1961
1963 const IntervalOfValidity& iov)
1964{
1965 (void)content;
1967 try {
1970 } catch (std::bad_alloc& ba) {
1971 B2FATAL(MemErr);
1972 }
1973 m_GeoDat->saveToDatabase(iov);
1974}
1975
static const EKLMElementNumbers & Instance()
Instantiation.
Position information for the elements of detector.
double getX() const
Get X coordinate.
double getOuterR() const
Get outer radius.
double getInnerR() const
Get inner radius.
double getZ() const
Get Z coordinate.
double getY() const
Get Y coordinate.
double getLength() const
Get length.
Endcap srtucture geometry parameters.
double getPhi() const
Get starting angle of the octagonal endcap structure shape.
int getNSides() const
Get number of sides.
double getDeltaL() const
Get Delta L (edge of last strip - edge of plastic sheet distance).
double getX() const
Get X coordinate.
double getY() const
Get Y coordinate.
double getCorner2Thickness() const
Get corner 2 thickness.
double getCorner2LY() const
Get corner 2 Y length.
double getCorner4Thickness() const
Get corner 4 thickness.
double getCorner1Z() const
Get corner 1 Z coordinate.
double getCornerX() const
Get coordinate X of corner 1.
double getCorner4LX() const
Get corner 4 X length.
double getCorner1LX() const
Get corner 1 X length.
double getCorner3LX() const
Get corner 3 X length.
const HepGeom::Point3D< double > & getCorner1B() const
Get corner 1B coordinates.
double getCornerAngle() const
Get corner 1 angle.
double getCorner4LY() const
Get corner 4 Y length.
const HepGeom::Point3D< double > & getCorner3Prism() const
Get coordinates of the corner of corner 3 prism.
const HepGeom::Point3D< double > & getCorner4() const
Get corner 4 coordinates.
double getCorner2LX() const
Get corner 2 X length.
const HepGeom::Point3D< double > & getCorner4Prism() const
Get coordinates of the corner of corner 4 prism.
double getThickness() const
Get thickness.
const HepGeom::Point3D< double > & getCorner3() const
Get corner 3 coordinates.
double getCorner4Z() const
Get corner 4 Z coordinate.
double getCorner3Z() const
Get corner 3 Z coordinate.
const HepGeom::Point3D< double > & getCorner1A() const
Get corner 1A coordinates.
double getCorner3Thickness() const
Get corner 3 thickness.
double getDeltaLY() const
Get outerR - Y of upper edge of BoxY.
const HepGeom::Point3D< double > & getCorner1AInner() const
Get corner 1A coordinates (inner side).
const HepGeom::Point3D< double > & getCorner2Inner() const
Get corner 2 coordinates (inner side).
double getCorner3LY() const
Get corner 3 Y length.
double getCorner1Width() const
Get corner 1 width.
double getCorner1Thickness() const
Get corner 1 thickness.
double getCorner2Z() const
Get corner 2 Z coordinate.
double getMiddleWidth() const
Get middle part width.
double getTopThickness() const
Get top part thickness.
double getTopWidth() const
Get top part width.
double getMiddleThickness() const
Get middle part thickness.
double getX() const
Get X coordinate.
double getZ() const
Get Z coordinate.
double getY() const
Get Y coordinate.
double getDeltaLRight() const
Get right Delta L.
double getDeltaLLeft() const
Get left Delta L.
Shield layer detail geometry data.
const Point * getPoint(int i) const
Get point.
double getLengthY() const
Get Y length.
double getLengthX() const
Get X length.
Shield layer geometry data.
const ShieldDetailGeometry * getDetailA() const
Get detail A geometry.
const ShieldDetailGeometry * getDetailB() const
Get detail B geometry.
const Point * getDetailCCenter() const
Get detail C center.
double getThickness() const
Get thickness.
const ShieldDetailGeometry * getDetailD() const
Get detail D geometry.
const Point * getDetailACenter() const
Get detail A center.
const Point * getDetailBCenter() const
Get detail B center.
const ShieldDetailGeometry * getDetailC() const
Get detail C geometry.
double getWidth() const
Get width.
double getNoScintillationThickness() const
Get nonscintillating layer thickness.
double getGrooveDepth() const
Get groove depth.
double getThickness() const
Get thickness.
double getGrooveWidth() const
Get groove width.
~GeoEKLMCreator() override
Destructor.
G4Box * createSectorSupportBoxY(G4Transform3D &t)
Create Y side of sector support structure.
struct Solids m_Solids
Solids.
void createShieldDetailDLogicalVolume()
Create shield detail D logical volume.
void createShieldDetailALogicalVolume()
Create shield detail A logical volume.
void createShieldDetailCLogicalVolume()
Create shield detail C logical volume.
void createSegment(G4LogicalVolume *plane) const
Create segment (strips + plastic sheets).
void createMaterials()
Creation of materials.
G4Tubs * createSectorSupportOuterTube()
Create outer tube of sector support structure.
struct LogicalVolumes m_LogVol
Logical volumes.
TransformData * m_TransformData
Transformation data.
struct VolumeNumbers m_CurVol
Current volumes.
void createSectorSupportCorner4(G4LogicalVolume *sector) const
Create sector support corner 4.
struct Materials m_Materials
Materials.
void createShieldDetailBLogicalVolume()
Create shield detail B logical volume.
void createScintillator(int iStrip) const
Create scintillator.
G4LogicalVolume * createSection(G4LogicalVolume *topVolume) const
Create section.
void createSectorSupportCorner1LogicalVolume()
Create sector support corner 1 logical volume.
void createFromDB(const std::string &name, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
Creation of the detector geometry from database.
KLM::SensitiveDetector * m_Sensitive
Sensitive detector.
G4LogicalVolume * createSector(G4LogicalVolume *layer) const
Create sector.
void createPlaneSolid(int n)
Create plane solid.
static G4SubtractionSolid * cutSolidCorner(const char *name, G4VSolid *solid, G4Box *subtractionBox, const HepGeom::Transform3D &transf, bool largerAngles, double x1, double y1, double x2, double y2)
Cut corner of a solid.
void createSectorSupportCorner2LogicalVolume()
Create sector support corner 2 logical volume.
void newVolumes()
Create new volumes.
void createSubtractionBoxSolid()
Create subtraction box solid.
G4Box * createSectorSupportBoxTop(G4Transform3D &t)
Create box in the cutted corner of sector support structure.
void newSensitive()
Create new sensitive detectors.
void createSectorSupportCorner1(G4LogicalVolume *sector) const
Create sector support corner 1.
void createSectorSupportCorner3(G4LogicalVolume *sector) const
Create sector support corner 3.
void deleteSensitive()
Delete sensitive detectors.
G4LogicalVolume * createLayerLogicalVolume(const char *name) const
Create layer logical volume.
void createPayloads(const GearDir &content, const IntervalOfValidity &iov) override
Creation of payloads.
void createSectorCover(int iCover, G4LogicalVolume *sector) const
Create sector cover.
void createStripSegment(int iSegment) const
Create strip segment.
G4LogicalVolume * createPlane(G4LogicalVolume *sector) const
Create plane.
void createScintillatorLogicalVolume(int iStrip)
Create scintillator logical volume.
void createSegmentSupportLogicalVolume(int iPlane, int iSegmentSupport)
Create segment support logical volume.
void createShield(G4LogicalVolume *sector) const
Create shield.
void createPlasticSheet(int iSheetPlane, int iSheet) const
Create plastic sheet.
const EKLMElementNumbers * m_ElementNumbers
Element numbers.
void createSectorSupportCorner4LogicalVolume()
Create sector support corner 4 logical volume.
void createSegmentLogicalVolume(int iSegment)
Create segment logical volume (strips + plastic sheets).
void createSolids()
Create solids (or logical volumes which must be created only once).
void createPlasticSheetLogicalVolume(int iSegment)
Create plastic sheet logical volume.
void createSectorSupportLogicalVolume()
Create sector support logical volume.
void createLayerSolid()
Create layer solid.
G4Box * createSectorSupportBoxX(G4Transform3D &t)
Create X side of sector support structure.
void createSectorCoverLogicalVolume()
Create sector cover solid.
void createSectorSupportCorner2(G4LogicalVolume *sector) const
Create sector support corner 2.
void createStripGrooveLogicalVolume(int iStrip)
Create strip groove logical volume.
bool detectorLayer(int section, int layer) const
Check if a given layer is a detector layer.
void createStripGroove(int iStrip) const
Create strip groove.
void createSectorSupportCorner3LogicalVolume()
Create sector support corner 3 logical volume.
G4LogicalVolume * createLayer(G4LogicalVolume *section) const
Create layer.
static G4VSolid * unifySolids(G4VSolid **solids, HepGeom::Transform3D *transf, int nSolids, const std::string &name)
Unify a group of solids.
void createSectionSolid()
Create section solid.
G4LogicalVolume * createSectorLogicalVolume(const char *name) const
Create sector logical volume.
void createStrip(G4LogicalVolume *segment) const
Create strip.
void createSectorSolid()
Create sector solid.
void createStripLogicalVolume(int iStrip)
Create strip logical volume.
void deleteVolumes()
Delete volumes.
void create(const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
Creation of the detector geometry from Gearbox (XML).
void createSectorSupport(G4LogicalVolume *sector) const
Create sector support structure (main part without corners).
const GeometryData * m_GeoDat
Geometry data.
void createStripSegmentLogicalVolume(int iSegment)
Create strip segment logical volume.
void createSegmentSupport(int iSegmentSupport, G4LogicalVolume *plane) const
Create segment support.
G4Tubs * createSectorSupportInnerTube()
Create inner tube of sector support structure.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
@ c_Gearbox
Gearbox (XML).
Transformation data.
@ c_Displacement
Use displacement data (for geometry).
G4VSolid * getSolid()
Get solid.
GearDir is the basic class used for accessing the parameter store.
Definition GearDir.h:31
A class that describes the interval of experiments/runs for which an object in the database is valid.
KLM sensitive-detector class.
static G4Material * get(const std::string &name)
Find given material.
Definition Materials.h:63
double tan(double a)
tan for double
Definition beamHelpers.h:31
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition utilities.cc:108
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition utilities.cc:100
GeometryTypes
Flag indicating the type of geometry to be used.
Abstract base class for different kinds of events.
Very simple class to provide an easy way to register creators with the CreatorManager.