9#include <vxd/geometry/GeoHeavyMetalShieldCreator.h>
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>
19#include <boost/math/special_functions/sign.hpp>
21#include <G4LogicalVolume.hh>
22#include <G4PVPlacement.hh>
23#include <G4AssemblyVolume.hh>
28#include <G4Polycone.hh>
29#include <G4SubtractionSolid.hh>
39 using namespace geometry;
51 for (
const GearDir& shield : param.getNodes(
"Shield")) {
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),
59 shield.getLength(
"Cutout/width1", 0.),
60 shield.getLength(
"Cutout/width2", 0.),
61 shield.getLength(
"Cutout/height", 0.),
62 shield.getLength(
"Cutout/depth", 0.)
65 for (
const GearDir& plane : shield.getNodes(
"Plane")) {
67 plane.getLength(
"posZ"),
68 plane.getLength(
"innerRadius"),
69 plane.getLength(
"outerRadius")
71 shieldPar.
getPlanes().push_back(planePar);
74 heavyMetalShieldGeometryPar.
getShields().push_back(shieldPar);
76 return heavyMetalShieldGeometryPar;
86 string name = shield.getName();
87 double minZ(0), maxZ(0);
90 double minPhi = shield.getMinPhi();
91 double dPhi = shield.getMaxPhi() - minPhi;
92 int nPlanes = shield.getPlanes().size();
94 B2ERROR(
"Polycone needs at least two planes");
97 std::vector<double> z(nPlanes, 0);
98 std::vector<double> rMin(nPlanes, 0);
99 std::vector<double> rMax(nPlanes, 0);
101 minZ = numeric_limits<double>::infinity();
102 maxZ = -numeric_limits<double>::infinity();
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;
114 G4VSolid* geoShield =
new G4Polycone(name +
" IR Shield", minPhi, dPhi, nPlanes, z.data(), rMin.data(), rMax.data());
117 if (shield.getDoCutOut()) {
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));
127 G4ThreeVector origin1(0, 0, sign * (minAbsZ + sizeZ));
128 G4ThreeVector origin2(0, 0, sign * (minAbsZ + depth2));
131 G4Trd* box1 =
new G4Trd(
"Cutout1", sizeX1, sizeX2, sizeY, sizeY, sizeZ);
132 G4Box* box2 =
new G4Box(
"Cutout2", 100 /
Unit::mm, sizeY, depth2);
134 geoShield =
new G4SubtractionSolid(name +
" IR Shield", geoShield, box1, G4Translate3D(origin1));
135 geoShield =
new G4SubtractionSolid(name +
" IR Shield", geoShield, box2, G4Translate3D(origin2));
138 string materialName = shield.getMaterial();
140 if (!material) B2FATAL(
"Material '" << materialName <<
"', required by " << name <<
" IR Shield could not be found");
142 G4LogicalVolume* volume =
new G4LogicalVolume(geoShield, material, name +
" IR Shield");
145 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), volume, name +
" IR Shield", &topVolume,
false, 0);
GearDir is the basic class used for accessing the parameter store.
static const double mm
[millimeters]
The Class for VXD PolyCone, possibly with coutouts.
std::vector< VXDPolyConePlanePar > & getPlanes(void)
Get planes.
The Class for VXD Polycone Plane.
static G4Material * get(const std::string &name)
Find given material.
CreatorFactory< GeoHeavyMetalShieldCreator > GeoHeavyMetalShieldFactory("HeavyMetalShieldCreator")
Register the creator.
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
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.