Belle II Software development
GeoTOPCreator Class Reference

Geometry creator for TOP counter. More...

#include <GeoTOPCreator.h>

Inheritance diagram for GeoTOPCreator:
CreatorBase

Public Member Functions

 GeoTOPCreator ()
 Constructor.
 
virtual ~GeoTOPCreator ()
 Destructor.
 
virtual void create (const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 Creation of the detector geometry from Gearbox (XML).
 
virtual void createFromDB (const std::string &name, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 Creation of the detector geometry from database.
 
virtual void createPayloads (const GearDir &content, const IntervalOfValidity &iov) override
 Creation of payloads.
 
 BELLE2_DEFINE_EXCEPTION (DBNotImplemented, "Cannot create geometry from Database.")
 Exception that will be thrown in createFromDB if member is not yet implemented by creator.
 

Private Types

enum  EPanelType {
  c_Inner ,
  c_Outer
}
 Honeycomb panel types. More...
 
enum  ESideRailType {
  c_Left ,
  c_Right
}
 Side rail types. More...
 

Private Member Functions

void createGeometry (const TOPGeometry &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
 Create the geometry from a parameter object.
 
G4LogicalVolume * createModule (const TOPGeometry &geo, int moduleID)
 Creates single module.
 
G4LogicalVolume * createModuleEnvelope (const TOPGeoQBB &geo, int moduleID)
 Creates module envelope.
 
G4AssemblyVolume * assembleQBB (const TOPGeoQBB &geo)
 Assembles QBB.
 
G4LogicalVolume * createHoneycombPanel (const TOPGeoQBB &geo, EPanelType type)
 Creates honeycomb panel.
 
G4LogicalVolume * createSideRail (const TOPGeoQBB &geo, ESideRailType type)
 Creates side rail.
 
G4AssemblyVolume * assembleFrontEnd (const TOPGeoFrontEnd &geo, int N)
 Assembles front-end electronics.
 
G4LogicalVolume * createBoardStack (const TOPGeoFrontEnd &geo, int N)
 Creates board stack.
 
G4AssemblyVolume * assembleOptics (const TOPGeoModule &geo)
 Assembles optical components (PMT array, prism and bar segments) along z.
 
G4LogicalVolume * createBarSegment (const TOPGeoBarSegment &geo, int moduleID)
 Creates quartz bar segment.
 
G4LogicalVolume * createPrism (const TOPGeoPrism &geo, int moduleID)
 Creates quartz prism.
 
G4LogicalVolume * createMirrorSegment (const TOPGeoMirrorSegment &geo, int moduleID)
 Creates quartz segment with spherical mirror.
 
G4LogicalVolume * createPMTArray (const TOPGeoPMTArray &geo, int moduleID)
 Creates PMT array.
 
G4LogicalVolume * createPMT (const TOPGeoPMT &geo)
 Creates single PMT.
 
G4LogicalVolume * createBox (const std::string &name, double A, double B, double C, const std::string &materialName)
 Creates material box.
 
G4LogicalVolume * createBoxSphereIntersection (const std::string &name, G4Box *box, double Rmin, double Rmax, double xc, double yc, double zc, const std::string &materialName)
 Creates material volume that is intersection of box and half-sphere shell (z > 0)
 
G4LogicalVolume * createExtrudedSolid (const std::string &name, const Polygon &shape, double length, const std::string &materialName)
 Creates material extruded solid.
 
std::string addNumber (const std::string &str, unsigned number)
 Adds number to string.
 

Private Attributes

SensitivePMTm_sensitivePMT = 0
 Sensitive vol.
 
SensitiveBarm_sensitiveBar = 0
 Sensitive vol.
 
BkgSensitiveDetectorm_sensitivePCB1 = 0
 PCB sensitive for BG studies.
 
BkgSensitiveDetectorm_sensitivePCB2 = 0
 PCB sensitive for BG studies.
 
TOPGeometryParm_topgp = TOPGeometryPar::Instance()
 singleton class
 
int m_isBeamBkgStudy = 0
 flag for beam backgound simulation
 
G4UnionSolid * m_moduleEnvelope = 0
 module envelope solid
 
G4AssemblyVolume * m_qbb = 0
 QBB assembly volume.
 
G4AssemblyVolume * m_frontEnd = 0
 front-end electronics assembly volume
 
int m_numDecoupledPMTs = 0
 number of optically decoupled PMT's
 
int m_numBrokenGlues = 0
 number of broken glues
 
int m_numPeelOffRegions = 0
 number of peel-off regions
 

Detailed Description

Geometry creator for TOP counter.

Definition at line 40 of file GeoTOPCreator.h.

Member Enumeration Documentation

◆ EPanelType

enum EPanelType
private

Honeycomb panel types.

Definition at line 86 of file GeoTOPCreator.h.

86{c_Inner, c_Outer};

◆ ESideRailType

enum ESideRailType
private

Side rail types.

Definition at line 91 of file GeoTOPCreator.h.

91{c_Left, c_Right};

Constructor & Destructor Documentation

◆ GeoTOPCreator()

Constructor.

Definition at line 66 of file GeoTOPCreator.cc.

67 {}

◆ ~GeoTOPCreator()

~GeoTOPCreator ( )
virtual

Destructor.

Definition at line 70 of file GeoTOPCreator.cc.

71 {
76 G4LogicalSkinSurface::CleanSurfaceTable();
77 }
SensitiveBar * m_sensitiveBar
Sensitive vol.
BkgSensitiveDetector * m_sensitivePCB2
PCB sensitive for BG studies.
BkgSensitiveDetector * m_sensitivePCB1
PCB sensitive for BG studies.
SensitivePMT * m_sensitivePMT
Sensitive vol.

Member Function Documentation

◆ addNumber()

std::string addNumber ( const std::string &  str,
unsigned  number 
)
private

Adds number to string.

Parameters
strstring
numbernumber to be added
Returns
string with a number

Definition at line 1040 of file GeoTOPCreator.cc.

1041 {
1042 stringstream ss;
1043 if (number < 10) {
1044 ss << "0" << number;
1045 } else {
1046 ss << number;
1047 }
1048 string out;
1049 ss >> out;
1050 return str + out;
1051 }

◆ assembleFrontEnd()

G4AssemblyVolume * assembleFrontEnd ( const TOPGeoFrontEnd geo,
int  N 
)
private

Assembles front-end electronics.

Parameters
geogeometry description
Nnumber of board stacks per module
Returns
assembly volume

Definition at line 278 of file GeoTOPCreator.cc.

279 {
280 auto* frontEnd = new G4AssemblyVolume();
282
283 G4ThreeVector move;
284
285 // front board
286
287 double Z = -geo.getFrontBoardGap();
288 double length = geo.getFrontBoardThickness();
289 auto* frontBoard = createBox("TOPFrontBoard",
290 geo.getFrontBoardWidth(),
291 geo.getFrontBoardHeight(),
292 length,
293 geo.getFrontBoardMaterial());
294 if (m_isBeamBkgStudy) {
295 if (!m_sensitivePCB1) m_sensitivePCB1 = new BkgSensitiveDetector("TOP", 1);
296 frontBoard->SetSensitiveDetector(m_sensitivePCB1);
297 }
298 move.setZ(Z - length / 2);
299 move.setY(geo.getFrontBoardY());
300 frontEnd->AddPlacedVolume(frontBoard, move, 0);
301 Z -= length;
302
303 // HV board
304
305 length = geo.getHVBoardLength();
306 auto* HVBoard = createBox("TOPHVBoard",
307 geo.getHVBoardWidth(),
308 geo.getHVBoardThickness(),
309 length,
310 geo.getHVBoardMaterial());
311 if (m_isBeamBkgStudy) {
312 if (!m_sensitivePCB2) m_sensitivePCB2 = new BkgSensitiveDetector("TOP", 2);
313 HVBoard->SetSensitiveDetector(m_sensitivePCB2);
314 }
315 move.setZ(Z - geo.getHVBoardGap() - length / 2);
316 move.setY(geo.getHVBoardY());
317 frontEnd->AddPlacedVolume(HVBoard, move, 0);
318
319 // board stack
320
321 length = geo.getBoardStackLength();
322 move.setZ(Z - geo.getBoardStackGap() - length / 2);
323 move.setY(geo.getBoardStackY());
324 auto* boardStack = createBoardStack(geo, N);
325 frontEnd->AddPlacedVolume(boardStack, move, 0);
326
327 return frontEnd;
328 }
void addAssemblyVolume(G4AssemblyVolume *vol)
Register a G4AssemblyVolume.
Definition: RunManager.h:68
static RunManager & Instance()
Static method to get a reference to the RunManager instance.
Definition: RunManager.cc:29
G4LogicalVolume * createBoardStack(const TOPGeoFrontEnd &geo, int N)
Creates board stack.
G4LogicalVolume * createBox(const std::string &name, double A, double B, double C, const std::string &materialName)
Creates material box.
int m_isBeamBkgStudy
flag for beam backgound simulation

◆ assembleOptics()

G4AssemblyVolume * assembleOptics ( const TOPGeoModule geo)
private

Assembles optical components (PMT array, prism and bar segments) along z.

Parameters
geogeometry description
Returns
assembly volume

Definition at line 593 of file GeoTOPCreator.cc.

594 {
595 auto* optics = new G4AssemblyVolume();
597
598 const double Lm = geo.getMirrorSegment().getFullLength();
599 const double L1 = geo.getBarSegment1().getFullLength();
600 const double L2 = geo.getBarSegment2().getFullLength();
601 const double Lp = geo.getPrism().getFullLength();
602 const double La = geo.getPMTArray().getSizeZ();
603
604 // note: z = 0 is at prism-bar joint
605
606 auto* pmtArray = createPMTArray(geo.getPMTArray(), geo.getModuleID());
607 double Dy = (geo.getPrism().getThickness() - geo.getPrism().getExitThickness()) / 2;
608 G4ThreeVector moveArray(geo.getPMTArrayDisplacement().getX(),
609 geo.getPMTArrayDisplacement().getY() + Dy,
610 -(Lp + La / 2));
611 G4RotationMatrix rotArray;
612 rotArray.rotateZ(geo.getPMTArrayDisplacement().getAlpha());
613 optics->AddPlacedVolume(pmtArray, moveArray, &rotArray);
614
615 G4ThreeVector move;
616 G4RotationMatrix rot;
617
618 auto* prism = createPrism(geo.getPrism(), geo.getModuleID());
619 move.setZ(0);
620 rot.rotateY(M_PI / 2);
621 optics->AddPlacedVolume(prism, move, &rot);
622
623 auto* barSegment2 = createBarSegment(geo.getBarSegment2(), geo.getModuleID());
624 move.setZ(L2 / 2);
625 optics->AddPlacedVolume(barSegment2, move, 0);
626
627 auto* barSegment1 = createBarSegment(geo.getBarSegment1(), geo.getModuleID());
628 move.setZ(L2 + L1 / 2);
629 optics->AddPlacedVolume(barSegment1, move, 0);
630
631 auto* mirrorSegment = createMirrorSegment(geo.getMirrorSegment(),
632 geo.getModuleID());
633 move.setZ(L2 + L1 + Lm / 2);
634 optics->AddPlacedVolume(mirrorSegment, move, 0);
635
636 // peek frame approximation (in order to shadow total reflection at prism end)
637 // a call to getFilterThickness is added for backward compatibility
638 const double length = geo.getPrism().getFilterThickness() + 3.5; //mm
639 const double thickness = 1.0; //mm
640 const double width = geo.getPrism().getWidth();
641 const double Yup = geo.getPrism().getThickness() / 2;
642 const double Ydn = Yup - geo.getPrism().getExitThickness();
643
644 auto* peekFrameAbove = createBox("PeekFrameAbove", width, thickness, length, "Al");
645 move.setZ(-(Lp - length / 2));
646 move.setY(Yup + thickness / 2);
647 optics->AddPlacedVolume(peekFrameAbove, move, 0);
648
649 auto* peekFrameBelow = createBox("PeekFrameBelow", width, thickness, length, "Al");
650 move.setZ(-(Lp - length / 2));
651 move.setY(Ydn - thickness / 2);
652 optics->AddPlacedVolume(peekFrameBelow, move, 0);
653
654 return optics;
655 }
G4LogicalVolume * createPMTArray(const TOPGeoPMTArray &geo, int moduleID)
Creates PMT array.
G4LogicalVolume * createMirrorSegment(const TOPGeoMirrorSegment &geo, int moduleID)
Creates quartz segment with spherical mirror.
G4LogicalVolume * createBarSegment(const TOPGeoBarSegment &geo, int moduleID)
Creates quartz bar segment.
G4LogicalVolume * createPrism(const TOPGeoPrism &geo, int moduleID)
Creates quartz prism.

◆ assembleQBB()

G4AssemblyVolume * assembleQBB ( const TOPGeoQBB geo)
private

Assembles QBB.

Parameters
geogeometry description
Returns
assembly volume

Definition at line 373 of file GeoTOPCreator.cc.

374 {
375 auto* qbb = new G4AssemblyVolume();
377
378 double Zback = -geo.getPrismEnclosure().getLength() / 2;
379 double Zfront = Zback + geo.getLength() - geo.getForwardEndPlate().getThickness();
380
381 G4ThreeVector move;
382
383 // outer panel
384
385 auto* outerPanel = createHoneycombPanel(geo, c_Outer);
386 move.setZ(Zfront - geo.getOuterPanel().getLength() / 2);
387 qbb->AddPlacedVolume(outerPanel, move, 0);
388
389 // inner panel
390
391 auto* innerPanel = createHoneycombPanel(geo, c_Inner);
392 move.setZ(Zfront - geo.getInnerPanel().getLength() / 2);
393 qbb->AddPlacedVolume(innerPanel, move, 0);
394
395 // forward end plate
396
397 double length = geo.getForwardEndPlate().getThickness();
398 auto* forwardEndPlate = createBox(geo.getForwardEndPlate().getName(),
399 geo.getWidth(),
400 geo.getForwardEndPlate().getHeight(),
401 length,
402 geo.getForwardEndPlate().getMaterial());
403 move.setZ(Zfront + length / 2);
404 qbb->AddPlacedVolume(forwardEndPlate, move, 0);
405
406 // prism enclosure box
407
408 std::string name = geo.getPrismEnclosure().getName();
409 double Z = Zback;
410 length = geo.getPrismEnclosure().getBackThickness();
411 auto* backPlate = createExtrudedSolid(name + "BackPlate",
412 geo.getBackPlateContour(),
413 length,
414 geo.getPrismEnclosure().getMaterial());
415 move.setZ(Z + length / 2);
416 qbb->AddPlacedVolume(backPlate, move, 0);
417 Z += length;
418
419 length = geo.getPrismEnclosure().getBodyLength();
420 auto* prismEnclosure = createExtrudedSolid(name + "Body",
421 geo.getPrismEnclosureContour(),
422 length,
423 geo.getPrismEnclosure().getMaterial());
424 move.setZ(Z + length / 2);
425 qbb->AddPlacedVolume(prismEnclosure, move, 0);
426 Z += length;
427
428 length = geo.getPrismEnclosure().getFrontThickness();
429 auto* frontPlate = createExtrudedSolid(name + "FrontPlate",
430 geo.getFrontPlateContour(),
431 length,
432 geo.getPrismEnclosure().getMaterial());
433 move.setZ(Z + length / 2);
434 qbb->AddPlacedVolume(frontPlate, move, 0);
435 Z += length;
436
437 length = Zfront - Z - geo.getInnerPanel().getLength();
438 if (length > 0) {
439 double height = geo.getPrismEnclosure().getExtensionThickness();
440 auto* extPlate = createBox(name + "ExtensionPlate",
441 geo.getPanelWidth(),
442 height,
443 length,
444 geo.getPrismEnclosure().getMaterial());
445
446 G4ThreeVector movePlate;
447 movePlate.setZ(Z + length / 2);
448 movePlate.setY((height - geo.getSideRails().getHeight()) / 2);
449 qbb->AddPlacedVolume(extPlate, movePlate, 0);
450 }
451
452 // side rails
453
454 auto* leftRail = createSideRail(geo, c_Left);
455 move.setZ(Zfront - geo.getSideRailsLength() / 2);
456 move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() -
457 geo.getSideRails().getHeight() / 2);
458 move.setX(-(geo.getWidth() - geo.getSideRails().getThickness()) / 2);
459 qbb->AddPlacedVolume(leftRail, move, 0);
460
461 auto* rightRail = createSideRail(geo, c_Right);
462 move.setX((geo.getWidth() - geo.getSideRails().getThickness()) / 2);
463 qbb->AddPlacedVolume(rightRail, move, 0);
464
465 // cold plate
466
467 length = geo.getLength() - geo.getPrismEnclosure().getBackThickness() -
468 geo.getOuterPanel().getLength() - geo.getForwardEndPlate().getThickness();
469 auto* coldPlateBase = createBox(geo.getColdPlate().getName() + "Base",
470 geo.getPanelWidth(),
471 geo.getColdPlate().getBaseThickness(),
472 length,
473 geo.getColdPlate().getBaseMaterial());
474 move.setZ(Zback + geo.getPrismEnclosure().getBackThickness() + length / 2);
475 move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() -
476 geo.getColdPlate().getBaseThickness() / 2);
477 move.setX(0);
478 qbb->AddPlacedVolume(coldPlateBase, move, 0);
479
480 auto* coldPlateCool = createBox(geo.getColdPlate().getName() + "Cooler",
481 geo.getColdPlate().getCoolWidth(),
482 geo.getColdPlate().getCoolThickness(),
483 length,
484 geo.getColdPlate().getCoolMaterial());
485 move.setY(geo.getOuterPanel().getY() + geo.getOuterPanel().getMinThickness() +
486 geo.getColdPlate().getCoolThickness() / 2);
487 qbb->AddPlacedVolume(coldPlateCool, move, 0);
488
489 return qbb;
490 }
G4LogicalVolume * createSideRail(const TOPGeoQBB &geo, ESideRailType type)
Creates side rail.
G4LogicalVolume * createHoneycombPanel(const TOPGeoQBB &geo, EPanelType type)
Creates honeycomb panel.
G4LogicalVolume * createExtrudedSolid(const std::string &name, const Polygon &shape, double length, const std::string &materialName)
Creates material extruded solid.

◆ create()

void create ( const GearDir content,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
overridevirtual

Creation of the detector geometry from Gearbox (XML).

Parameters
[in]contentXML data directory.
[in]topVolumeGeant world volume.
[in]typeGeometry type.

Implements CreatorBase.

Definition at line 80 of file GeoTOPCreator.cc.

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 }
void createGeometry(const TOPGeometry &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create the geometry from a parameter object.
TOPGeometryPar * m_topgp
singleton class
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
bool isValid() const
check if the geometry is available
void Initialize(const GearDir &content)
Initialize from Gearbox (XML)

◆ createBarSegment()

G4LogicalVolume * createBarSegment ( const TOPGeoBarSegment geo,
int  moduleID 
)
private

Creates quartz bar segment.

Parameters
geogeometry description
moduleIDmodule ID (e.g. slot number)
Returns
logical volume of bar segment

Definition at line 658 of file GeoTOPCreator.cc.

660 {
661 G4Transform3D move;
662
663 // mother volume
664 auto* bar = createBox(geo.getName(),
665 geo.getWidth(), geo.getThickness(), geo.getFullLength(),
666 geo.getMaterial());
667 // glue
668 auto* glue = createBox(geo.getName() + "Glue",
669 geo.getWidth(), geo.getThickness(), geo.getGlueThickness(),
670 geo.getGlueMaterial());
671 if (geo.getBrokenGlueFraction() > 0) {
672 auto* brokenGlue = createExtrudedSolid(geo.getName() + "BrokenGlue",
673 geo.getBrokenGlueContour(),
674 geo.getGlueThickness(),
675 geo.getBrokenGlueMaterial());
676 G4Transform3D fix;
677 new G4PVPlacement(fix, brokenGlue, geo.getName() + "BrokenGlue", glue, false, 1);
678 B2RESULT("GeoTOPCreator, broken glue at " << geo.getName()
679 << addNumber(" of Slot", moduleID));
681 }
682
683 // place glue to -z side
684 move = G4TranslateZ3D(-(geo.getFullLength() - geo.getGlueThickness()) / 2);
685 new G4PVPlacement(move, glue, geo.getName() + "Glue", bar, false, 1);
686
687 // optical surface
688 auto& materials = Materials::getInstance();
689 auto* optSurf = materials.createOpticalSurface(geo.getSurface());
690 optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
691 new G4LogicalSkinSurface("opticalSurface", bar, optSurf);
692
693 // Activate sensitive volume
694 bar->SetSensitiveDetector(m_sensitiveBar);
695
696 return bar;
697 }
int m_numBrokenGlues
number of broken glues
std::string addNumber(const std::string &str, unsigned number)
Adds number to string.
static Materials & getInstance()
Get a reference to the singleton instance.
Definition: Materials.cc:85

◆ createBoardStack()

G4LogicalVolume * createBoardStack ( const TOPGeoFrontEnd geo,
int  N 
)
private

Creates board stack.

Parameters
geogeometry description
Nnumber of board stacks per module
Returns
logical volume

Definition at line 331 of file GeoTOPCreator.cc.

332 {
333 double width = geo.getBoardStackWidth();
334 double fullWidth = width * N;
335 std::string name = "TOPBoardStack";
336 auto* boardStack = createBox(name,
337 fullWidth,
338 geo.getBoardStackHeight(),
339 geo.getBoardStackLength(),
340 geo.getBoardStackMaterial());
341
342 double spacerWidth = geo.getSpacerWidth();
343 std::string name1 = name + "Spacer";
344 auto* spacer = createBox(name1,
345 spacerWidth,
346 geo.getBoardStackHeight(),
347 geo.getBoardStackLength(),
348 geo.getSpacerMaterial());
349
350 std::string name2 = name + "TwoSpacers";
351 auto* twoSpacers = createBox(name2,
352 spacerWidth * 2,
353 geo.getBoardStackHeight(),
354 geo.getBoardStackLength(),
355 geo.getSpacerMaterial());
356
357 G4Transform3D move;
358 move = G4TranslateX3D(-(fullWidth - spacerWidth) / 2);
359 new G4PVPlacement(move, spacer, name1, boardStack, false, 1);
360 move = G4TranslateX3D((fullWidth - spacerWidth) / 2);
361 new G4PVPlacement(move, spacer, name1, boardStack, false, 2);
362
363 int n = N - 1;
364 for (int i = 0; i < n; i++) {
365 move = G4TranslateX3D(width * (2 * i - n + 1) / 2.0);
366 new G4PVPlacement(move, twoSpacers, name2, boardStack, false, i + 1);
367 }
368
369 return boardStack;
370 }

◆ createBox()

G4LogicalVolume * createBox ( const std::string &  name,
double  A,
double  B,
double  C,
const std::string &  materialName 
)
private

Creates material box.

Parameters
namevolume name
Abox x size
Bbox y size
Cbox z size
materialNamematerial name
Returns
logical volume

Definition at line 982 of file GeoTOPCreator.cc.

985 {
986 G4Box* box = new G4Box(name, A / 2, B / 2, C / 2);
987 G4Material* material = Materials::get(materialName);
988 if (!material) B2FATAL("Material '" << materialName << "' not found");
989 return new G4LogicalVolume(box, material, name);
990 }
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63

◆ createBoxSphereIntersection()

G4LogicalVolume * createBoxSphereIntersection ( const std::string &  name,
G4Box *  box,
double  Rmin,
double  Rmax,
double  xc,
double  yc,
double  zc,
const std::string &  materialName 
)
private

Creates material volume that is intersection of box and half-sphere shell (z > 0)

Parameters
namevolume name
boxbox shape
Rminminimal radius of sphere shell
Rmaxmaximal radius of sphere shell
xccenter of a sphere in x
yccenter of a sphere in y
zccenter of a sphere in z
materialNamematerial name
Returns
logical volume

Definition at line 994 of file GeoTOPCreator.cc.

1002 {
1003 // determine max theta - note: not valid generically!
1004 double x = box->GetXHalfLength();
1005 double y = box->GetYHalfLength();
1006 double z = box->GetZHalfLength();
1007 double dx = fmax(fabs(-x - xc), fabs(x - xc));
1008 double dy = fmax(fabs(-y - yc), fabs(y - yc));
1009 double dz = fmin(-z - zc, z - zc);
1010 double theta = atan(sqrt(dx * dx + dy * dy) / dz);
1011
1012 auto* sphere = new G4Sphere(name + "Sphere",
1013 Rmin, Rmax, 0, 2 * M_PI, 0, theta);
1014 G4Translate3D move(xc, yc, zc);
1015 auto* shape = new G4IntersectionSolid(name, box, sphere, move);
1016
1017 G4Material* material = Materials::get(materialName);
1018 if (!material) B2FATAL("Material '" << materialName << "' not found");
1019 return new G4LogicalVolume(shape, material, name);
1020 }
double atan(double a)
atan for double
Definition: beamHelpers.h:34
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28

◆ createExtrudedSolid()

G4LogicalVolume * createExtrudedSolid ( const std::string &  name,
const Polygon &  shape,
double  length,
const std::string &  materialName 
)
private

Creates material extruded solid.

Parameters
namevolume name
shapex-y shape of extruded solid
lengthlength in z
materialNamematerial name
Returns
logical volume

Definition at line 1023 of file GeoTOPCreator.cc.

1027 {
1028 std::vector<G4TwoVector> polygon;
1029 for (auto& point : shape) {
1030 polygon.push_back(G4TwoVector(point.first, point.second));
1031 }
1032 G4ExtrudedSolid* solid = new G4ExtrudedSolid(name, polygon, length / 2,
1033 G4TwoVector(), 1, G4TwoVector(), 1);
1034 G4Material* material = Materials::get(materialName);
1035 if (!material) B2FATAL("Material '" << materialName << "' not found");
1036 return new G4LogicalVolume(solid, material, name);
1037 }

◆ createFromDB()

void createFromDB ( const std::string &  name,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
overridevirtual

Creation of the detector geometry from database.

Parameters
[in]nameName of the component in the database.
[in]topVolumeGeant world volume.
[in]typeGeometry type.

Reimplemented from CreatorBase.

Definition at line 120 of file GeoTOPCreator.cc.

122 {
123
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 }

◆ createGeometry()

void createGeometry ( const TOPGeometry parameters,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
private

Create the geometry from a parameter object.

Definition at line 137 of file GeoTOPCreator.cc.

140 {
141 m_sensitivePMT = new SensitivePMT();
142 m_sensitiveBar = new SensitiveBar();
143
146
147 geo.useGeantUnits();
148
149 double backwardLength = geo.getQBB().getPrismEnclosure().getLength();
150 double prismPosition = geo.getQBB().getPrismPosition();
151
152 G4Region* aRegion = 0;
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 if (not aRegion) aRegion = new G4Region("TOPEnvelope"); // allocation moved inside the loop to prevent memory leak warning
187 module->SetRegion(aRegion);
188 aRegion->AddRootLogicalVolume(module);
189
190 new G4PVPlacement(T, module, name, &topVolume, false, moduleID);
191 }
192
193 if (m_numDecoupledPMTs > 0) B2WARNING("GeoTOPCreator, " << m_numDecoupledPMTs
194 << " PMT's are optically decoupled");
195 if (m_numBrokenGlues > 0) B2WARNING("GeoTOPCreator, " << m_numBrokenGlues
196 << " broken glues");
197 if (m_numPeelOffRegions > 0) B2WARNING("GeoTOPCreator, " << m_numPeelOffRegions
198 << " peel-off cookie regions");
199 }
int m_numPeelOffRegions
number of peel-off regions
int m_numDecoupledPMTs
number of optically decoupled PMT's
G4LogicalVolume * createModule(const TOPGeometry &geo, int moduleID)
Creates single module.
void setReplicaDepth(int depth)
Sets replica depth of module volume.
Definition: SensitiveBar.h:51
void setModuleReplicaDepth(int depth)
Sets replica depth of module volume.
Definition: SensitivePMT.h:56

◆ createHoneycombPanel()

G4LogicalVolume * createHoneycombPanel ( const TOPGeoQBB geo,
EPanelType  type 
)
private

Creates honeycomb panel.

Parameters
geogeometry description
typepanel type
Returns
logical volume

Definition at line 493 of file GeoTOPCreator.cc.

495 {
496 G4Transform3D move;
497
498 TOPGeoHoneycombPanel geoPanel;
499 Polygon contour;
500 double sideEdgeHeight = 0;
501 double sideEdgeY = 0;
502
503 if (type == c_Inner) {
504 geoPanel = geo.getInnerPanel();
505 contour = geo.getInnerPanelContour();
506 sideEdgeHeight = geoPanel.getMaxThickness();
507 sideEdgeY = geoPanel.getY() - sideEdgeHeight / 2;
508 } else {
509 geoPanel = geo.getOuterPanel();
510 contour = geo.getOuterPanelContour();
511 sideEdgeHeight = geoPanel.getMinThickness();
512 sideEdgeY = geoPanel.getY() + sideEdgeHeight / 2;
513 }
514
515 // honeycomb panel
516
517 auto* panel = createExtrudedSolid(geoPanel.getName(),
518 contour,
519 geoPanel.getLength(),
520 geoPanel.getMaterial());
521
522 // reinforced faces
523
524 std::string faceEdgeName = geoPanel.getName() + "ReinforcedFace";
525 auto* faceEdge = createExtrudedSolid(faceEdgeName,
526 contour,
527 geoPanel.getEdgeWidth(),
528 geoPanel.getEdgeMaterial());
529
530 move = G4TranslateZ3D((geoPanel.getLength() - geoPanel.getEdgeWidth()) / 2);
531 new G4PVPlacement(move, faceEdge, faceEdgeName, panel, false, 1);
532 move = G4TranslateZ3D(-(geoPanel.getLength() - geoPanel.getEdgeWidth()) / 2);
533 new G4PVPlacement(move, faceEdge, faceEdgeName, panel, false, 2);
534
535 // reinforced sides
536
537 double width = geo.getPanelWidth();
538 double sideEdgeWidth = geoPanel.getEdgeWidth() + (width - geoPanel.getWidth()) / 2;
539 std::string sideEdgeName = geoPanel.getName() + "ReinforcedSide";
540 auto* sideEdge = createBox(sideEdgeName,
541 sideEdgeWidth,
542 sideEdgeHeight,
543 geoPanel.getLength() - 2 * geoPanel.getEdgeWidth(),
544 geoPanel.getEdgeMaterial());
545
546
547 move = G4Translate3D((width - sideEdgeWidth) / 2, sideEdgeY, 0);
548 new G4PVPlacement(move, sideEdge, sideEdgeName, panel, false, 1);
549 move = G4Translate3D(-(width - sideEdgeWidth) / 2, sideEdgeY, 0);
550 new G4PVPlacement(move, sideEdge, sideEdgeName, panel, false, 2);
551
552 return panel;
553 }

◆ createMirrorSegment()

G4LogicalVolume * createMirrorSegment ( const TOPGeoMirrorSegment geo,
int  moduleID 
)
private

Creates quartz segment with spherical mirror.

Parameters
geogeometry description
moduleIDmodule ID (e.g. slot number)
Returns
logical volume of mirror segment

Definition at line 700 of file GeoTOPCreator.cc.

702 {
703 G4Transform3D move;
704
705 // box of the bar
706 auto* box = new G4Box(geo.getName(),
707 geo.getWidth() / 2, geo.getThickness() / 2,
708 geo.getFullLength() / 2);
709
710 // mother volume
711 auto* bar = createBoxSphereIntersection(geo.getName(),
712 box,
713 0, geo.getOuterRadius(),
714 geo.getXc(), geo.getYc(), geo.getZc(),
715 geo.getMaterial());
716
717 // glue
718 auto* glue = createBox(geo.getName() + "Glue",
719 geo.getWidth(), geo.getThickness(), geo.getGlueThickness(),
720 geo.getGlueMaterial());
721 if (geo.getBrokenGlueFraction() > 0) {
722 auto* brokenGlue = createExtrudedSolid(geo.getName() + "BrokenGlue",
723 geo.getBrokenGlueContour(),
724 geo.getGlueThickness(),
725 geo.getBrokenGlueMaterial());
726 G4Transform3D fix;
727 new G4PVPlacement(fix, brokenGlue, geo.getName() + "BrokenGlue", glue, false, 1);
728 B2RESULT("GeoTOPCreator, broken glue at " << geo.getName()
729 << addNumber(" of Slot", moduleID));
731 }
732
733 // place glue to -z side
734 move = G4TranslateZ3D(-(geo.getFullLength() - geo.getGlueThickness()) / 2);
735 new G4PVPlacement(move, glue, geo.getName() + "Glue", bar, false, 1);
736
737 // bar optical surface
738 auto& materials = Materials::getInstance();
739 auto* optSurf = materials.createOpticalSurface(geo.getSurface());
740 optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
741 new G4LogicalSkinSurface("opticalSurface", bar, optSurf);
742
743 // mirror reflective coating
744 auto* mirror = createBoxSphereIntersection(geo.getName() + "ReflectiveCoating",
745 box,
746 geo.getRadius(), geo.getOuterRadius(),
747 geo.getXc(), geo.getYc(), geo.getZc(),
748 geo.getCoatingMaterial());
749
750 // mirror optical surface
751 auto* mirrorSurf = materials.createOpticalSurface(geo.getCoatingSurface());
752 new G4LogicalSkinSurface("mirrorSurface", mirror, mirrorSurf);
753
754 // place reflective coating
755 move = G4TranslateZ3D(0);
756 new G4PVPlacement(move, mirror, geo.getName() + "ReflectiveCoating", bar, false, 1);
757
758 // Activate sensitive volume
759 bar->SetSensitiveDetector(m_sensitiveBar);
760
761 return bar;
762 }
G4LogicalVolume * createBoxSphereIntersection(const std::string &name, G4Box *box, double Rmin, double Rmax, double xc, double yc, double zc, const std::string &materialName)
Creates material volume that is intersection of box and half-sphere shell (z > 0)

◆ createModule()

G4LogicalVolume * createModule ( const TOPGeometry geo,
int  moduleID 
)
private

Creates single module.

Parameters
geogeometry description
moduleIDmodule ID (slot number)
Returns
logical volume

Definition at line 202 of file GeoTOPCreator.cc.

203 {
204 // note: z = 0 is at center of backward envelope
205
206 G4ThreeVector move;
207 G4RotationMatrix rot;
208
209 // create module envelope volume
210
211 const auto& geoQBB = geo.getQBB();
212 auto* module = createModuleEnvelope(geoQBB, moduleID);
213
214 // add quartz optics together with PMT array
215
216 const auto& geoModule = geo.getModule(moduleID);
217 auto* optics = assembleOptics(geoModule);
218
219 move.setZ(geoQBB.getPrismPosition() - geoQBB.getPrismEnclosure().getLength() / 2);
220 optics->MakeImprint(module, move, &rot);
221
222 // add front-end electronics
223
224 if (!m_frontEnd) {
225 m_frontEnd = assembleFrontEnd(geo.getFrontEnd(), geo.getNumBoardStacks());
226 }
227 double Lprism = geoModule.getPrism().getFullLength();
228 double Larray = geoModule.getPMTArray().getSizeZ();
229 move.setZ(move.z() - Lprism - Larray);
230 m_frontEnd->MakeImprint(module, move, &rot);
231
232 // add QBB
233
234 if (!m_qbb) m_qbb = assembleQBB(geoQBB);
235 move.setZ(0);
236 m_qbb->MakeImprint(module, move, &rot);
237
238 return module;
239 }
G4AssemblyVolume * assembleFrontEnd(const TOPGeoFrontEnd &geo, int N)
Assembles front-end electronics.
G4AssemblyVolume * assembleQBB(const TOPGeoQBB &geo)
Assembles QBB.
G4AssemblyVolume * m_frontEnd
front-end electronics assembly volume
G4AssemblyVolume * m_qbb
QBB assembly volume.
G4AssemblyVolume * assembleOptics(const TOPGeoModule &geo)
Assembles optical components (PMT array, prism and bar segments) along z.
G4LogicalVolume * createModuleEnvelope(const TOPGeoQBB &geo, int moduleID)
Creates module envelope.

◆ createModuleEnvelope()

G4LogicalVolume * createModuleEnvelope ( const TOPGeoQBB geo,
int  moduleID 
)
private

Creates module envelope.

Parameters
geogeometry description
moduleIDmodule ID (slot number)
Returns
logical volume

Definition at line 242 of file GeoTOPCreator.cc.

244 {
245 // note: z = 0 is at center of backward envelope
246
247 if (!m_moduleEnvelope) {
248 double backwardLength = geo.getPrismEnclosure().getLength();
249 double forwardLength = geo.getLength() - backwardLength;
250 std::vector<G4TwoVector> polygon;
251 for (auto& point : geo.getBackwardContour()) {
252 polygon.push_back(G4TwoVector(point.first, point.second));
253 }
254 auto* backward = new G4ExtrudedSolid("backwardEnvelope",
255 polygon, backwardLength / 2,
256 G4TwoVector(), 1, G4TwoVector(), 1);
257 polygon.clear();
258 for (auto& point : geo.getForwardContour()) {
259 polygon.push_back(G4TwoVector(point.first, point.second));
260 }
261 auto* forward = new G4ExtrudedSolid("forwardEnvelope",
262 polygon, forwardLength / 2,
263 G4TwoVector(), 1, G4TwoVector(), 1);
264
265 G4Transform3D move = G4TranslateZ3D((backwardLength + forwardLength) / 2);
266 m_moduleEnvelope = new G4UnionSolid("moduleEnvelope", backward, forward, move);
267 }
268
269 G4Material* material = Materials::get(geo.getMaterial());
270 if (!material) B2FATAL("Material '" << geo.getMaterial() << "' not found");
271
272 std::string name = addNumber("TOPEnvelopeModule", moduleID);
273 return new G4LogicalVolume(m_moduleEnvelope, material, name);
274
275 }
G4UnionSolid * m_moduleEnvelope
module envelope solid

◆ createPayloads()

void createPayloads ( const GearDir content,
const IntervalOfValidity iov 
)
overridevirtual

Creation of payloads.

Parameters
contentXML data directory.
iovInterval of validity.

Reimplemented from CreatorBase.

Definition at line 98 of file GeoTOPCreator.cc.

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
114
115 B2RESULT("TOP: geometry and mappers imported to database");
116
117 }
void importPayload(const IntervalOfValidity &iov) const
import mappings to database
void importPayload(const IntervalOfValidity &iov) const
import mappings to database
const ChannelMapper & getChannelMapper() const
Returns default channel mapper (mapping of channels to pixels)
const FrontEndMapper & getFrontEndMapper() const
Returns front-end mapper (mapping of SCROD's to positions within TOP modules)

◆ createPMT()

G4LogicalVolume * createPMT ( const TOPGeoPMT geo)
private

Creates single PMT.

Parameters
geogeometry description
Returns
logical volume of one PMT

Definition at line 905 of file GeoTOPCreator.cc.

906 {
907 G4Transform3D move;
908
909 // mother volume
910 auto* pmt = createBox(geo.getName(),
911 geo.getSizeX(), geo.getSizeY(), geo.getSizeZ(),
912 geo.getWallMaterial());
913
914 // window + photocathode + reflective edge
915 double winThickness = geo.getWinThickness() + geo.getReflEdgeThickness();
916 auto* window = createBox(geo.getName() + "Window",
917 geo.getSizeX(), geo.getSizeY(),
918 winThickness,
919 geo.getWinMaterial());
920 auto* photoCathode = createBox(geo.getName() + "PhotoCathode",
921 geo.getSensSizeX(), geo.getSensSizeY(),
922 geo.getSensThickness(),
923 geo.getSensMaterial());
924 photoCathode->SetSensitiveDetector(m_sensitivePMT); // Activate sensitive area
925
926 move = G4TranslateZ3D(-(winThickness - geo.getSensThickness()) / 2
927 + geo.getReflEdgeThickness());
928 new G4PVPlacement(move, photoCathode, geo.getName() + "PhotoCathode", window,
929 false, 1);
930
931 auto* reflEdge = createBox(geo.getName() + "ReflectiveEdge",
932 geo.getSizeX(), geo.getSizeY(),
933 geo.getReflEdgeThickness(),
934 geo.getWallMaterial());
935 double holeSizeX = geo.getSizeX() - 2 * geo.getReflEdgeWidth();
936 double holeSizeY = geo.getSizeY() - 2 * geo.getReflEdgeWidth();
937 if (holeSizeX > 0 and holeSizeY > 0) {
938 auto* hole = createBox(geo.getName() + "ReflectiveEdgeHole",
939 holeSizeX, holeSizeY,
940 geo.getReflEdgeThickness(),
941 geo.getFillMaterial());
942 move = G4TranslateZ3D(0.0);
943 new G4PVPlacement(move, hole, geo.getName() + "ReflectiveEdgeHole", reflEdge,
944 false, 1);
945 }
946
947 auto& materials = Materials::getInstance();
948 auto* optSurf = materials.createOpticalSurface(geo.getReflEdgeSurface());
949 new G4LogicalSkinSurface("reflectiveEdgeSurface", reflEdge, optSurf);
950
951 move = G4TranslateZ3D(-(winThickness - geo.getReflEdgeThickness()) / 2);
952 new G4PVPlacement(move, reflEdge, geo.getName() + "ReflectiveEdge", window,
953 false, 1);
954
955 move = G4TranslateZ3D((geo.getSizeZ() - winThickness) / 2);
956 new G4PVPlacement(move, window, geo.getName() + "Window", pmt, false, 1);
957
958 // bottom
959 if (geo.getBotMaterial() != geo.getWallMaterial()) {
960 auto* bottom = createBox(geo.getName() + "Bottom",
961 geo.getSizeX(), geo.getSizeY(), geo.getBotThickness(),
962 geo.getBotMaterial());
963 move = G4TranslateZ3D(-(geo.getSizeZ() - geo.getBotThickness()) / 2);
964 new G4PVPlacement(move, bottom, geo.getName() + "Bottom", pmt, false, 1);
965 }
966
967 // interior
968 double interiorSizeZ = geo.getSizeZ() - winThickness - geo.getBotThickness();
969 auto* interior = createBox(geo.getName() + "Interior",
970 geo.getSizeX() - 2 * geo.getWallThickness(),
971 geo.getSizeY() - 2 * geo.getWallThickness(),
972 interiorSizeZ,
973 geo.getBotMaterial());
974 move = G4TranslateZ3D(-(geo.getSizeZ() - interiorSizeZ) / 2
975 + geo.getBotThickness());
976 new G4PVPlacement(move, interior, geo.getName() + "Interior", pmt, false, 1);
977
978 return pmt;
979 }

◆ createPMTArray()

G4LogicalVolume * createPMTArray ( const TOPGeoPMTArray geo,
int  moduleID 
)
private

Creates PMT array.

Parameters
geogeometry description
moduleIDmodule ID (e.g. slot number)
Returns
logical volume of PMT array

Definition at line 849 of file GeoTOPCreator.cc.

851 {
852 // mother volume
853 auto* pmtArray = createBox(geo.getName(),
854 geo.getSizeX(), geo.getSizeY(),
855 geo.getSizeZ(),
856 geo.getMaterial());
857
858 // single PMT
859 auto* pmt = createPMT(geo.getPMT());
860
861 // place PMT's
862 std::string message = addNumber("optically decoupled PMT's of Slot", moduleID) + ":";
863 for (unsigned row = 1; row <= geo.getNumRows(); row++) {
864 for (unsigned col = 1; col <= geo.getNumColumns(); col++) {
865 auto id = geo.getPmtID(row, col);
866 double z = geo.getAirGap();
867 if (geo.isPMTDecoupled(id)) {
868 z = 0;
869 message += addNumber(" ", id);
871 }
872 z -= (geo.getSizeZ() - geo.getPMT().getSizeZ()) / 2;
873 G4Transform3D move = G4Translate3D(geo.getX(col), geo.getY(row), z);
874 new G4PVPlacement(move, pmt, addNumber(geo.getPMT().getName(), id), pmtArray,
875 false, id);
876 }
877 }
878
879 // wavelenght filter and silicone cookies (new payload)
880 if (geo.getFilterThickness() > 0) { // new payload
881 double fullThickness = geo.getFilterThickness() + geo.getCookieThickness();
882 auto* filter = createBox(geo.getName() + "Filter+Cookie",
883 geo.getSizeX(), geo.getSizeY(),
884 fullThickness,
885 geo.getFilterMaterial());
886 double cookieThickness = geo.getCookieThickness();
887 auto* cookie = createBox(geo.getName() + "Cookie",
888 geo.getSizeX(), geo.getSizeY(),
889 cookieThickness,
890 geo.getCookieMaterial());
891 G4Transform3D move = G4Translate3D(0, 0, (fullThickness - cookieThickness) / 2);
892 new G4PVPlacement(move, cookie, geo.getName() + "Cookie", filter, false, 1);
893
894 move = G4Translate3D(0, 0, (geo.getSizeZ() - fullThickness) / 2);
895 new G4PVPlacement(move, filter, geo.getName() + "Filter+Cookie", pmtArray,
896 false, 1);
897 }
898
899 if (!geo.getDecoupledPMTs().empty()) B2RESULT("GeoTOPCreator, " << message);
900
901 return pmtArray;
902 }
G4LogicalVolume * createPMT(const TOPGeoPMT &geo)
Creates single PMT.
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

◆ createPrism()

G4LogicalVolume * createPrism ( const TOPGeoPrism geo,
int  moduleID 
)
private

Creates quartz prism.

Parameters
geogeometry description
moduleIDmodule ID (e.g. slot number)
Returns
logical volume of prism

Definition at line 765 of file GeoTOPCreator.cc.

767 {
768 G4Transform3D move;
769
770 // mother volume
771
772 std::vector<G4TwoVector> polygon;
773 polygon.push_back(G4TwoVector(0, geo.getThickness() / 2));
774 polygon.push_back(G4TwoVector(geo.getFullLength(), geo.getThickness() / 2));
775 polygon.push_back(G4TwoVector(geo.getFullLength(),
776 geo.getThickness() / 2 - geo.getExitThickness()));
777 polygon.push_back(G4TwoVector(geo.getLength() - geo.getFlatLength(),
778 geo.getThickness() / 2 - geo.getExitThickness()));
779 polygon.push_back(G4TwoVector(0, -geo.getThickness() / 2));
780
781 auto* volume = new G4ExtrudedSolid(geo.getName(), polygon, geo.getWidth() / 2,
782 G4TwoVector(), 1, G4TwoVector(), 1);
783 G4Material* material = Materials::get(geo.getMaterial());
784 if (!material) B2FATAL("Material '" << geo.getMaterial() << "' not found");
785 auto* prism = new G4LogicalVolume(volume, material, geo.getName());
786
787 // wavelenght filter (old payload) and peel-off regions (if defined)
788 // new payload: wavelength filter is a part of PMT array
789
790 if (geo.getFilterThickness() > 0 or !geo.getPeelOffRegions().empty()) {
791 double filterThickness = geo.getFilterThickness();
792 std::string filterMaterial;
793 if (filterThickness > 0) { // old payload, put wavelength filter into prism
794 filterMaterial = geo.getFilterMaterial();
795 } else { // new payload, make a dummy volume in which to put peel-off regions
796 filterThickness = geo.getPeelOffThickness();
797 filterMaterial = geo.getMaterial();
798 }
799 auto* filter = createBox(geo.getName() + "Filter",
800 filterThickness,
801 geo.getExitThickness(),
802 geo.getWidth(),
803 filterMaterial);
804 // place peel-off regions (if any) into filter
805 int numRegions = 0;
806 std::string message = addNumber("peel-off cookie regions of Slot", moduleID) + ":";
807 for (const auto& region : geo.getPeelOffRegions()) {
808 if (region.fraction <= 0) continue;
809 std::string name = addNumber(geo.getName() + "PeelOff", region.ID);
810 double thickness = geo.getPeelOffThickness();
811 auto* peelOff = createExtrudedSolid(name,
812 geo.getPeelOffContour(region),
813 thickness,
814 geo.getPeelOffMaterial());
815 G4Transform3D T = G4Translate3D((geo.getFilterThickness() - thickness) / 2,
816 0,
817 geo.getPeelOffCenter(region));
818 G4Transform3D R = G4RotateY3D(-M_PI / 2);
819 G4Transform3D moveRegion = T * R;
820 new G4PVPlacement(moveRegion, peelOff, name, filter, false, 1);
821 message += addNumber(" ", region.ID);
822 numRegions++;
823 }
824 if (numRegions > 0) B2RESULT("GeoTOPCreator, " << message);
825 m_numPeelOffRegions += numRegions;
826
827 // place filter to +x side
828 move = G4Translate3D(geo.getFullLength() - geo.getFilterThickness() / 2,
829 (geo.getThickness() - geo.getExitThickness()) / 2,
830 0);
831 new G4PVPlacement(move, filter, geo.getName() + "Filter", prism, false, 1);
832 }
833
834 // optical surface
835
836 auto& materials = Materials::getInstance();
837 auto* optSurf = materials.createOpticalSurface(geo.getSurface());
838 optSurf->SetSigmaAlpha(geo.getSigmaAlpha());
839 new G4LogicalSkinSurface("opticalSurface", prism, optSurf);
840
841 // Activate sensitive volume
842
843 prism->SetSensitiveDetector(m_sensitiveBar);
844
845 return prism;
846 }
double R
typedef autogenerated by FFTW

◆ createSideRail()

G4LogicalVolume * createSideRail ( const TOPGeoQBB geo,
ESideRailType  type 
)
private

Creates side rail.

Parameters
geogeometry description
typeside rail type
Returns
logical volume

Definition at line 556 of file GeoTOPCreator.cc.

558 {
559 double A = geo.getSideRails().getThickness();
560 double B = geo.getSideRails().getHeight();
561 double C = geo.getSideRailsLength();
562 double a = A - geo.getSideRails().getReducedThickness();
563 double b = B - geo.getColdPlate().getBaseThickness();
564 double c = geo.getPrismEnclosure().getLength() -
565 geo.getPrismEnclosure().getBackThickness();
566
567 auto* box = new G4Box("box", A / 2, B / 2, C / 2);
568 auto* subtrBox = new G4Box("subtrBox", a / 2, b / 2, c / 2);
569 double x = 0;
570 if (type == c_Left) {
571 x = (A - a) / 2;
572 } else {
573 x = -(A - a) / 2;
574 }
575 G4Transform3D move = G4Translate3D(x, -(B - b) / 2, -(C - c) / 2);
576 auto* solid = new G4SubtractionSolid("sideRail", box, subtrBox, move);
577
578 G4Material* material = Materials::get(geo.getSideRails().getMaterial());
579 if (!material) B2FATAL("Material '" << geo.getSideRails().getMaterial() <<
580 "' not found");
581
582 std::string name = geo.getSideRails().getName();
583 if (type == c_Left) {
584 name += "Left";
585 } else {
586 name += "Rigth";
587 }
588
589 return new G4LogicalVolume(solid, material, name);
590 }

Member Data Documentation

◆ m_frontEnd

G4AssemblyVolume* m_frontEnd = 0
private

front-end electronics assembly volume

Definition at line 263 of file GeoTOPCreator.h.

◆ m_isBeamBkgStudy

int m_isBeamBkgStudy = 0
private

flag for beam backgound simulation

Definition at line 259 of file GeoTOPCreator.h.

◆ m_moduleEnvelope

G4UnionSolid* m_moduleEnvelope = 0
private

module envelope solid

Definition at line 261 of file GeoTOPCreator.h.

◆ m_numBrokenGlues

int m_numBrokenGlues = 0
private

number of broken glues

Definition at line 266 of file GeoTOPCreator.h.

◆ m_numDecoupledPMTs

int m_numDecoupledPMTs = 0
private

number of optically decoupled PMT's

Definition at line 265 of file GeoTOPCreator.h.

◆ m_numPeelOffRegions

int m_numPeelOffRegions = 0
private

number of peel-off regions

Definition at line 267 of file GeoTOPCreator.h.

◆ m_qbb

G4AssemblyVolume* m_qbb = 0
private

QBB assembly volume.

Definition at line 262 of file GeoTOPCreator.h.

◆ m_sensitiveBar

SensitiveBar* m_sensitiveBar = 0
private

Sensitive vol.

to register particles

Definition at line 255 of file GeoTOPCreator.h.

◆ m_sensitivePCB1

BkgSensitiveDetector* m_sensitivePCB1 = 0
private

PCB sensitive for BG studies.

Definition at line 256 of file GeoTOPCreator.h.

◆ m_sensitivePCB2

BkgSensitiveDetector* m_sensitivePCB2 = 0
private

PCB sensitive for BG studies.

Definition at line 257 of file GeoTOPCreator.h.

◆ m_sensitivePMT

SensitivePMT* m_sensitivePMT = 0
private

Sensitive vol.

to register PMT hits

Definition at line 254 of file GeoTOPCreator.h.

◆ m_topgp

singleton class

Definition at line 258 of file GeoTOPCreator.h.


The documentation for this class was generated from the following files: