Belle II Software  release-08-01-10
GeoTOPCreator.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <top/geometry/GeoTOPCreator.h>
10 #include <top/geometry/TOPGeometryPar.h>
11 
12 #include <geometry/Materials.h>
13 #include <geometry/CreatorFactory.h>
14 #include <geometry/utilities.h>
15 #include <framework/gearbox/GearDir.h>
16 #include <framework/gearbox/Unit.h>
17 #include <framework/logging/Logger.h>
18 #include <framework/database/Database.h>
19 #include <framework/database/IntervalOfValidity.h>
20 #include <framework/database/DBImportObjPtr.h>
21 #include <framework/database/DBObjPtr.h>
22 #include <top/simulation/SensitivePMT.h>
23 #include <top/simulation/SensitiveBar.h>
24 #include <simulation/background/BkgSensitiveDetector.h>
25 #include <simulation/kernel/RunManager.h>
26 
27 #include <cmath>
28 
29 #include <G4LogicalVolume.hh>
30 #include <G4PVPlacement.hh>
31 #include <G4AssemblyVolume.hh>
32 #include <G4LogicalSkinSurface.hh>
33 #include <G4OpticalSurface.hh>
34 
35 #include <G4Box.hh>
36 #include <G4UserLimits.hh>
37 #include <G4Material.hh>
38 #include <G4ExtrudedSolid.hh>
39 #include <G4UnionSolid.hh>
40 #include <G4Sphere.hh>
41 #include <G4IntersectionSolid.hh>
42 #include <G4SubtractionSolid.hh>
43 #include <G4Region.hh>
44 #include <G4Colour.hh>
45 #include <G4TwoVector.hh>
46 #include <G4ThreeVector.hh>
47 
48 #include <sstream>
49 
50 using namespace std;
51 
52 namespace Belle2 {
58  using namespace geometry;
59 
60  namespace TOP {
61 
63  geometry::CreatorFactory<GeoTOPCreator> GeoTOPFactory("TOPCreator");
64 
65 
66  GeoTOPCreator::GeoTOPCreator()
67  {}
68 
69 
70  GeoTOPCreator::~GeoTOPCreator()
71  {
72  if (m_sensitivePMT) delete m_sensitivePMT;
73  if (m_sensitiveBar) delete m_sensitiveBar;
74  if (m_sensitivePCB1) delete m_sensitivePCB1;
75  if (m_sensitivePCB2) delete m_sensitivePCB2;
76  G4LogicalSkinSurface::CleanSurfaceTable();
77  }
78 
79 
80  void GeoTOPCreator::create(const GearDir& content, G4LogicalVolume& topVolume,
82  {
83 
84  m_isBeamBkgStudy = content.getInt("BeamBackgroundStudy");
85 
86  m_topgp->Initialize(content);
87  if (!m_topgp->isValid()) {
88  B2ERROR("TOP: geometry or mappers not valid (gearbox) - geometry not created");
89  return;
90  }
91 
92  const auto* geo = m_topgp->getGeometry();
93  createGeometry(*geo, topVolume, type);
94 
95  }
96 
97 
98  void GeoTOPCreator::createPayloads(const GearDir& content,
99  const IntervalOfValidity& iov)
100  {
101  m_topgp->Initialize(content);
102  if (!m_topgp->isValid()) {
103  B2ERROR("TOP: geometry or mappers not valid (gearbox) - no payloads imported");
104  return;
105  }
106 
107  DBImportObjPtr<TOPGeometry> importObj;
108  const auto* geo = m_topgp->getGeometry();
109  importObj.construct(*geo);
110  importObj.import(iov);
111 
112  m_topgp->getChannelMapper().importPayload(iov);
113  m_topgp->getFrontEndMapper().importPayload(iov);
114 
115  B2RESULT("TOP: geometry and mappers imported to database");
116 
117  }
118 
119 
120  void GeoTOPCreator::createFromDB(const std::string& name, G4LogicalVolume& topVolume,
122  {
123 
124  m_topgp->Initialize();
125  if (!m_topgp->isValid()) {
126  B2ERROR("Cannot create Geometry from Database: no configuration found for "
127  << name);
128  return;
129  }
130 
131  const auto* geo = m_topgp->getGeometry();
132  createGeometry(*geo, topVolume, type);
133 
134  }
135 
136 
137  void GeoTOPCreator::createGeometry(const TOPGeometry& geo,
138  G4LogicalVolume& topVolume,
140  {
141  m_sensitivePMT = new SensitivePMT();
142  m_sensitiveBar = new SensitiveBar();
143 
144  m_sensitivePMT->setModuleReplicaDepth(4);
145  m_sensitiveBar->setReplicaDepth(1);
146 
147  geo.useGeantUnits();
148 
149  double backwardLength = geo.getQBB().getPrismEnclosure().getLength();
150  double prismPosition = geo.getQBB().getPrismPosition();
151 
152  G4Region* aRegion = new G4Region("TOPEnvelope");
153 
154  for (const auto& geoModule : geo.getModules()) {
155  int moduleID = geoModule.getModuleID();
156  double barLength = geoModule.getBarLength();
157 
158  // go to local (bar) frame
159 
160  G4Transform3D T1 =
161  G4TranslateZ3D(backwardLength / 2 - prismPosition - barLength / 2);
162 
163  // displaced geometry
164 
165  const auto& displacement = geoModule.getModuleDisplacement();
166  G4Transform3D dRx = G4RotateX3D(displacement.getAlpha());
167  G4Transform3D dRy = G4RotateY3D(displacement.getBeta());
168  G4Transform3D dRz = G4RotateZ3D(displacement.getGamma());
169  G4Transform3D dtr = G4Translate3D(displacement.getX(),
170  displacement.getY(),
171  displacement.getZ());
172  G4Transform3D D = dtr * dRz * dRy * dRx;
173 
174  // position the module
175 
176  double radius = geoModule.getRadius();
177  double backwardZ = geoModule.getBackwardZ();
178  G4Transform3D tr = G4Translate3D(0, radius, barLength / 2 + backwardZ);
179  double phi = geoModule.getPhi() - M_PI / 2;
180  G4Transform3D Rz = G4RotateZ3D(phi);
181  G4Transform3D T = Rz * tr * D * T1;
182  auto* module = createModule(geo, moduleID);
183  std::string name = geoModule.getName();
184 
185  // Set up region for production cuts
186  module->SetRegion(aRegion);
187  aRegion->AddRootLogicalVolume(module);
188 
189  new G4PVPlacement(T, module, name, &topVolume, false, moduleID);
190  }
191 
192  if (m_numDecoupledPMTs > 0) B2WARNING("GeoTOPCreator, " << m_numDecoupledPMTs
193  << " PMT's are optically decoupled");
194  if (m_numBrokenGlues > 0) B2WARNING("GeoTOPCreator, " << m_numBrokenGlues
195  << " broken glues");
196  if (m_numPeelOffRegions > 0) B2WARNING("GeoTOPCreator, " << m_numPeelOffRegions
197  << " peel-off cookie regions");
198  }
199 
200 
201  G4LogicalVolume* GeoTOPCreator::createModule(const TOPGeometry& geo, int moduleID)
202  {
203  // note: z = 0 is at center of backward envelope
204 
205  G4ThreeVector move;
206  G4RotationMatrix rot;
207 
208  // create module envelope volume
209 
210  const auto& geoQBB = geo.getQBB();
211  auto* module = createModuleEnvelope(geoQBB, moduleID);
212 
213  // add quartz optics together with PMT array
214 
215  const auto& geoModule = geo.getModule(moduleID);
216  auto* optics = assembleOptics(geoModule);
217 
218  move.setZ(geoQBB.getPrismPosition() - geoQBB.getPrismEnclosure().getLength() / 2);
219  optics->MakeImprint(module, move, &rot);
220 
221  // add front-end electronics
222 
223  if (!m_frontEnd) {
224  m_frontEnd = assembleFrontEnd(geo.getFrontEnd(), geo.getNumBoardStacks());
225  }
226  double Lprism = geoModule.getPrism().getFullLength();
227  double Larray = geoModule.getPMTArray().getSizeZ();
228  move.setZ(move.z() - Lprism - Larray);
229  m_frontEnd->MakeImprint(module, move, &rot);
230 
231  // add QBB
232 
233  if (!m_qbb) m_qbb = assembleQBB(geoQBB);
234  move.setZ(0);
235  m_qbb->MakeImprint(module, move, &rot);
236 
237  return module;
238  }
239 
240 
241  G4LogicalVolume* GeoTOPCreator::createModuleEnvelope(const TOPGeoQBB& geo,
242  int moduleID)
243  {
244  // note: z = 0 is at center of backward envelope
245 
246  if (!m_moduleEnvelope) {
247  double backwardLength = geo.getPrismEnclosure().getLength();
248  double forwardLength = geo.getLength() - backwardLength;
249  std::vector<G4TwoVector> polygon;
250  for (auto& point : geo.getBackwardContour()) {
251  polygon.push_back(G4TwoVector(point.first, point.second));
252  }
253  auto* backward = new G4ExtrudedSolid("backwardEnvelope",
254  polygon, backwardLength / 2,
255  G4TwoVector(), 1, G4TwoVector(), 1);
256  polygon.clear();
257  for (auto& point : geo.getForwardContour()) {
258  polygon.push_back(G4TwoVector(point.first, point.second));
259  }
260  auto* forward = new G4ExtrudedSolid("forwardEnvelope",
261  polygon, forwardLength / 2,
262  G4TwoVector(), 1, G4TwoVector(), 1);
263 
264  G4Transform3D move = G4TranslateZ3D((backwardLength + forwardLength) / 2);
265  m_moduleEnvelope = new G4UnionSolid("moduleEnvelope", backward, forward, move);
266  }
267 
268  G4Material* material = Materials::get(geo.getMaterial());
269  if (!material) B2FATAL("Material '" << geo.getMaterial() << "' not found");
270 
271  std::string name = addNumber("TOPEnvelopeModule", moduleID);
272  return new G4LogicalVolume(m_moduleEnvelope, material, name);
273 
274  }
275 
276 
277  G4AssemblyVolume* GeoTOPCreator::assembleFrontEnd(const TOPGeoFrontEnd& geo, int N)
278  {
279  auto* frontEnd = new G4AssemblyVolume();
280  Simulation::RunManager::Instance().addAssemblyVolume(frontEnd);
281 
282  G4ThreeVector move;
283 
284  // front board
285 
286  double Z = -geo.getFrontBoardGap();
287  double length = geo.getFrontBoardThickness();
288  auto* frontBoard = createBox("TOPFrontBoard",
289  geo.getFrontBoardWidth(),
290  geo.getFrontBoardHeight(),
291  length,
292  geo.getFrontBoardMaterial());
293  if (m_isBeamBkgStudy) {
294  if (!m_sensitivePCB1) m_sensitivePCB1 = new BkgSensitiveDetector("TOP", 1);
295  frontBoard->SetSensitiveDetector(m_sensitivePCB1);
296  }
297  move.setZ(Z - length / 2);
298  move.setY(geo.getFrontBoardY());
299  frontEnd->AddPlacedVolume(frontBoard, move, 0);
300  Z -= length;
301 
302  // HV board
303 
304  length = geo.getHVBoardLength();
305  auto* HVBoard = createBox("TOPHVBoard",
306  geo.getHVBoardWidth(),
307  geo.getHVBoardThickness(),
308  length,
309  geo.getHVBoardMaterial());
310  if (m_isBeamBkgStudy) {
311  if (!m_sensitivePCB2) m_sensitivePCB2 = new BkgSensitiveDetector("TOP", 2);
312  HVBoard->SetSensitiveDetector(m_sensitivePCB2);
313  }
314  move.setZ(Z - geo.getHVBoardGap() - length / 2);
315  move.setY(geo.getHVBoardY());
316  frontEnd->AddPlacedVolume(HVBoard, move, 0);
317 
318  // board stack
319 
320  length = geo.getBoardStackLength();
321  move.setZ(Z - geo.getBoardStackGap() - length / 2);
322  move.setY(geo.getBoardStackY());
323  auto* boardStack = createBoardStack(geo, N);
324  frontEnd->AddPlacedVolume(boardStack, move, 0);
325 
326  return frontEnd;
327  }
328 
329 
330  G4LogicalVolume* GeoTOPCreator::createBoardStack(const TOPGeoFrontEnd& geo, int N)
331  {
332  double width = geo.getBoardStackWidth();
333  double fullWidth = width * N;
334  std::string name = "TOPBoardStack";
335  auto* boardStack = createBox(name,
336  fullWidth,
337  geo.getBoardStackHeight(),
338  geo.getBoardStackLength(),
339  geo.getBoardStackMaterial());
340 
341  double spacerWidth = geo.getSpacerWidth();
342  std::string name1 = name + "Spacer";
343  auto* spacer = createBox(name1,
344  spacerWidth,
345  geo.getBoardStackHeight(),
346  geo.getBoardStackLength(),
347  geo.getSpacerMaterial());
348 
349  std::string name2 = name + "TwoSpacers";
350  auto* twoSpacers = createBox(name2,
351  spacerWidth * 2,
352  geo.getBoardStackHeight(),
353  geo.getBoardStackLength(),
354  geo.getSpacerMaterial());
355 
356  G4Transform3D move;
357  move = G4TranslateX3D(-(fullWidth - spacerWidth) / 2);
358  new G4PVPlacement(move, spacer, name1, boardStack, false, 1);
359  move = G4TranslateX3D((fullWidth - spacerWidth) / 2);
360  new G4PVPlacement(move, spacer, name1, boardStack, false, 2);
361 
362  int n = N - 1;
363  for (int i = 0; i < n; i++) {
364  move = G4TranslateX3D(width * (2 * i - n + 1) / 2.0);
365  new G4PVPlacement(move, twoSpacers, name2, boardStack, false, i + 1);
366  }
367 
368  return boardStack;
369  }
370 
371 
372  G4AssemblyVolume* GeoTOPCreator::assembleQBB(const TOPGeoQBB& geo)
373  {
374  auto* qbb = new G4AssemblyVolume();
375  Simulation::RunManager::Instance().addAssemblyVolume(qbb);
376 
377  double Zback = -geo.getPrismEnclosure().getLength() / 2;
378  double Zfront = Zback + geo.getLength() - geo.getForwardEndPlate().getThickness();
379 
380  G4ThreeVector move;
381 
382  // outer panel
383 
384  auto* outerPanel = createHoneycombPanel(geo, c_Outer);
385  move.setZ(Zfront - geo.getOuterPanel().getLength() / 2);
386  qbb->AddPlacedVolume(outerPanel, move, 0);
387 
388  // inner panel
389 
390  auto* innerPanel = createHoneycombPanel(geo, c_Inner);
391  move.setZ(Zfront - geo.getInnerPanel().getLength() / 2);
392  qbb->AddPlacedVolume(innerPanel, move, 0);
393 
394  // forward end plate
395 
396  double length = geo.getForwardEndPlate().getThickness();
397  auto* forwardEndPlate = createBox(geo.getForwardEndPlate().getName(),
398  geo.getWidth(),
400  length,
402  move.setZ(Zfront + length / 2);
403  qbb->AddPlacedVolume(forwardEndPlate, move, 0);
404 
405  // prism enclosure box
406 
407  std::string name = geo.getPrismEnclosure().getName();
408  double Z = Zback;
409  length = geo.getPrismEnclosure().getBackThickness();
410  auto* backPlate = createExtrudedSolid(name + "BackPlate",
411  geo.getBackPlateContour(),
412  length,
414  move.setZ(Z + length / 2);
415  qbb->AddPlacedVolume(backPlate, move, 0);
416  Z += length;
417 
418  length = geo.getPrismEnclosure().getBodyLength();
419  auto* prismEnclosure = createExtrudedSolid(name + "Body",
421  length,
423  move.setZ(Z + length / 2);
424  qbb->AddPlacedVolume(prismEnclosure, move, 0);
425  Z += length;
426 
427  length = geo.getPrismEnclosure().getFrontThickness();
428  auto* frontPlate = createExtrudedSolid(name + "FrontPlate",
429  geo.getFrontPlateContour(),
430  length,
432  move.setZ(Z + length / 2);
433  qbb->AddPlacedVolume(frontPlate, move, 0);
434  Z += length;
435 
436  length = Zfront - Z - geo.getInnerPanel().getLength();
437  if (length > 0) {
438  double height = geo.getPrismEnclosure().getExtensionThickness();
439  auto* extPlate = createBox(name + "ExtensionPlate",
440  geo.getPanelWidth(),
441  height,
442  length,
444 
445  G4ThreeVector movePlate;
446  movePlate.setZ(Z + length / 2);
447  movePlate.setY((height - geo.getSideRails().getHeight()) / 2);
448  qbb->AddPlacedVolume(extPlate, movePlate, 0);
449  }
450 
451  // side rails
452 
453  auto* leftRail = createSideRail(geo, c_Left);
454  move.setZ(Zfront - geo.getSideRailsLength() / 2);
455  move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() -
456  geo.getSideRails().getHeight() / 2);
457  move.setX(-(geo.getWidth() - geo.getSideRails().getThickness()) / 2);
458  qbb->AddPlacedVolume(leftRail, move, 0);
459 
460  auto* rightRail = createSideRail(geo, c_Right);
461  move.setX((geo.getWidth() - geo.getSideRails().getThickness()) / 2);
462  qbb->AddPlacedVolume(rightRail, move, 0);
463 
464  // cold plate
465 
466  length = geo.getLength() - geo.getPrismEnclosure().getBackThickness() -
468  auto* coldPlateBase = createBox(geo.getColdPlate().getName() + "Base",
469  geo.getPanelWidth(),
471  length,
472  geo.getColdPlate().getBaseMaterial());
473  move.setZ(Zback + geo.getPrismEnclosure().getBackThickness() + length / 2);
474  move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() -
475  geo.getColdPlate().getBaseThickness() / 2);
476  move.setX(0);
477  qbb->AddPlacedVolume(coldPlateBase, move, 0);
478 
479  auto* coldPlateCool = createBox(geo.getColdPlate().getName() + "Cooler",
480  geo.getColdPlate().getCoolWidth(),
482  length,
483  geo.getColdPlate().getCoolMaterial());
484  move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() +
485  geo.getColdPlate().getCoolThickness() / 2);
486  qbb->AddPlacedVolume(coldPlateCool, move, 0);
487 
488  return qbb;
489  }
490 
491 
492  G4LogicalVolume* GeoTOPCreator::createHoneycombPanel(const TOPGeoQBB& geo,
493  EPanelType type)
494  {
495  G4Transform3D move;
496 
497  TOPGeoHoneycombPanel geoPanel;
498  Polygon contour;
499  double sideEdgeHeight = 0;
500  double sideEdgeY = 0;
501 
502  if (type == c_Inner) {
503  geoPanel = geo.getInnerPanel();
504  contour = geo.getInnerPanelContour();
505  sideEdgeHeight = geoPanel.getMaxThickness();
506  sideEdgeY = geoPanel.getY() - sideEdgeHeight / 2;
507  } else {
508  geoPanel = geo.getOuterPanel();
509  contour = geo.getOuterPanelContour();
510  sideEdgeHeight = geoPanel.getMinThickness();
511  sideEdgeY = geoPanel.getY() + sideEdgeHeight / 2;
512  }
513 
514  // honeycomb panel
515 
516  auto* panel = createExtrudedSolid(geoPanel.getName(),
517  contour,
518  geoPanel.getLength(),
519  geoPanel.getMaterial());
520 
521  // reinforced faces
522 
523  std::string faceEdgeName = geoPanel.getName() + "ReinforcedFace";
524  auto* faceEdge = createExtrudedSolid(faceEdgeName,
525  contour,
526  geoPanel.getEdgeWidth(),
527  geoPanel.getEdgeMaterial());
528 
529  move = G4TranslateZ3D((geoPanel.getLength() - geoPanel.getEdgeWidth()) / 2);
530  new G4PVPlacement(move, faceEdge, faceEdgeName, panel, false, 1);
531  move = G4TranslateZ3D(-(geoPanel.getLength() - geoPanel.getEdgeWidth()) / 2);
532  new G4PVPlacement(move, faceEdge, faceEdgeName, panel, false, 2);
533 
534  // reinforced sides
535 
536  double width = geo.getPanelWidth();
537  double sideEdgeWidth = geoPanel.getEdgeWidth() + (width - geoPanel.getWidth()) / 2;
538  std::string sideEdgeName = geoPanel.getName() + "ReinforcedSide";
539  auto* sideEdge = createBox(sideEdgeName,
540  sideEdgeWidth,
541  sideEdgeHeight,
542  geoPanel.getLength() - 2 * geoPanel.getEdgeWidth(),
543  geoPanel.getEdgeMaterial());
544 
545 
546  move = G4Translate3D((width - sideEdgeWidth) / 2, sideEdgeY, 0);
547  new G4PVPlacement(move, sideEdge, sideEdgeName, panel, false, 1);
548  move = G4Translate3D(-(width - sideEdgeWidth) / 2, sideEdgeY, 0);
549  new G4PVPlacement(move, sideEdge, sideEdgeName, panel, false, 2);
550 
551  return panel;
552  }
553 
554 
555  G4LogicalVolume* GeoTOPCreator::createSideRail(const TOPGeoQBB& geo,
556  ESideRailType type)
557  {
558  double A = geo.getSideRails().getThickness();
559  double B = geo.getSideRails().getHeight();
560  double C = geo.getSideRailsLength();
561  double a = A - geo.getSideRails().getReducedThickness();
562  double b = B - geo.getColdPlate().getBaseThickness();
563  double c = geo.getPrismEnclosure().getLength() -
565 
566  auto* box = new G4Box("box", A / 2, B / 2, C / 2);
567  auto* subtrBox = new G4Box("subtrBox", a / 2, b / 2, c / 2);
568  double x = 0;
569  if (type == c_Left) {
570  x = (A - a) / 2;
571  } else {
572  x = -(A - a) / 2;
573  }
574  G4Transform3D move = G4Translate3D(x, -(B - b) / 2, -(C - c) / 2);
575  auto* solid = new G4SubtractionSolid("sideRail", box, subtrBox, move);
576 
577  G4Material* material = Materials::get(geo.getSideRails().getMaterial());
578  if (!material) B2FATAL("Material '" << geo.getSideRails().getMaterial() <<
579  "' not found");
580 
581  std::string name = geo.getSideRails().getName();
582  if (type == c_Left) {
583  name += "Left";
584  } else {
585  name += "Rigth";
586  }
587 
588  return new G4LogicalVolume(solid, material, name);
589  }
590 
591 
592  G4AssemblyVolume* GeoTOPCreator::assembleOptics(const TOPGeoModule& geo)
593  {
594  auto* optics = new G4AssemblyVolume();
595  Simulation::RunManager::Instance().addAssemblyVolume(optics);
596 
597  const double Lm = geo.getMirrorSegment().getFullLength();
598  const double L1 = geo.getBarSegment1().getFullLength();
599  const double L2 = geo.getBarSegment2().getFullLength();
600  const double Lp = geo.getPrism().getFullLength();
601  const double La = geo.getPMTArray().getSizeZ();
602 
603  // note: z = 0 is at prism-bar joint
604 
605  auto* pmtArray = createPMTArray(geo.getPMTArray(), geo.getModuleID());
606  double Dy = (geo.getPrism().getThickness() - geo.getPrism().getExitThickness()) / 2;
607  G4ThreeVector moveArray(geo.getPMTArrayDisplacement().getX(),
608  geo.getPMTArrayDisplacement().getY() + Dy,
609  -(Lp + La / 2));
610  G4RotationMatrix rotArray;
611  rotArray.rotateZ(geo.getPMTArrayDisplacement().getAlpha());
612  optics->AddPlacedVolume(pmtArray, moveArray, &rotArray);
613 
614  G4ThreeVector move;
615  G4RotationMatrix rot;
616 
617  auto* prism = createPrism(geo.getPrism(), geo.getModuleID());
618  move.setZ(0);
619  rot.rotateY(M_PI / 2);
620  optics->AddPlacedVolume(prism, move, &rot);
621 
622  auto* barSegment2 = createBarSegment(geo.getBarSegment2(), geo.getModuleID());
623  move.setZ(L2 / 2);
624  optics->AddPlacedVolume(barSegment2, move, 0);
625 
626  auto* barSegment1 = createBarSegment(geo.getBarSegment1(), geo.getModuleID());
627  move.setZ(L2 + L1 / 2);
628  optics->AddPlacedVolume(barSegment1, move, 0);
629 
630  auto* mirrorSegment = createMirrorSegment(geo.getMirrorSegment(),
631  geo.getModuleID());
632  move.setZ(L2 + L1 + Lm / 2);
633  optics->AddPlacedVolume(mirrorSegment, move, 0);
634 
635  // peek frame approximation (in order to shadow total reflection at prism end)
636  // a call to getFilterThickness is added for backward compatibility
637  const double length = geo.getPrism().getFilterThickness() + 3.5; //mm
638  const double thickness = 1.0; //mm
639  const double width = geo.getPrism().getWidth();
640  const double Yup = geo.getPrism().getThickness() / 2;
641  const double Ydn = Yup - geo.getPrism().getExitThickness();
642 
643  auto* peekFrameAbove = createBox("PeekFrameAbove", width, thickness, length, "Al");
644  move.setZ(-(Lp - length / 2));
645  move.setY(Yup + thickness / 2);
646  optics->AddPlacedVolume(peekFrameAbove, move, 0);
647 
648  auto* peekFrameBelow = createBox("PeekFrameBelow", width, thickness, length, "Al");
649  move.setZ(-(Lp - length / 2));
650  move.setY(Ydn - thickness / 2);
651  optics->AddPlacedVolume(peekFrameBelow, move, 0);
652 
653  return optics;
654  }
655 
656 
657  G4LogicalVolume* GeoTOPCreator::createBarSegment(const TOPGeoBarSegment& geo,
658  int moduleID)
659  {
660  G4Transform3D move;
661 
662  // mother volume
663  auto* bar = createBox(geo.getName(),
664  geo.getWidth(), geo.getThickness(), geo.getFullLength(),
665  geo.getMaterial());
666  // glue
667  auto* glue = createBox(geo.getName() + "Glue",
668  geo.getWidth(), geo.getThickness(), geo.getGlueThickness(),
669  geo.getGlueMaterial());
670  if (geo.getBrokenGlueFraction() > 0) {
671  auto* brokenGlue = createExtrudedSolid(geo.getName() + "BrokenGlue",
672  geo.getBrokenGlueContour(),
673  geo.getGlueThickness(),
674  geo.getBrokenGlueMaterial());
675  G4Transform3D fix;
676  new G4PVPlacement(fix, brokenGlue, geo.getName() + "BrokenGlue", glue, false, 1);
677  B2RESULT("GeoTOPCreator, broken glue at " << geo.getName()
678  << addNumber(" of Slot", moduleID));
679  m_numBrokenGlues++;
680  }
681 
682  // place glue to -z side
683  move = G4TranslateZ3D(-(geo.getFullLength() - geo.getGlueThickness()) / 2);
684  new G4PVPlacement(move, glue, geo.getName() + "Glue", bar, false, 1);
685 
686  // optical surface
687  auto& materials = Materials::getInstance();
688  auto* optSurf = materials.createOpticalSurface(geo.getSurface());
689  optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
690  new G4LogicalSkinSurface("opticalSurface", bar, optSurf);
691 
692  // Activate sensitive volume
693  bar->SetSensitiveDetector(m_sensitiveBar);
694 
695  return bar;
696  }
697 
698 
699  G4LogicalVolume* GeoTOPCreator::createMirrorSegment(const TOPGeoMirrorSegment& geo,
700  int moduleID)
701  {
702  G4Transform3D move;
703 
704  // box of the bar
705  auto* box = new G4Box(geo.getName(),
706  geo.getWidth() / 2, geo.getThickness() / 2,
707  geo.getFullLength() / 2);
708 
709  // mother volume
710  auto* bar = createBoxSphereIntersection(geo.getName(),
711  box,
712  0, geo.getOuterRadius(),
713  geo.getXc(), geo.getYc(), geo.getZc(),
714  geo.getMaterial());
715 
716  // glue
717  auto* glue = createBox(geo.getName() + "Glue",
718  geo.getWidth(), geo.getThickness(), geo.getGlueThickness(),
719  geo.getGlueMaterial());
720  if (geo.getBrokenGlueFraction() > 0) {
721  auto* brokenGlue = createExtrudedSolid(geo.getName() + "BrokenGlue",
722  geo.getBrokenGlueContour(),
723  geo.getGlueThickness(),
724  geo.getBrokenGlueMaterial());
725  G4Transform3D fix;
726  new G4PVPlacement(fix, brokenGlue, geo.getName() + "BrokenGlue", glue, false, 1);
727  B2RESULT("GeoTOPCreator, broken glue at " << geo.getName()
728  << addNumber(" of Slot", moduleID));
729  m_numBrokenGlues++;
730  }
731 
732  // place glue to -z side
733  move = G4TranslateZ3D(-(geo.getFullLength() - geo.getGlueThickness()) / 2);
734  new G4PVPlacement(move, glue, geo.getName() + "Glue", bar, false, 1);
735 
736  // bar optical surface
737  auto& materials = Materials::getInstance();
738  auto* optSurf = materials.createOpticalSurface(geo.getSurface());
739  optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
740  new G4LogicalSkinSurface("opticalSurface", bar, optSurf);
741 
742  // mirror reflective coating
743  auto* mirror = createBoxSphereIntersection(geo.getName() + "ReflectiveCoating",
744  box,
745  geo.getRadius(), geo.getOuterRadius(),
746  geo.getXc(), geo.getYc(), geo.getZc(),
747  geo.getCoatingMaterial());
748 
749  // mirror optical surface
750  auto* mirrorSurf = materials.createOpticalSurface(geo.getCoatingSurface());
751  new G4LogicalSkinSurface("mirrorSurface", mirror, mirrorSurf);
752 
753  // place reflective coating
754  move = G4TranslateZ3D(0);
755  new G4PVPlacement(move, mirror, geo.getName() + "ReflectiveCoating", bar, false, 1);
756 
757  // Activate sensitive volume
758  bar->SetSensitiveDetector(m_sensitiveBar);
759 
760  return bar;
761  }
762 
763 
764  G4LogicalVolume* GeoTOPCreator::createPrism(const TOPGeoPrism& geo, int moduleID)
765 
766  {
767  G4Transform3D move;
768 
769  // mother volume
770 
771  std::vector<G4TwoVector> polygon;
772  polygon.push_back(G4TwoVector(0, geo.getThickness() / 2));
773  polygon.push_back(G4TwoVector(geo.getFullLength(), geo.getThickness() / 2));
774  polygon.push_back(G4TwoVector(geo.getFullLength(),
775  geo.getThickness() / 2 - geo.getExitThickness()));
776  polygon.push_back(G4TwoVector(geo.getLength() - geo.getFlatLength(),
777  geo.getThickness() / 2 - geo.getExitThickness()));
778  polygon.push_back(G4TwoVector(0, -geo.getThickness() / 2));
779 
780  auto* volume = new G4ExtrudedSolid(geo.getName(), polygon, geo.getWidth() / 2,
781  G4TwoVector(), 1, G4TwoVector(), 1);
782  G4Material* material = Materials::get(geo.getMaterial());
783  if (!material) B2FATAL("Material '" << geo.getMaterial() << "' not found");
784  auto* prism = new G4LogicalVolume(volume, material, geo.getName());
785 
786  // wavelenght filter (old payload) and peel-off regions (if defined)
787  // new payload: wavelength filter is a part of PMT array
788 
789  if (geo.getFilterThickness() > 0 or !geo.getPeelOffRegions().empty()) {
790  double filterThickness = geo.getFilterThickness();
791  std::string filterMaterial;
792  if (filterThickness > 0) { // old payload, put wavelength filter into prism
793  filterMaterial = geo.getFilterMaterial();
794  } else { // new payload, make a dummy volume in which to put peel-off regions
795  filterThickness = geo.getPeelOffThickness();
796  filterMaterial = geo.getMaterial();
797  }
798  auto* filter = createBox(geo.getName() + "Filter",
799  filterThickness,
800  geo.getExitThickness(),
801  geo.getWidth(),
802  filterMaterial);
803  // place peel-off regions (if any) into filter
804  int numRegions = 0;
805  std::string message = addNumber("peel-off cookie regions of Slot", moduleID) + ":";
806  for (const auto& region : geo.getPeelOffRegions()) {
807  if (region.fraction <= 0) continue;
808  std::string name = addNumber(geo.getName() + "PeelOff", region.ID);
809  double thickness = geo.getPeelOffThickness();
810  auto* peelOff = createExtrudedSolid(name,
811  geo.getPeelOffContour(region),
812  thickness,
813  geo.getPeelOffMaterial());
814  G4Transform3D T = G4Translate3D((geo.getFilterThickness() - thickness) / 2,
815  0,
816  geo.getPeelOffCenter(region));
817  G4Transform3D R = G4RotateY3D(-M_PI / 2);
818  G4Transform3D moveRegion = T * R;
819  new G4PVPlacement(moveRegion, peelOff, name, filter, false, 1);
820  message += addNumber(" ", region.ID);
821  numRegions++;
822  }
823  if (numRegions > 0) B2RESULT("GeoTOPCreator, " << message);
824  m_numPeelOffRegions += numRegions;
825 
826  // place filter to +x side
827  move = G4Translate3D(geo.getFullLength() - geo.getFilterThickness() / 2,
828  (geo.getThickness() - geo.getExitThickness()) / 2,
829  0);
830  new G4PVPlacement(move, filter, geo.getName() + "Filter", prism, false, 1);
831  }
832 
833  // optical surface
834 
835  auto& materials = Materials::getInstance();
836  auto* optSurf = materials.createOpticalSurface(geo.getSurface());
837  optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
838  new G4LogicalSkinSurface("opticalSurface", prism, optSurf);
839 
840  // Activate sensitive volume
841 
842  prism->SetSensitiveDetector(m_sensitiveBar);
843 
844  return prism;
845  }
846 
847 
848  G4LogicalVolume* GeoTOPCreator::createPMTArray(const TOPGeoPMTArray& geo,
849  int moduleID)
850  {
851  // mother volume
852  auto* pmtArray = createBox(geo.getName(),
853  geo.getSizeX(), geo.getSizeY(),
854  geo.getSizeZ(),
855  geo.getMaterial());
856 
857  // single PMT
858  auto* pmt = createPMT(geo.getPMT());
859 
860  // place PMT's
861  std::string message = addNumber("optically decoupled PMT's of Slot", moduleID) + ":";
862  for (unsigned row = 1; row <= geo.getNumRows(); row++) {
863  for (unsigned col = 1; col <= geo.getNumColumns(); col++) {
864  auto id = geo.getPmtID(row, col);
865  double z = geo.getAirGap();
866  if (geo.isPMTDecoupled(id)) {
867  z = 0;
868  message += addNumber(" ", id);
869  m_numDecoupledPMTs++;
870  }
871  z -= (geo.getSizeZ() - geo.getPMT().getSizeZ()) / 2;
872  G4Transform3D move = G4Translate3D(geo.getX(col), geo.getY(row), z);
873  new G4PVPlacement(move, pmt, addNumber(geo.getPMT().getName(), id), pmtArray,
874  false, id);
875  }
876  }
877 
878  // wavelenght filter and silicone cookies (new payload)
879  if (geo.getFilterThickness() > 0) { // new payload
880  double fullThickness = geo.getFilterThickness() + geo.getCookieThickness();
881  auto* filter = createBox(geo.getName() + "Filter+Cookie",
882  geo.getSizeX(), geo.getSizeY(),
883  fullThickness,
884  geo.getFilterMaterial());
885  double cookieThickness = geo.getCookieThickness();
886  auto* cookie = createBox(geo.getName() + "Cookie",
887  geo.getSizeX(), geo.getSizeY(),
888  cookieThickness,
889  geo.getCookieMaterial());
890  G4Transform3D move = G4Translate3D(0, 0, (fullThickness - cookieThickness) / 2);
891  new G4PVPlacement(move, cookie, geo.getName() + "Cookie", filter, false, 1);
892 
893  move = G4Translate3D(0, 0, (geo.getSizeZ() - fullThickness) / 2);
894  new G4PVPlacement(move, filter, geo.getName() + "Filter+Cookie", pmtArray,
895  false, 1);
896  }
897 
898  if (!geo.getDecoupledPMTs().empty()) B2RESULT("GeoTOPCreator, " << message);
899 
900  return pmtArray;
901  }
902 
903 
904  G4LogicalVolume* GeoTOPCreator::createPMT(const TOPGeoPMT& geo)
905  {
906  G4Transform3D move;
907 
908  // mother volume
909  auto* pmt = createBox(geo.getName(),
910  geo.getSizeX(), geo.getSizeY(), geo.getSizeZ(),
911  geo.getWallMaterial());
912 
913  // window + photocathode + reflective edge
914  double winThickness = geo.getWinThickness() + geo.getReflEdgeThickness();
915  auto* window = createBox(geo.getName() + "Window",
916  geo.getSizeX(), geo.getSizeY(),
917  winThickness,
918  geo.getWinMaterial());
919  auto* photoCathode = createBox(geo.getName() + "PhotoCathode",
920  geo.getSensSizeX(), geo.getSensSizeY(),
921  geo.getSensThickness(),
922  geo.getSensMaterial());
923  photoCathode->SetSensitiveDetector(m_sensitivePMT); // Activate sensitive area
924 
925  move = G4TranslateZ3D(-(winThickness - geo.getSensThickness()) / 2
926  + geo.getReflEdgeThickness());
927  new G4PVPlacement(move, photoCathode, geo.getName() + "PhotoCathode", window,
928  false, 1);
929 
930  auto* reflEdge = createBox(geo.getName() + "ReflectiveEdge",
931  geo.getSizeX(), geo.getSizeY(),
932  geo.getReflEdgeThickness(),
933  geo.getWallMaterial());
934  double holeSizeX = geo.getSizeX() - 2 * geo.getReflEdgeWidth();
935  double holeSizeY = geo.getSizeY() - 2 * geo.getReflEdgeWidth();
936  if (holeSizeX > 0 and holeSizeY > 0) {
937  auto* hole = createBox(geo.getName() + "ReflectiveEdgeHole",
938  holeSizeX, holeSizeY,
939  geo.getReflEdgeThickness(),
940  geo.getFillMaterial());
941  move = G4TranslateZ3D(0.0);
942  new G4PVPlacement(move, hole, geo.getName() + "ReflectiveEdgeHole", reflEdge,
943  false, 1);
944  }
945 
946  auto& materials = Materials::getInstance();
947  auto* optSurf = materials.createOpticalSurface(geo.getReflEdgeSurface());
948  new G4LogicalSkinSurface("reflectiveEdgeSurface", reflEdge, optSurf);
949 
950  move = G4TranslateZ3D(-(winThickness - geo.getReflEdgeThickness()) / 2);
951  new G4PVPlacement(move, reflEdge, geo.getName() + "ReflectiveEdge", window,
952  false, 1);
953 
954  move = G4TranslateZ3D((geo.getSizeZ() - winThickness) / 2);
955  new G4PVPlacement(move, window, geo.getName() + "Window", pmt, false, 1);
956 
957  // bottom
958  if (geo.getBotMaterial() != geo.getWallMaterial()) {
959  auto* bottom = createBox(geo.getName() + "Bottom",
960  geo.getSizeX(), geo.getSizeY(), geo.getBotThickness(),
961  geo.getBotMaterial());
962  move = G4TranslateZ3D(-(geo.getSizeZ() - geo.getBotThickness()) / 2);
963  new G4PVPlacement(move, bottom, geo.getName() + "Bottom", pmt, false, 1);
964  }
965 
966  // interior
967  double interiorSizeZ = geo.getSizeZ() - winThickness - geo.getBotThickness();
968  auto* interior = createBox(geo.getName() + "Interior",
969  geo.getSizeX() - 2 * geo.getWallThickness(),
970  geo.getSizeY() - 2 * geo.getWallThickness(),
971  interiorSizeZ,
972  geo.getBotMaterial());
973  move = G4TranslateZ3D(-(geo.getSizeZ() - interiorSizeZ) / 2
974  + geo.getBotThickness());
975  new G4PVPlacement(move, interior, geo.getName() + "Interior", pmt, false, 1);
976 
977  return pmt;
978  }
979 
980 
981  G4LogicalVolume* GeoTOPCreator::createBox(const std::string& name,
982  double A, double B, double C,
983  const std::string& materialName)
984  {
985  G4Box* box = new G4Box(name, A / 2, B / 2, C / 2);
986  G4Material* material = Materials::get(materialName);
987  if (!material) B2FATAL("Material '" << materialName << "' not found");
988  return new G4LogicalVolume(box, material, name);
989  }
990 
991 
992  G4LogicalVolume*
993  GeoTOPCreator::createBoxSphereIntersection(const std::string& name,
994  G4Box* box,
995  double Rmin,
996  double Rmax,
997  double xc,
998  double yc,
999  double zc,
1000  const std::string& materialName)
1001  {
1002  // determine max theta - note: not valid generically!
1003  double x = box->GetXHalfLength();
1004  double y = box->GetYHalfLength();
1005  double z = box->GetZHalfLength();
1006  double dx = fmax(fabs(-x - xc), fabs(x - xc));
1007  double dy = fmax(fabs(-y - yc), fabs(y - yc));
1008  double dz = fmin(-z - zc, z - zc);
1009  double theta = atan(sqrt(dx * dx + dy * dy) / dz);
1010 
1011  auto* sphere = new G4Sphere(name + "Sphere",
1012  Rmin, Rmax, 0, 2 * M_PI, 0, theta);
1013  G4Translate3D move(xc, yc, zc);
1014  auto* shape = new G4IntersectionSolid(name, box, sphere, move);
1015 
1016  G4Material* material = Materials::get(materialName);
1017  if (!material) B2FATAL("Material '" << materialName << "' not found");
1018  return new G4LogicalVolume(shape, material, name);
1019  }
1020 
1021 
1022  G4LogicalVolume* GeoTOPCreator::createExtrudedSolid(const std::string& name,
1023  const Polygon& shape,
1024  double length,
1025  const std::string& materialName)
1026  {
1027  std::vector<G4TwoVector> polygon;
1028  for (auto& point : shape) {
1029  polygon.push_back(G4TwoVector(point.first, point.second));
1030  }
1031  G4ExtrudedSolid* solid = new G4ExtrudedSolid(name, polygon, length / 2,
1032  G4TwoVector(), 1, G4TwoVector(), 1);
1033  G4Material* material = Materials::get(materialName);
1034  if (!material) B2FATAL("Material '" << materialName << "' not found");
1035  return new G4LogicalVolume(solid, material, name);
1036  }
1037 
1038 
1039  std::string GeoTOPCreator::addNumber(const std::string& str, unsigned number)
1040  {
1041  stringstream ss;
1042  if (number < 10) {
1043  ss << "0" << number;
1044  } else {
1045  ss << number;
1046  }
1047  string out;
1048  ss >> out;
1049  return str + out;
1050  }
1051 
1052  } // name space TOP
1054 } // name space Belle2
double R
typedef autogenerated by FFTW
The Class for BeamBackground Sensitive Detector.
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
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.
Geometry parameters of a quartz bar segment.
double getWidth() const
Returns bar segment width.
const std::string & getBrokenGlueMaterial() const
Returns material name which represents broken glue.
double getFullLength() const
Returns bar segment length including glue.
const std::string & getGlueMaterial() const
Returns glue material name (glue on -z side)
double getThickness() const
Returns bar segment thickness.
double getSigmaAlpha() const
Returns geant4 parameter describing surface roughness.
double getBrokenGlueFraction() const
Returns fraction of the delaminated surface.
const std::string & getMaterial() const
Returns bar segment material name.
const GeoOpticalSurface & getSurface() const
Returns optical surface.
double getLength() const
Returns bar segment length.
virtual double getGlueThickness() const
Returns glue thickness (glue on -z side)
const std::string & getName() const
Returns object name.
Definition: TOPGeoBase.h:51
const std::string & getCoolMaterial() const
Returns cooling plate material name.
double getCoolWidth() const
Returns cooling plate width.
double getCoolThickness() const
Returns cooling plate thickness.
double getBaseThickness() const
Returns base plate thickness.
const std::string & getBaseMaterial() const
Returns base plate material name.
double getHeight() const
Returns height.
double getThickness() const
Returns thickness.
const std::string & getMaterial() const
Returns material name.
Geometry parameters of board stack (front-end electronic module)
double getHVBoardGap() const
Returns gap between HV board and front board.
double getFrontBoardGap() const
Returns gap between front board and PMT array.
double getHVBoardThickness() const
Returns HV board thickness.
double getFrontBoardThickness() const
Returns front board thickness.
double getHVBoardLength() const
Returns HV board length.
const std::string & getBoardStackMaterial() const
Returns board stack material.
double getBoardStackLength() const
Returns board stack length.
double getBoardStackY() const
Returns position of board stack center in bar frame.
double getBoardStackWidth() const
Returns board stack width.
double getFrontBoardWidth() const
Returns front board width.
double getBoardStackHeight() const
Returns board stack height.
const std::string & getFrontBoardMaterial() const
Returns front board material.
double getBoardStackGap() const
Returns gap between board stack and front board.
const std::string & getSpacerMaterial() const
Returns board stack spacer material.
double getHVBoardY() const
Returns position of HV board center in bar frame.
double getHVBoardWidth() const
Returns HV board width.
double getFrontBoardY() const
Returns position of front board center in bar frame.
double getFrontBoardHeight() const
Returns front board height.
double getSpacerWidth() const
Returns board stack spacer width.
const std::string & getHVBoardMaterial() const
Returns HV board material.
Geometry parameters of honeycomb panel.
double getWidth() const
Returns panel width.
double getMaxThickness() const
Returns panel maximal thickness.
const std::string & getEdgeMaterial() const
Returns material name of reinforced edge.
double getMinThickness() const
Returns panel minimal thickness.
double getY() const
Returns y position of the flat surface in local (bar) frame.
const std::string & getMaterial() const
Returns material name.
double getEdgeWidth() const
Returns width of the reinforced edge.
double getLength() const
Returns panel length.
Geometry parameters of a mirror segment.
const std::string & getCoatingMaterial() const
Returns reflective coating material.
double getYc() const
Returns spherical mirror center of curvature in y.
double getOuterRadius() const
Returns spherical mirror outer radius of curvature.
double getRadius() const
Returns spherical mirror radius of curvature.
const GeoOpticalSurface & getCoatingSurface() const
Returns reflective coating optical surface.
double getXc() const
Returns spherical mirror center of curvature in x.
Geometry parameters of a module (optical components + positioning)
Definition: TOPGeoModule.h:31
const TOPGeoBarSegment & getBarSegment1() const
Returns bar segment No.1 (forward bar)
Definition: TOPGeoModule.h:200
const TOPGeoPrism & getPrism() const
Returns prism.
Definition: TOPGeoModule.h:218
const TOPGeoPMTArrayDisplacement & getPMTArrayDisplacement() const
Returns PMT array displacement.
Definition: TOPGeoModule.h:230
int getModuleID() const
Returns module ID.
Definition: TOPGeoModule.h:170
const TOPGeoBarSegment & getBarSegment2() const
Returns bar segment No.2 (backward bar)
Definition: TOPGeoModule.h:206
const TOPGeoPMTArray & getPMTArray() const
Returns PMT array.
Definition: TOPGeoModule.h:224
const TOPGeoMirrorSegment & getMirrorSegment() const
Returns mirror segment.
Definition: TOPGeoModule.h:212
double getX() const
Returns translation in x.
double getAlpha() const
Returns rotation angle (around z)
double getY() const
Returns translation in y.
Geometry parameters of MCP-PMT array.
double getSizeZ() const
Returns array volume dimension in z.
unsigned getNumColumns() const
Returns number of array columns.
double getX(unsigned col) const
Returns x coordinate of column center.
double getY(unsigned row) const
Returns the y coordinate of row center.
double getFilterThickness() const
Returns wavelength filter thickness.
const std::string & getCookieMaterial() const
Returns silicone cookie material.
const std::vector< unsigned > & getDecoupledPMTs() const
Returns ID's of optically decoupled PMT's.
double getSizeX() const
Returns array volume dimension in x.
double getSizeY() const
Returns array volume dimension in y.
const std::string & getMaterial() const
Returns material name into which PMT's are inserted.
unsigned getNumRows() const
Returns number of array rows.
const TOPGeoPMT & getPMT() const
Returns PMT geometry parameters.
double getCookieThickness() const
Returns silicone cookie thickness.
const std::string & getFilterMaterial() const
Returns wavelenght filter material.
double getAirGap() const
Returns air gap.
Geometry parameters of MCP-PMT.
Definition: TOPGeoPMT.h:24
double getSizeZ() const
Returns full size in z.
Definition: TOPGeoPMT.h:141
const std::string & getSensMaterial() const
Returns sensitive material name.
Definition: TOPGeoPMT.h:201
const std::string & getFillMaterial() const
Returns fill (inside) material name.
Definition: TOPGeoPMT.h:159
double getReflEdgeThickness() const
Returns reflective edge thickness.
Definition: TOPGeoPMT.h:237
const std::string & getWinMaterial() const
Returns entrance window material name.
Definition: TOPGeoPMT.h:213
double getWinThickness() const
Returns entrance window thickness.
Definition: TOPGeoPMT.h:207
double getBotThickness() const
Returns bottom thickness.
Definition: TOPGeoPMT.h:219
const std::string & getWallMaterial() const
Returns wall (casing) material name.
Definition: TOPGeoPMT.h:153
double getReflEdgeWidth() const
Returns reflective edge width.
Definition: TOPGeoPMT.h:231
double getSensSizeX() const
Returns sensitive volume (photo-cathode) size in x.
Definition: TOPGeoPMT.h:165
double getSizeX() const
Returns full size in x.
Definition: TOPGeoPMT.h:129
const std::string & getBotMaterial() const
Returns bottom material name.
Definition: TOPGeoPMT.h:225
double getSizeY() const
Returns full size in y.
Definition: TOPGeoPMT.h:135
double getWallThickness() const
Returns wall thickness.
Definition: TOPGeoPMT.h:147
double getSensThickness() const
Returns sensitive volume (photo-cathode) thickness.
Definition: TOPGeoPMT.h:177
const GeoOpticalSurface & getReflEdgeSurface() const
Returns reflective edge optical surface.
Definition: TOPGeoPMT.h:243
double getSensSizeY() const
Returns sensitive volume (photo-cathode) size in y.
Definition: TOPGeoPMT.h:171
double getBackThickness() const
Returns back wall thickness.
double getBodyLength() const
Returns length w/o back and front plates.
const std::string & getMaterial() const
Returns material name.
double getExtensionThickness() const
Returns extension plate thickness.
double getFrontThickness() const
Returns front wall thickness.
double getLength() const
Returns full length.
Geometry parameters of prism.
Definition: TOPGeoPrism.h:27
double getPeelOffCenter(const PeelOffRegion &region) const
Returns peel-off offset in x of the given region.
Definition: TOPGeoPrism.h:198
const std::string & getPeelOffMaterial() const
Returns peel-off material.
Definition: TOPGeoPrism.h:185
double getFilterThickness() const
Returns wavelength filter thickness (filter on -z side).
Definition: TOPGeoPrism.h:154
double getExitThickness() const
Returns prism thickness at PMT side.
Definition: TOPGeoPrism.h:126
double getPeelOffThickness() const
Returns peel-off thickness.
Definition: TOPGeoPrism.h:179
double getFlatLength() const
Returns the length of a flat surface at prism bottom.
Definition: TOPGeoPrism.h:132
const std::vector< PeelOffRegion > & getPeelOffRegions() const
Returns peel-off cookie regions.
Definition: TOPGeoPrism.h:191
const std::string & getFilterMaterial() const
Returns wavelength filter material name (filter on -z side) For backward compatibility,...
Definition: TOPGeoPrism.h:161
Geometry parameters of Quartz Bar Box (mother class)
Definition: TOPGeoQBB.h:30
double getWidth() const
Returns full width.
Definition: TOPGeoQBB.h:102
const TOPGeoPrismEnclosure & getPrismEnclosure() const
Returns prism enclosure.
Definition: TOPGeoQBB.h:162
const TOPGeoEndPlate & getForwardEndPlate() const
Returns forward end plate.
Definition: TOPGeoQBB.h:168
const TOPGeoSideRails & getSideRails() const
Returns side rails.
Definition: TOPGeoQBB.h:156
const TOPGeoColdPlate & getColdPlate() const
Returns cold plate.
Definition: TOPGeoQBB.h:174
double getSideRailsLength() const
Returns side rails length.
Definition: TOPGeoQBB.h:123
const TOPGeoHoneycombPanel & getInnerPanel() const
Returns inner honeycomb panel.
Definition: TOPGeoQBB.h:144
const TOPGeoHoneycombPanel & getOuterPanel() const
Returns outer honeycomb panel.
Definition: TOPGeoQBB.h:150
double getPrismPosition() const
Returns the position of prism-bar joint wrt QBB back.
Definition: TOPGeoQBB.h:132
const std::string & getMaterial() const
Returns the name of material inside QBB.
Definition: TOPGeoQBB.h:138
double getLength() const
Returns full length.
Definition: TOPGeoQBB.h:117
double getPanelWidth() const
Returns panel width used in x-y contours of honeycomb panels.
Definition: TOPGeoQBB.h:108
double getHeight() const
Returns height.
double getThickness() const
Returns thickness.
const std::string & getMaterial() const
Returns material name.
double getReducedThickness() const
Returns thickness at prism enclosure.
Geometry parameters of TOP.
Definition: TOPGeometry.h:34
unsigned getNumBoardStacks() const
Returns number of boardstacks per module.
Definition: TOPGeometry.h:168
static void useGeantUnits()
Use Geant units when returning geometry parameters.
Definition: TOPGeometry.h:58
const std::vector< TOPGeoModule > & getModules() const
Returns all modules.
Definition: TOPGeometry.h:149
const TOPGeoFrontEnd & getFrontEnd() const
Returns front-end.
Definition: TOPGeometry.h:162
const TOPGeoQBB & getQBB() const
Returns quartz bar box.
Definition: TOPGeometry.h:174
ESideRailType
Side rail types.
Definition: GeoTOPCreator.h:91
EPanelType
Honeycomb panel types.
Definition: GeoTOPCreator.h:86
Class providing information on MCParticles hitting the bars.
Definition: SensitiveBar.h:31
Class providing SimHits.
Definition: SensitivePMT.h:30
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
double atan(double a)
atan for double
Definition: beamHelpers.h:34
std::vector< std::pair< double, double > > getBackPlateContour() const
Returns prism enclosure back plate x-y contour.
Definition: TOPGeoQBB.cc:174
std::vector< std::pair< double, double > > getPrismEnclosureContour() const
Returns prism enclosure wall x-y contour.
Definition: TOPGeoQBB.cc:139
std::vector< std::pair< double, double > > getPeelOffContour(const PeelOffRegion &region) const
Returns the x-y contour of the peel-off region.
Definition: TOPGeoPrism.cc:118
double getZc() const
Returns spherical mirror center of curvature in z (in local frame of this segment)
bool isPMTDecoupled(unsigned pmtID) const
Checks if PMT is optically decoupled.
const TOPGeoModule & getModule(int moduleID) const
Returns module.
Definition: TOPGeometry.cc:42
std::vector< std::pair< double, double > > getFrontPlateContour() const
Returns prism enclosure front plate x-y contour.
Definition: TOPGeoQBB.cc:203
std::vector< std::pair< double, double > > getOuterPanelContour() const
Returns outer honeycomb panel x-y contour.
Definition: TOPGeoQBB.cc:80
std::vector< std::pair< double, double > > getForwardContour() const
Returns forward x-y contour.
Definition: TOPGeoQBB.cc:21
std::vector< std::pair< double, double > > getBrokenGlueContour() const
Returns the x-y contour of broken glue.
unsigned getPmtID(unsigned row, unsigned col) const
Converts row and column numbers to PMT ID (1-based)
std::vector< std::pair< double, double > > getBackwardContour() const
Returns backward x-y contour.
Definition: TOPGeoQBB.cc:106
std::vector< std::pair< double, double > > getInnerPanelContour() const
Returns inner honeycomb panel x-y contour.
Definition: TOPGeoQBB.cc:54
std::map< ExpRun, std::pair< double, double > > filter(const std::map< ExpRun, std::pair< double, double >> &runs, double cut, std::map< ExpRun, std::pair< double, double >> &runsRemoved)
filter events to remove runs shorter than cut, it stores removed runs in runsRemoved
Definition: Splitter.cc:38
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.