Belle II Software  release-08-01-10
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 
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 = new KLM::SensitiveDetector("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  createSectorSolid();
1428  createSectorCoverLogicalVolume();
1429  createSectorSupportLogicalVolume();
1434  createSectorSupportCorner1LogicalVolume();
1435  createSectorSupportCorner2LogicalVolume();
1436  createSectorSupportCorner3LogicalVolume();
1437  createSectorSupportCorner4LogicalVolume();
1438  /* Plane. */
1439  createSubtractionBoxSolid();
1440  for (i = 0; i < m_GeoDat->getNPlanes(); i++) {
1441  createPlaneSolid(i);
1442  /* Segment support. */
1443  for (j = 1; j <= m_GeoDat->getNSegments() + 1; j++)
1444  createSegmentSupportLogicalVolume(i + 1, j);
1445  }
1446  /* Strips. */
1447  n = m_GeoDat->getNStripsDifferentLength();
1448  for (i = 0; i < n; i++) {
1449  createStripLogicalVolume(i);
1450  createStripGrooveLogicalVolume(i);
1451  createScintillatorLogicalVolume(i);
1452  }
1453  /* Plastic sheet elements. */
1454  for (i = 0; i < m_GeoDat->getNSegments(); i++)
1455  createPlasticSheetLogicalVolume(i);
1456  /* Strip segments. */
1457  for (i = 0; i < m_GeoDat->getNSegments(); i++)
1458  createStripSegmentLogicalVolume(i);
1459  /* Segments. */
1460  for (i = 0; i < m_GeoDat->getNSegments(); i++)
1461  createSegmentLogicalVolume(i);
1462  /* Shield layer details. */
1463  createShieldDetailALogicalVolume();
1464  createShieldDetailBLogicalVolume();
1465  createShieldDetailCLogicalVolume();
1466  createShieldDetailDLogicalVolume();
1467 }
1468 
1469 /************************** CREATION OF VOLUMES ******************************/
1470 
1471 G4LogicalVolume*
1472 EKLM::GeoEKLMCreator::createSection(G4LogicalVolume* topVolume) const
1473 {
1474  G4LogicalVolume* logicSection = nullptr;
1475  const HepGeom::Transform3D* t;
1476  std::string sectionName = "Section_" + std::to_string(m_CurVol.section);
1477  try {
1478  logicSection = new G4LogicalVolume(m_Solids.section, m_Materials.iron,
1479  sectionName);
1480  } catch (std::bad_alloc& ba) {
1481  B2FATAL(MemErr);
1482  }
1483  geometry::setVisibility(*logicSection, true);
1484  geometry::setColor(*logicSection, "#ffffff22");
1485  t = m_TransformData->getSectionTransform(m_CurVol.section);
1486  try {
1487  new G4PVPlacement(*t, logicSection, sectionName, topVolume, false,
1488  m_CurVol.section, false);
1489  } catch (std::bad_alloc& ba) {
1490  B2FATAL(MemErr);
1491  }
1492  return logicSection;
1493 }
1494 
1495 G4LogicalVolume* EKLM::GeoEKLMCreator::
1496 createLayer(G4LogicalVolume* section) const
1497 {
1498  G4LogicalVolume* logicLayer;
1499  const HepGeom::Transform3D* t;
1500  std::string layerName = "Layer_" + std::to_string(m_CurVol.layer) +
1501  "_" + section->GetName();
1502  logicLayer = createLayerLogicalVolume(layerName.c_str());
1503  t = m_TransformData->getLayerTransform(m_CurVol.section, m_CurVol.layer);
1504  try {
1505  new G4PVPlacement(*t, logicLayer, logicLayer->GetName(), section, false,
1506  m_CurVol.layer, false);
1507  } catch (std::bad_alloc& ba) {
1508  B2FATAL(MemErr);
1509  }
1510  return logicLayer;
1511 }
1512 
1513 G4LogicalVolume* EKLM::GeoEKLMCreator::
1514 createSector(G4LogicalVolume* layer) const
1515 {
1516  G4LogicalVolume* logicSector;
1517  const HepGeom::Transform3D* t;
1518  std::string sectorName = "Sector_" + std::to_string(m_CurVol.sector) +
1519  "_" + layer->GetName();
1520  logicSector = createSectorLogicalVolume(sectorName.c_str());
1521  t = m_TransformData->getSectorTransform(m_CurVol.section, m_CurVol.layer,
1522  m_CurVol.sector);
1523  try {
1524  new G4PVPlacement(*t, logicSector, logicSector->GetName(), layer, false,
1525  m_CurVol.sector, false);
1526  } catch (std::bad_alloc& ba) {
1527  B2FATAL(MemErr);
1528  }
1529  return logicSector;
1530 }
1531 
1533 createSectorCover(int iCover, G4LogicalVolume* sector) const
1534 {
1535  double z;
1536  HepGeom::Transform3D t;
1537  G4LogicalVolume* lv = m_LogVol.cover;
1538  const EKLMGeometry::ElementPosition* sectorPos =
1539  m_GeoDat->getSectorPosition();
1540  const EKLMGeometry::ElementPosition* sectorSupportPos =
1541  m_GeoDat->getSectorSupportPosition();
1542  z = 0.25 * (sectorPos->getLength() + sectorSupportPos->getLength());
1543  if (iCover == 2)
1544  z = -z;
1545  t = HepGeom::Translate3D(0., 0., z);
1546  try {
1547  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1548  false, 1, false);
1549  } catch (std::bad_alloc& ba) {
1550  B2FATAL(MemErr);
1551  }
1552 }
1553 
1555 createSectorSupportCorner1(G4LogicalVolume* sector) const
1556 {
1557  HepGeom::Transform3D t;
1558  G4LogicalVolume* lv = m_LogVol.sectorsup.corn1;
1559  const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1560  m_GeoDat->getSectorSupportGeometry();
1561  t = HepGeom::Translate3D(0., 0., sectorSupportGeometry->getCorner1Z());
1562  try {
1563  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1564  false, 1, false);
1565  } catch (std::bad_alloc& ba) {
1566  B2FATAL(MemErr);
1567  }
1568 }
1569 
1571 createSectorSupportCorner2(G4LogicalVolume* sector) const
1572 {
1573  HepGeom::Transform3D t;
1574  G4LogicalVolume* lv = m_LogVol.sectorsup.corn2;
1575  const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1576  m_GeoDat->getSectorSupportGeometry();
1577  t = HepGeom::Translate3D(sectorSupportGeometry->getCorner2Inner().x(),
1578  sectorSupportGeometry->getCorner2Inner().y(),
1579  sectorSupportGeometry->getCorner2Z());
1580  try {
1581  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1582  false, 1, false);
1583  } catch (std::bad_alloc& ba) {
1584  B2FATAL(MemErr);
1585  }
1586 }
1587 
1589 createSectorSupportCorner3(G4LogicalVolume* sector) const
1590 {
1591  HepGeom::Transform3D t;
1592  G4LogicalVolume* lv = m_LogVol.sectorsup.corn3;
1593  const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1594  m_GeoDat->getSectorSupportGeometry();
1595  t = HepGeom::Translate3D(sectorSupportGeometry->getCorner3Prism().x(),
1596  sectorSupportGeometry->getCorner3Prism().y(),
1597  sectorSupportGeometry->getCorner3Z());
1598  try {
1599  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1600  false, 1, false);
1601  } catch (std::bad_alloc& ba) {
1602  B2FATAL(MemErr);
1603  }
1604 }
1605 
1607 createSectorSupportCorner4(G4LogicalVolume* sector) const
1608 {
1609  HepGeom::Transform3D t;
1610  G4LogicalVolume* lv = m_LogVol.sectorsup.corn4;
1611  const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
1612  m_GeoDat->getSectorSupportGeometry();
1613  t = HepGeom::Translate3D(sectorSupportGeometry->getCorner4Prism().x(),
1614  sectorSupportGeometry->getCorner4Prism().y(),
1615  sectorSupportGeometry->getCorner4Z());
1616  try {
1617  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1618  false, 1, false);
1619  } catch (std::bad_alloc& ba) {
1620  B2FATAL(MemErr);
1621  }
1622 }
1623 
1625 createSectorSupport(G4LogicalVolume* sector) const
1626 {
1627  HepGeom::Transform3D t;
1628  G4LogicalVolume* lv = m_LogVol.sectorsup.supp;
1629  const EKLMGeometry::ElementPosition* sectorSupportPos =
1630  m_GeoDat->getSectorSupportPosition();
1631  t = HepGeom::Translate3D(0., 0., sectorSupportPos->getZ());
1632  try {
1633  new G4PVPlacement(t, lv, lv->GetName() + "_" + sector->GetName(), sector,
1634  false, 1, false);
1635  } catch (std::bad_alloc& ba) {
1636  B2FATAL(MemErr);
1637  }
1638 }
1639 
1640 G4LogicalVolume*
1641 EKLM::GeoEKLMCreator::createPlane(G4LogicalVolume* sector) const
1642 {
1643  G4LogicalVolume* logicPlane = nullptr;
1644  const HepGeom::Transform3D* t;
1645  std::string planeName =
1646  "Plane_" + std::to_string(m_CurVol.plane) + "_" + sector->GetName();
1647  try {
1648  logicPlane = new G4LogicalVolume(m_Solids.plane[m_CurVol.plane - 1],
1649  m_Materials.air, planeName);
1650  } catch (std::bad_alloc& ba) {
1651  B2FATAL(MemErr);
1652  }
1653  geometry::setVisibility(*logicPlane, false);
1654  t = m_TransformData->getPlaneTransform(m_CurVol.section, m_CurVol.layer,
1655  m_CurVol.sector, m_CurVol.plane);
1656  try {
1657  new G4PVPlacement(*t, logicPlane, planeName, sector, false,
1658  m_CurVol.plane, false);
1659  } catch (std::bad_alloc& ba) {
1660  B2FATAL(MemErr);
1661  }
1662  return logicPlane;
1663 }
1664 
1666 createSegmentSupport(int iSegmentSupport, G4LogicalVolume* plane) const
1667 {
1668  HepGeom::Transform3D t;
1669  G4LogicalVolume* lv =
1670  m_LogVol.segmentsup[m_CurVol.plane - 1][iSegmentSupport - 1];
1671  const EKLMGeometry::SegmentSupportPosition* segmentSupportPos =
1672  m_GeoDat->getSegmentSupportPosition(m_CurVol.plane, iSegmentSupport);
1673  t = (*m_TransformData->getPlaneDisplacement(m_CurVol.section, m_CurVol.layer,
1674  m_CurVol.sector, m_CurVol.plane)) *
1675  HepGeom::Translate3D(
1676  0.5 * (segmentSupportPos->getDeltaLLeft() -
1677  segmentSupportPos->getDeltaLRight()) +
1678  segmentSupportPos->getX(), segmentSupportPos->getY(),
1679  segmentSupportPos->getZ()) *
1680  HepGeom::RotateX3D(180.0 * CLHEP::deg);
1681  try {
1682  new G4PVPlacement(t, lv, lv->GetName() + "_" + plane->GetName(), plane,
1683  false, 1, false);
1684  } catch (std::bad_alloc& ba) {
1685  B2FATAL(MemErr);
1686  }
1687 }
1688 
1689 void EKLM::GeoEKLMCreator::createPlasticSheet(int iSheetPlane, int iSheet) const
1690 {
1691  double z;
1692  HepGeom::Transform3D t;
1693  const EKLMGeometry::PlasticSheetGeometry* plasticSheetGeometry =
1694  m_GeoDat->getPlasticSheetGeometry();
1695  const EKLMGeometry::StripGeometry* stripGeometry =
1696  m_GeoDat->getStripGeometry();
1697  std::string sheetName =
1698  "Sheet_" + std::to_string(iSheet) +
1699  "_SheetPlane_" + std::to_string(iSheetPlane);
1700  z = 0.5 * (stripGeometry->getThickness() + plasticSheetGeometry->getWidth());
1701  if (iSheetPlane == 2)
1702  z = -z;
1703  t = HepGeom::Translate3D(0, 0, z);
1704  try {
1705  new G4PVPlacement(t, m_LogVol.psheet[iSheet - 1], sheetName,
1706  m_LogVol.segment[iSheet - 1], false, (iSheetPlane - 1) *
1707  m_GeoDat->getNSegments() + iSheet, false);
1708  } catch (std::bad_alloc& ba) {
1709  B2FATAL(MemErr);
1710  }
1711 }
1712 
1714 {
1715  HepGeom::Transform3D t;
1716  std::string segmentName = "StripSegment_" + std::to_string(iSegment);
1717  t = HepGeom::Translate3D(0, 0, 0);
1718  try {
1719  new G4PVPlacement(t, m_LogVol.stripSegment[iSegment - 1], segmentName,
1720  m_LogVol.segment[iSegment - 1], false, iSegment, false);
1721  } catch (std::bad_alloc& ba) {
1722  B2FATAL(MemErr);
1723  }
1724 }
1725 
1726 void EKLM::GeoEKLMCreator::createSegment(G4LogicalVolume* plane) const
1727 {
1728  HepGeom::Transform3D t;
1729  std::string segmentName =
1730  "Segment_" + std::to_string(m_CurVol.segment) + "_" + plane->GetName();
1731  t = (*m_TransformData->getPlaneDisplacement(m_CurVol.section, m_CurVol.layer,
1732  m_CurVol.sector, m_CurVol.plane)) *
1733  (*m_TransformData->getSegmentTransform(
1734  m_CurVol.section, m_CurVol.layer, m_CurVol.sector, m_CurVol.plane,
1735  m_CurVol.segment));
1736  try {
1737  new G4PVPlacement(t, m_LogVol.segment[m_CurVol.segment - 1], segmentName,
1738  plane, false, m_CurVol.segment, false);
1739  } catch (std::bad_alloc& ba) {
1740  B2FATAL(MemErr);
1741  }
1742 }
1743 
1744 void EKLM::GeoEKLMCreator::createStrip(G4LogicalVolume* segment) const
1745 {
1746  int n;
1747  HepGeom::Transform3D t, t2;
1748  G4LogicalVolume* lv;
1749  n = m_GeoDat->getStripLengthIndex(m_CurVol.strip - 1);
1750  m_GeoDat->getStripTransform(&t, m_CurVol.strip - 1);
1751  t2 = t * HepGeom::RotateX3D(180.0 * CLHEP::deg);
1752  lv = m_LogVol.strip[n];
1753  try {
1754  new G4PVPlacement(t2, lv, lv->GetName(), segment, false, m_CurVol.strip,
1755  false);
1756  } catch (std::bad_alloc& ba) {
1757  B2FATAL(MemErr);
1758  }
1759 }
1760 
1762 {
1763  HepGeom::Transform3D t;
1764  G4LogicalVolume* lv;
1765  G4LogicalVolume* lvm;
1766  const EKLMGeometry::StripGeometry* stripGeometry =
1767  m_GeoDat->getStripGeometry();
1768  t = HepGeom::Translate3D(0., 0., 0.5 * (stripGeometry->getThickness() -
1769  stripGeometry->getGrooveDepth()));
1770  lvm = m_LogVol.strip[iStrip];
1771  lv = m_LogVol.groove[iStrip];
1772  try {
1773  new G4PVPlacement(t, lv, lv->GetName(), lvm, false, 1, false);
1774  } catch (std::bad_alloc& ba) {
1775  B2FATAL(MemErr);
1776  }
1777 }
1778 
1780 {
1781  HepGeom::Transform3D t;
1782  G4LogicalVolume* lv;
1783  G4LogicalVolume* lvm;
1784  t = HepGeom::Translate3D(0., 0., 0.);
1785  lvm = m_LogVol.strip[iStrip];
1786  lv = m_LogVol.scint[iStrip];
1787  try {
1788  new G4PVPlacement(t, lv, lv->GetName(), lvm, false, 1, false);
1789  } catch (std::bad_alloc& ba) {
1790  B2FATAL(MemErr);
1791  }
1792 }
1793 
1794 void EKLM::GeoEKLMCreator::createShield(G4LogicalVolume* sector) const
1795 {
1796  HepGeom::Transform3D ta, tb, tc, td, te;
1797  G4LogicalVolume* lv;
1798  double lx, ly;
1799  const double asqrt2 = 1.0 / sqrt(2.0);
1800  const EKLMGeometry::ShieldGeometry* shieldGeometry =
1801  m_GeoDat->getShieldGeometry();
1802  lx = shieldGeometry->getDetailB()->getLengthX() / 2;
1803  ly = shieldGeometry->getDetailB()->getLengthY() / 2;
1804  ta = HepGeom::Translate3D(shieldGeometry->getDetailACenter()->getX(),
1805  shieldGeometry->getDetailACenter()->getY(), 0) *
1806  HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1807  tb = HepGeom::Translate3D(shieldGeometry->getDetailBCenter()->getX(),
1808  shieldGeometry->getDetailBCenter()->getY(), 0) *
1809  HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1810  tc = HepGeom::Translate3D(shieldGeometry->getDetailCCenter()->getX(),
1811  shieldGeometry->getDetailCCenter()->getY(), 0) *
1812  HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1813  HepGeom::RotateY3D(180.0 * CLHEP::deg);
1814  td = HepGeom::Translate3D(
1815  shieldGeometry->getDetailBCenter()->getX() + asqrt2 * (-lx - ly),
1816  shieldGeometry->getDetailBCenter()->getY() + asqrt2 * (lx - ly), 0) *
1817  HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1818  HepGeom::RotateX3D(180.0 * CLHEP::deg);
1819  te = HepGeom::Translate3D(
1820  shieldGeometry->getDetailBCenter()->getX() + asqrt2 * (lx - ly),
1821  shieldGeometry->getDetailBCenter()->getY() + asqrt2 * (-lx - ly), 0) *
1822  HepGeom::RotateZ3D(135.0 * CLHEP::deg);
1823  lv = m_LogVol.shield.detailA;
1824  try {
1825  new G4PVPlacement(ta, lv, lv->GetName(), sector, false, 1, false);
1826  } catch (std::bad_alloc& ba) {
1827  B2FATAL(MemErr);
1828  }
1829  lv = m_LogVol.shield.detailB;
1830  try {
1831  new G4PVPlacement(tb, lv, lv->GetName(), sector, false, 1, false);
1832  } catch (std::bad_alloc& ba) {
1833  B2FATAL(MemErr);
1834  }
1835  lv = m_LogVol.shield.detailC;
1836  try {
1837  new G4PVPlacement(tc, lv, lv->GetName(), sector, false, 1, false);
1838  } catch (std::bad_alloc& ba) {
1839  B2FATAL(MemErr);
1840  }
1841  lv = m_LogVol.shield.detailD;
1842  try {
1843  new G4PVPlacement(td, lv, lv->GetName(), sector, false, 1, false);
1844  } catch (std::bad_alloc& ba) {
1845  B2FATAL(MemErr);
1846  }
1847  try {
1848  new G4PVPlacement(te, lv, "ShieldDetailE", sector, false, 1, false);
1849  } catch (std::bad_alloc& ba) {
1850  B2FATAL(MemErr);
1851  }
1852 }
1853 
1854 bool EKLM::GeoEKLMCreator::detectorLayer(int section, int layer) const
1855 {
1856  return ((section == 1 && layer <= m_GeoDat->getNDetectorLayers(1)) ||
1857  (section == 2 && layer <= m_GeoDat->getNDetectorLayers(2)));
1858 }
1859 
1860 void EKLM::GeoEKLMCreator::create(G4LogicalVolume& topVolume)
1861 {
1862  /* cppcheck-suppress variableScope */
1863  int i, j, imin, imax;
1864  /* cppcheck-suppress variableScope */
1865  G4LogicalVolume* section, *layer, *sector, *plane;
1866  createMaterials();
1867  createSolids();
1868  /* Create physical volumes which are used only once. */
1869  for (i = 0; i < m_GeoDat->getNStripsDifferentLength(); i++) {
1870  createStripGroove(i);
1871  createScintillator(i);
1872  }
1873  for (i = 0; i < m_GeoDat->getNSegments(); i++) {
1874  imin = i * m_ElementNumbers->getNStripsSegment();
1875  imax = (i + 1) * m_ElementNumbers->getNStripsSegment();
1876  for (m_CurVol.strip = imin + 1; m_CurVol.strip <= imax; m_CurVol.strip++)
1877  createStrip(m_LogVol.stripSegment[i]);
1878  }
1879  for (i = 1; i <= m_GeoDat->getNSegments(); i++) {
1880  for (j = 1; j <= 2; j++)
1881  createPlasticSheet(j, i);
1882  createStripSegment(i);
1883  }
1884  /* Create other volumes. */
1885  /* Set up region for production cuts. */
1886  G4Region* aRegion = new G4Region("EKLMEnvelope");
1887  for (m_CurVol.section = 1; m_CurVol.section <= m_GeoDat->getNSections();
1888  m_CurVol.section++) {
1889  section = createSection(&topVolume);
1890  /* Assign same region to each section. */
1891  section->SetRegion(aRegion);
1892  aRegion->AddRootLogicalVolume(section);
1893  for (m_CurVol.layer = 1; m_CurVol.layer <= m_GeoDat->getNLayers();
1894  m_CurVol.layer++) {
1895  layer = createLayer(section);
1896  for (m_CurVol.sector = 1; m_CurVol.sector <= m_GeoDat->getNSectors();
1897  m_CurVol.sector++) {
1898  sector = createSector(layer);
1899  createSectorSupport(sector);
1900  createSectorSupportCorner1(sector);
1901  createSectorSupportCorner2(sector);
1902  createSectorSupportCorner3(sector);
1903  createSectorSupportCorner4(sector);
1904  for (i = 1; i <= 2; i++)
1905  createSectorCover(i, sector);
1906  if (detectorLayer(m_CurVol.section, m_CurVol.layer)) {
1907  /* Detector layer. */
1908  for (m_CurVol.plane = 1; m_CurVol.plane <= m_GeoDat->getNPlanes();
1909  m_CurVol.plane++) {
1910  plane = createPlane(sector);
1911  for (i = 1; i <= m_GeoDat->getNSegments() + 1; i++)
1912  createSegmentSupport(i, plane);
1913  for (m_CurVol.segment = 1;
1914  m_CurVol.segment <= m_GeoDat->getNSegments();
1915  m_CurVol.segment++)
1916  createSegment(plane);
1917  }
1918  } else {
1919  /* Shield layer. */
1920  createShield(sector);
1921  }
1922  }
1923  }
1924  }
1925 }
1926 
1928  G4LogicalVolume& topVolume,
1930 {
1931  (void)content;
1932  (void)type;
1933  m_GeoDat = &(EKLM::GeometryData::Instance(GeometryData::c_Gearbox, &content));
1934  try {
1935  m_TransformData =
1937  } catch (std::bad_alloc& ba) {
1938  B2FATAL(MemErr);
1939  }
1940  newVolumes();
1941  newSensitive();
1942  create(topVolume);
1943 }
1944 
1945 void EKLM::GeoEKLMCreator::createFromDB(const std::string& name,
1946  G4LogicalVolume& topVolume,
1948 {
1949  (void)name;
1950  (void)type;
1952  try {
1953  m_TransformData =
1955  } catch (std::bad_alloc& ba) {
1956  B2FATAL(MemErr);
1957  }
1958  newVolumes();
1959  newSensitive();
1960  create(topVolume);
1961 }
1962 
1964  const IntervalOfValidity& iov)
1965 {
1966  (void)content;
1967  m_GeoDat = &(EKLM::GeometryData::Instance(GeometryData::c_Gearbox, &content));
1968  try {
1969  m_TransformData =
1971  } catch (std::bad_alloc& ba) {
1972  B2FATAL(MemErr);
1973  }
1974  m_GeoDat->saveToDatabase(iov);
1975 }
1976 
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.
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.
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.
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.
KLM sensitive-detector class.
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
double tan(double a)
tan for double
Definition: beamHelpers.h:31
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 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).