Belle II Software development
GeoHeavyMetalShieldCreator.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/GeoHeavyMetalShieldCreator.h>
10
11#include <geometry/Materials.h>
12#include <geometry/CreatorFactory.h>
13#include <geometry/utilities.h>
14#include <framework/gearbox/GearDir.h>
15#include <framework/gearbox/Unit.h>
16#include <framework/logging/Logger.h>
17
18#include <cmath>
19#include <boost/math/special_functions/sign.hpp>
20
21#include <G4LogicalVolume.hh>
22#include <G4PVPlacement.hh>
23#include <G4AssemblyVolume.hh>
24
25// Shapes
26#include <G4Box.hh>
27#include <G4Trd.hh>
28#include <G4Polycone.hh>
29#include <G4SubtractionSolid.hh>
30
31using namespace std;
32
33namespace Belle2 {
39 using namespace geometry;
40
42 namespace VXD {
43
46
48 {
49 HeavyMetalShieldGeometryPar heavyMetalShieldGeometryPar;
50 //Read the definition of all shields
51 for (const GearDir& shield : param.getNodes("Shield")) {
52 VXDPolyConePar shieldPar(
53 shield.getString("@name"),
54 shield.getString("Material", "Air"),
55 shield.getAngle("minPhi", 0),
56 shield.getAngle("maxPhi", 2 * M_PI),
57 (shield.getNodes("Cutout").size() > 0),
58 //shield.getLength("Cutout/width", 0.),
59 shield.getLength("Cutout/width1", 0.),
60 shield.getLength("Cutout/width2", 0.),
61 shield.getLength("Cutout/height", 0.),
62 shield.getLength("Cutout/depth", 0.)
63 );
64
65 for (const GearDir& plane : shield.getNodes("Plane")) {
66 VXDPolyConePlanePar planePar(
67 plane.getLength("posZ"),
68 plane.getLength("innerRadius"),
69 plane.getLength("outerRadius")
70 );
71 shieldPar.getPlanes().push_back(planePar);
72 }
73
74 heavyMetalShieldGeometryPar.getShields().push_back(shieldPar);
75 }
76 return heavyMetalShieldGeometryPar;
77 }
78
79 void GeoHeavyMetalShieldCreator::createGeometry(const HeavyMetalShieldGeometryPar& parameters, G4LogicalVolume& topVolume,
81 {
82
83 // Create the shields
84 for (const VXDPolyConePar& shield : parameters.getShields()) {
85
86 string name = shield.getName();
87 double minZ(0), maxZ(0);
88
89 // Create a polycone
90 double minPhi = shield.getMinPhi();
91 double dPhi = shield.getMaxPhi() - minPhi;
92 int nPlanes = shield.getPlanes().size();
93 if (nPlanes < 2) {
94 B2ERROR("Polycone needs at least two planes");
95 return ;
96 }
97 std::vector<double> z(nPlanes, 0);
98 std::vector<double> rMin(nPlanes, 0);
99 std::vector<double> rMax(nPlanes, 0);
100 int index(0);
101 minZ = numeric_limits<double>::infinity();
102 maxZ = -numeric_limits<double>::infinity();
103
104
105 for (const VXDPolyConePlanePar& plane : shield.getPlanes()) {
106 z[index] = plane.getPosZ() / Unit::mm;
107 minZ = min(minZ, z[index]);
108 maxZ = max(maxZ, z[index]);
109 rMin[index] = plane.getInnerRadius() / Unit::mm;
110 rMax[index] = plane.getOuterRadius() / Unit::mm;
111 ++index;
112 }
113
114 G4VSolid* geoShield = new G4Polycone(name + " IR Shield", minPhi, dPhi, nPlanes, z.data(), rMin.data(), rMax.data());
115
116 // Cutouts (if present)
117 if (shield.getDoCutOut()) {
118 //double sizeX = shield.getCutOutWidth() / Unit::mm / 2.;
119 double sizeX1 = shield.getCutOutWidth1() / Unit::mm / 2.;
120 double sizeX2 = shield.getCutOutWidth2() / Unit::mm / 2.;
121 double sizeY = shield.getCutOutHeight() / Unit::mm / 2.;
122 double depth2 = shield.getCutOutDepth() / Unit::mm / 2.;
123 double sizeZ = (maxZ - minZ) / 2.;
124 double sign = boost::math::sign<double>(minZ);
125 double minAbsZ = min(fabs(minZ), fabs(maxZ));
126
127 G4ThreeVector origin1(0, 0, sign * (minAbsZ + sizeZ));
128 G4ThreeVector origin2(0, 0, sign * (minAbsZ + depth2));
129
130 //G4Box* box1 = new G4Box("Cutout", sizeX, sizeY, sizeZ);
131 G4Trd* box1 = new G4Trd("Cutout1", sizeX1, sizeX2, sizeY, sizeY, sizeZ);
132 G4Box* box2 = new G4Box("Cutout2", 100 / Unit::mm, sizeY, depth2);
133
134 geoShield = new G4SubtractionSolid(name + " IR Shield", geoShield, box1, G4Translate3D(origin1));
135 geoShield = new G4SubtractionSolid(name + " IR Shield", geoShield, box2, G4Translate3D(origin2));
136 }
137
138 string materialName = shield.getMaterial();
139 G4Material* material = Materials::get(materialName);
140 if (!material) B2FATAL("Material '" << materialName << "', required by " << name << " IR Shield could not be found");
141
142 G4LogicalVolume* volume = new G4LogicalVolume(geoShield, material, name + " IR Shield");
143 setColor(*volume, "#cc0000");
144 //setVisibility(*volume, false);
145 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), volume, name + " IR Shield", &topVolume, false, 0);
146 }
147 }
148 }
150}
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
The Class for VXD Heavy Metal Shield.
std::vector< VXDPolyConePar > & getShields(void)
Get shields.
static const double mm
[millimeters]
Definition: Unit.h:70
The Class for VXD PolyCone, possibly with coutouts.
std::vector< VXDPolyConePlanePar > & getPlanes(void)
Get planes.
The Class for VXD Polycone Plane.
HeavyMetalShieldGeometryPar createConfiguration(const GearDir &param)
Create a parameter object from the Gearbox XML parameters.
void createGeometry(const HeavyMetalShieldGeometryPar &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create the geometry from a parameter object.
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
CreatorFactory< GeoHeavyMetalShieldCreator > GeoHeavyMetalShieldFactory("HeavyMetalShieldCreator")
Register the creator.
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition: utilities.cc:100
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
STL namespace.
Very simple class to provide an easy way to register creators with the CreatorManager.