Belle II Software development
GeoVXDServiceCreator.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 <vxd/geometry/GeoVXDServiceCreator.h>
10#include <vxd/geometry/GeoVXDComponents.h>
11#include <geometry/CreatorFactory.h>
12#include <geometry/Materials.h>
13#include <simulation/background/BkgSensitiveDetector.h>
14#include <framework/gearbox/GearDir.h>
15#include <framework/logging/Logger.h>
16#include <G4Transform3D.hh>
17#include <G4LogicalVolume.hh>
18#include <G4PVPlacement.hh>
19#include <G4Tubs.hh>
20#include <G4Box.hh>
21#include <map>
22
23namespace Belle2 {
28 using namespace geometry;
29 namespace VXD {
30
33
36 {
37 VXDServiceGeometryPar vxdServiceGeometryPar(content.getBool("RecordBackground", false));
38
39 GearDir content2(content, "DockBoxes");
40
41 // Read parameters to creates boxes
42 for (const GearDir& boxtype : content2.getNodes("BoxType")) {
43 VXDBoxTypesPar boxtypePar(
44 boxtype.getString("@name"),
45 boxtype.getString("material"),
46 boxtype.getInt("@identifier", 0),
47 boxtype.getLength("width"),
48 boxtype.getLength("length"),
49 boxtype.getLength("height")
50 );
51 vxdServiceGeometryPar.getBoxTypes().push_back(boxtypePar);
52 }
53
54 // Read paramater to place boxes
55 for (const GearDir& position : content2.getNodes("Position")) {
56 VXDBoxPositionsPar positionPar(
57 position.getString("@name"),
58 position.getLength("minZ"),
59 position.getLength("maxZ"),
60 position.getLength("minR"),
61 position.getLength("maxR"),
62 position.getInt("divisions")
63 );
64 for (const GearDir& slot : position.getNodes("slots")) {
65 VXDSlotsPar slotsPar(slot.getString("@type"));
66 for (const double number : slot.getArray("")) {
67 slotsPar.getSlotNumbers().push_back(number);
68 }
69 positionPar.getSlots().push_back(slotsPar);
70 }
71 vxdServiceGeometryPar.getPositions().push_back(positionPar);
72 }
73
74 return vxdServiceGeometryPar;
75 }
76
77 void GeoVXDServiceCreator::createGeometry(const VXDServiceGeometryPar& parameters, G4LogicalVolume& topVolume, GeometryTypes)
78 {
79 m_defaultMaterial = topVolume.GetMaterial();
80 bool active = parameters.getRecordBackground();
81
82 // Create the Boxes
83 std::map<std::string, VXDGeoComponent> boxes;
84
85 for (const VXDBoxTypesPar& boxtype : parameters.getBoxTypes()) {
87 boxtype.getMaterial(), "",
88 boxtype.getWidth() / 2.0 / Unit::mm, 0,
89 boxtype.getLength() / 2.0 / Unit::mm,
90 boxtype.getHeight() / 2.0 / Unit::mm);
91 const std::string name = boxtype.getName();
92 G4VSolid* shape_box = new G4Box(name, box.getHeight(), box.getWidth(), box.getLength());
93 box.setVolume(new G4LogicalVolume(shape_box, Materials::get(box.getMaterial()), name));
94 B2DEBUG(50, "Created " << name << " DockBox with a mass of " << (box.getVolume()->GetMass(true) / CLHEP::kg) << "kg");
95 if (active) {
96 int identifier = boxtype.getIdentifier();
97 B2DEBUG(50, "Creating BkgSensitiveDetector for DockBox " << name << " with identifier " << identifier);
98 BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(name.c_str(), identifier);
99 box.getVolume()->SetSensitiveDetector(sensitive);
100 }
101 boxes[name] = box;
102 }
103
104 // Now place the Boxes
105 for (const VXDBoxPositionsPar& position : parameters.getPositions()) {
106 const double minZ = position.getMinZ() / Unit::mm;
107 const double maxZ = position.getMaxZ() / Unit::mm;
108 const double minR = position.getMinR() / Unit::mm;
109 const double maxR = position.getMaxR() / Unit::mm;
110 const int divisions = position.getDivisions();
111 const std::string name = "VXD.DockBoxes." + position.getName();
112
113 //Boxes are aligned to the side closer to the IP so we need the sign in
114 //which to shift
115 const int signZ = minZ < 0 ? -1 : +1;
116 double startPhiAngle = 0;
117 double deltaAngle = 2 * M_PI;
118 if (signZ > 0) {
119 startPhiAngle = 0.35; // Allow space for He3 tubes in forward envelope
120 deltaAngle = 2 * M_PI - startPhiAngle;
121 }
122 G4VSolid* shape_envelope = new G4Tubs(name, minR, maxR, (maxZ - minZ) / 2.0, startPhiAngle, deltaAngle);
123 G4LogicalVolume* envelope = new G4LogicalVolume(shape_envelope, m_defaultMaterial, name);
124 new G4PVPlacement(G4TranslateZ3D((minZ + maxZ) / 2.0), envelope, name, &topVolume, false, 1);
125 //We have divisions slots with always to slots joining at phi=0
126 //As such, the center phi of one slot is 2pi/divisions*(i+0.5);
127 //We start numbering with i=0 as the slot with the smallest phi>0
128 for (const VXDSlotsPar& slot : position.getSlots()) {
129 const std::string type = slot.getType();
130 const VXDGeoComponent& box = boxes[type];
131 if (!box.getVolume()) B2FATAL("Unknown DockBox type: " << type);
132 for (double number : slot.getSlotNumbers()) {
133 const double angle = (2 * M_PI / divisions) * (number + 0.5);
134 //Position boxes as close to beamline as envelope allows
135 const double r = minR + box.getHeight();
136 //Shift the box as close to the IP as the envelope allows
137 const double z = -signZ * ((maxZ - minZ) / 2.0 - box.getLength());
138 const G4Transform3D placement = G4RotateZ3D(angle) * G4Translate3D(r, 0, z);
139 new G4PVPlacement(placement, box.getVolume(), name + ".box", envelope, false, static_cast<int>(number));
140 }
141 }
142 }
143 }
144 } // VXD namespace
146} // Belle2 namespace
The Class for BeamBackground Sensitive Detector.
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
static const double mm
[millimeters]
Definition: Unit.h:70
The Class for VXD doc box envelope.
const std::vector< VXDSlotsPar > & getSlots(void) const
Get slots.
The Class for VXD doc box.
Class holding all parameters for an VXD geometry component.
double getWidth() const
get the width of the component
double & getHeight()
get the height of the component
const std::string & getMaterial() const
get the name of the Material for the component
void setVolume(G4LogicalVolume *volume)
set the pointer to the logical volume
G4LogicalVolume * getVolume() const
get the pointer to the logical volume, NULL if not yet created
double getLength() const
get the length of the component
The Class for VXD service geometry.
const std::vector< VXDBoxPositionsPar > & getPositions(void) const
Get positions.
const std::vector< VXDBoxTypesPar > & getBoxTypes(void) const
Get boxes.
The Class for Slot types.
const std::vector< double > & getSlotNumbers(void) const
Get slot numbers.
void createGeometry(const VXDServiceGeometryPar &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create the geometry from a parameter object.
VXDServiceGeometryPar createConfiguration(const GearDir &param)
Create a parameter object from the Gearbox XML parameters.
G4Material * m_defaultMaterial
Default Material, inherited from topVolume.
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:21
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
geometry::CreatorFactory< GeoVXDServiceCreator > GeoVXDServiceFactory("VXDServiceCreator")
Create factory instance so that the framework can instantiate the VXDServiceCreator.
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
Very simple class to provide an easy way to register creators with the CreatorManager.