Belle II Software  release-06-00-14
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/format.hpp>
20 #include <boost/algorithm/string.hpp>
21 #include <boost/math/special_functions/sign.hpp>
22 
23 #include <G4LogicalVolume.hh>
24 #include <G4PVPlacement.hh>
25 #include <G4AssemblyVolume.hh>
26 
27 // Shapes
28 #include <G4Box.hh>
29 #include <G4Polycone.hh>
30 #include <G4SubtractionSolid.hh>
31 
32 using namespace std;
33 using namespace boost;
34 
35 namespace Belle2 {
41  using namespace geometry;
42 
44  namespace VXD {
45 
48 
49  HeavyMetalShieldGeometryPar GeoHeavyMetalShieldCreator::createConfiguration(const GearDir& param)
50  {
51  HeavyMetalShieldGeometryPar heavyMetalShieldGeometryPar;
52  //Read the definition of all shields
53  for (const GearDir& shield : param.getNodes("Shield")) {
54  VXDPolyConePar shieldPar(
55  shield.getString("@name"),
56  shield.getString("Material", "Air"),
57  shield.getAngle("minPhi", 0),
58  shield.getAngle("maxPhi", 2 * M_PI),
59  (shield.getNodes("Cutout").size() > 0),
60  shield.getLength("Cutout/width", 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 sizeY = shield.getCutOutHeight() / Unit::mm / 2.;
120  double depth2 = shield.getCutOutDepth() / Unit::mm / 2.;
121  double sizeZ = (maxZ - minZ) / 2.;
122  double sign = math::sign<double>(minZ);
123  double minAbsZ = min(fabs(minZ), fabs(maxZ));
124 
125  G4ThreeVector origin1(0, 0, sign * (minAbsZ + sizeZ));
126  G4ThreeVector origin2(0, 0, sign * (minAbsZ + depth2));
127 
128  G4Box* box1 = new G4Box("Cutout", sizeX, sizeY, sizeZ);
129  G4Box* box2 = new G4Box("Cutout", 100 / Unit::mm, sizeY, depth2);
130 
131  geoShield = new G4SubtractionSolid(name + " IR Shield", geoShield, box1, G4Translate3D(origin1));
132  geoShield = new G4SubtractionSolid(name + " IR Shield", geoShield, box2, G4Translate3D(origin2));
133  }
134 
135  string materialName = shield.getMaterial();
136  G4Material* material = Materials::get(materialName);
137  if (!material) B2FATAL("Material '" << materialName << "', required by " << name << " IR Shield could not be found");
138 
139  G4LogicalVolume* volume = new G4LogicalVolume(geoShield, material, name + " IR Shield");
140  setColor(*volume, "#cc0000");
141  //setVisibility(*volume, false);
142  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), volume, name + " IR Shield", &topVolume, false, 0);
143  }
144  }
145  }
147 }
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.
The Class for VXD PolyCone, possibly with coutouts.
std::vector< VXDPolyConePlanePar > & getPlanes(void)
Get planes.
The Class for VXD Polycone Plane.
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:97
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.