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