Belle II Software development
BeamabortCreator.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 <beast/beamabort/geometry/BeamabortCreator.h>
10#include <beast/beamabort/simulation/SensitiveDetector.h>
11
12#include <geometry/Materials.h>
13#include <geometry/CreatorFactory.h>
14#include <framework/gearbox/GearDir.h>
15#include <framework/logging/Logger.h>
16
17#include <cmath>
18#include <boost/format.hpp>
19#include <boost/foreach.hpp>
20#include <boost/algorithm/string.hpp>
21
22#include <G4LogicalVolume.hh>
23#include <G4PVPlacement.hh>
24
25//Shapes
26#include <G4Box.hh>
27#include "G4SubtractionSolid.hh"
28#include <G4UserLimits.hh>
29
30//Visualization
31#include "G4Colour.hh"
32#include <G4VisAttributes.hh>
33
34using namespace std;
35using namespace boost;
36
37namespace Belle2 {
43 using namespace geometry;
44
46 namespace beamabort {
47
48 // Register the creator
50 geometry::CreatorFactory <BeamabortCreator> BeamabortFactory("BEAMABORTCreator");
51
53 {}
54
56 {}
57
58 void BeamabortCreator::createGeometry(G4LogicalVolume& topVolume, GeometryTypes)
59 {
60 //get parameters from .xml file
61 std::string prep = "Active.";
62
63 B2INFO("BeamabortCreator phase3");
64 //Visualization Attributes
65 G4VisAttributes* orange = new G4VisAttributes(G4Colour(1, 2, 0));
66 orange->SetForceAuxEdgeVisible(true);
67 G4VisAttributes* magenta = new G4VisAttributes(G4Colour(1, 0, 1));
68 magenta->SetForceAuxEdgeVisible(true);
69 //lets get the stepsize parameter with a default value of 5 µm
70 double stepSize = m_config.getParameter("stepSize", 5 * CLHEP::um);
71
72 //Lets loop over all the Active nodes
73 int phase = m_config.getParameter(prep + "phase");
74 //Positioned Diamonds
75 std::vector<double> x_pos;
76 std::vector<double> y_pos;
77 std::vector<double> z_pos;
78 std::vector<double> phi;
79 std::vector<double> thetaX;
80 std::vector<double> thetaY;
81 std::vector<double> thetaZ;
82 std::vector<double> svdAngle;
83 std::vector<double> r;
84 std::vector<double> deltaX;
85 unsigned int dimz = 0;
86
87 for (double z : m_config.getParArray(prep + "z", {0})) {
88 z *= CLHEP::cm;
89 z_pos.push_back(z);
90 dimz++;
91 }
92
93 for (double ThetaZ : m_config.getParArray(prep + "ThetaZ", {0})) {
94 thetaZ.push_back(ThetaZ);
95 }
96
97 if (thetaZ.size() != dimz) { B2ERROR("Diamond data not consistent (i.e. not same number of all position parmeters)"); return;}
98
99 if (phase == 2 || phase == 3) {
100
101 for (double Phi : m_config.getParArray(prep + "Phi", {0})) {
102 phi.push_back(Phi);
103 }
104
105 for (double r_dia : m_config.getParArray(prep + "r_dia", {0})) {
106 r_dia *= CLHEP::cm;
107 r.push_back(r_dia);
108 }
109 for (double dX : m_config.getParArray(prep + "deltaX", {0})) {
110 dX *= CLHEP::cm;
111 deltaX.push_back(dX);
112 }
113 for (double addAngle : m_config.getParArray(prep + "addAngle", {0})) {
114 svdAngle.push_back(addAngle);
115 }
116 if (phi.size() != dimz || r.size() != dimz || deltaX.size() != dimz || svdAngle.size() != dimz) { B2ERROR("Diamond data not consistent (i.e. not same number of all position parmeters)"); return;}
117 }
118 if (phase == 1) {
119 for (double x : m_config.getParArray(prep + "x", {0})) {
120 x *= CLHEP::cm;
121 x_pos.push_back(x);
122 }
123 for (double y : m_config.getParArray(prep + "y", {0})) {
124 y *= CLHEP::cm;
125 y_pos.push_back(y);
126 }
127
128 for (double ThetaX : m_config.getParArray(prep + "ThetaX", {0})) {
129 thetaX.push_back(ThetaX);
130 }
131 for (double ThetaY : m_config.getParArray(prep + "ThetaY", {0})) {
132 thetaY.push_back(ThetaY);
133 }
134 if (x_pos.size() != dimz || y_pos.size() != dimz || thetaX.size() != dimz || thetaY.size() != dimz) { B2ERROR("Diamond data not consistent (i.e. not same number of all position parmeters)"); return;}
135 }
136
137 //create beamabort package
138 G4double dx_opa = 12. / 2. * CLHEP::mm;
139 G4double dy_opa = 18. / 2. * CLHEP::mm;
140 G4double dz_opa = 3.1 / 2. * CLHEP::mm;
141 G4VSolid* s_pa = new G4Box("s_opa", dx_opa, dy_opa, dz_opa);
142 G4double dx_ipa = 6. / 2. * CLHEP::mm;
143 G4double dy_ipa = 6. / 2. * CLHEP::mm;
144 G4double dz_ipa = 5.6 / 2. * CLHEP::mm;
145 G4VSolid* s_ipa = new G4Box("s_ipa", dx_ipa, dy_ipa, dz_ipa);
146 s_pa = new G4SubtractionSolid("s_pa", s_pa, s_ipa, 0, G4ThreeVector(0., 4.0, 0.));
147 G4LogicalVolume* l_pa = new G4LogicalVolume(s_pa, G4Material::GetMaterial("Al6061"), "l_pa");
148 l_pa->SetVisAttributes(magenta);
149 G4Transform3D transform;
150 for (unsigned int i = 0; i < dimz; i++) {
151 B2INFO("DIA-" << i << "RotateZ3D phi: " << phi[i]);
152
153 if (phase == 1) {
154 transform = G4Translate3D(x_pos[i], y_pos[i], z_pos[i]) * G4RotateX3D(thetaX[i]) *
155 G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
156 } else if (phase == 2 || phase == 3) {
157 transform = G4Translate3D(deltaX[i], 0, 0) * G4RotateZ3D(phi[i]) *
158 G4Translate3D(r[i], 0, z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[i]) *
159 G4RotateZ3D(svdAngle[i]) * G4RotateY3D(M_PI / 2);
160 }
161 new G4PVPlacement(transform, l_pa, TString::Format("p_dia_pa_%d", i).Data(), &topVolume, false, 0);
162 B2INFO("DIA-" << i << " placed at: " << transform.getTranslation() << " mm ");
163 }
164
165 //create beamabort volumes
166 G4double dx_ba = 4.5 / 2. * CLHEP::mm;
167 G4double dy_ba = 4.5 / 2. * CLHEP::mm;
168 G4double dz_ba = 0.5 / 2. * CLHEP::mm;
169 G4Box* s_BEAMABORT = new G4Box("s_BEAMABORT", dx_ba, dy_ba, dz_ba);
170 G4LogicalVolume* l_BEAMABORT = new G4LogicalVolume(s_BEAMABORT, geometry::Materials::get("Diamond"), "l_BEAMABORT");
171 l_BEAMABORT->SetVisAttributes(orange);
172
173 //Lets limit the Geant4 stepsize inside the volume
174 l_BEAMABORT->SetUserLimits(new G4UserLimits(stepSize));
175 l_BEAMABORT->SetVisAttributes(orange);
176
177 // make the volume sensitive if the beam background study flag is enabled
178 if (m_config.getParameter("BeamBackgroundStudy")) l_BEAMABORT->SetSensitiveDetector(new SensitiveDetector());
179
180 for (unsigned int i = 0; i < dimz; i++) {
181
182 if (phase == 1)
183 transform = G4Translate3D(x_pos[i], y_pos[i],
184 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
185 if (phase == 2 || phase == 3)
186 transform = G4Translate3D(deltaX[i], 0, 0) * G4RotateZ3D(phi[i]) *
187 G4Translate3D(r[i], 0, z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[i]) *
188 G4RotateZ3D(svdAngle[i]) * G4RotateY3D(M_PI / 2) * G4Translate3D(0, 4.2, 0);
189
190 new G4PVPlacement(transform, l_BEAMABORT, TString::Format("p_dia_%d", i).Data(), &topVolume, false, i);
191
192 B2INFO("DIA-sensitive volume-" << i << " placed at: " << transform.getTranslation() << " mm "
193 << " at phi angle = " << phi[i] << " at theta angle = "
194 << thetaZ[i]);
195 B2INFO("DIA-sensitive volume-" << i << " G4RotateZ3D of: phi= " << phi[i] << " G4RotateX3D = "
196 << (-M_PI / 2 - thetaZ[i]));
197 }
198 }
199 }
201}
std::vector< double > getParArray(const std::string &name) const
Get parameter value array.
Definition: BeamabortGeo.h:64
double getParameter(const std::string &name) const
Get parameter value.
Definition: BeamabortGeo.h:41
void createGeometry(G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create detector geometry.
BeamabortGeo m_config
geometry parameters object
Sensitive Detector implementation of the BEAMABORT detector.
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
geometry::CreatorFactory< BeamabortCreator > BeamabortFactory("BEAMABORTCreator")
Creator creates the BEAMABORT geometry.
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
STL namespace.