9 #include <beast/beamabort/geometry/BeamabortCreator.h>
10 #include <beast/beamabort/simulation/SensitiveDetector.h>
12 #include <geometry/Materials.h>
13 #include <geometry/CreatorFactory.h>
14 #include <framework/gearbox/GearDir.h>
15 #include <framework/logging/Logger.h>
18 #include <boost/format.hpp>
19 #include <boost/foreach.hpp>
20 #include <boost/algorithm/string.hpp>
22 #include <G4LogicalVolume.hh>
23 #include <G4PVPlacement.hh>
27 #include "G4SubtractionSolid.hh"
28 #include <G4UserLimits.hh>
31 #include "G4Colour.hh"
32 #include <G4VisAttributes.hh>
35 using namespace boost;
43 using namespace geometry;
52 BeamabortCreator::BeamabortCreator()
55 BeamabortCreator::~BeamabortCreator()
58 void BeamabortCreator::createGeometry(G4LogicalVolume& topVolume,
GeometryTypes)
61 std::string prep =
"Active.";
63 B2INFO(
"BeamabortCreator phase3");
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);
70 double stepSize = m_config.getParameter(
"stepSize", 5 * CLHEP::um);
73 int phase = m_config.getParameter(prep +
"phase");
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;
87 for (
double z : m_config.getParArray(prep +
"z", {0})) {
93 for (
double ThetaZ : m_config.getParArray(prep +
"ThetaZ", {0})) {
94 thetaZ.push_back(ThetaZ);
97 if (thetaZ.size() != dimz) { B2ERROR(
"Diamond data not consistent (i.e. not same number of all position parmeters)");
return;}
99 if (phase == 2 || phase == 3) {
101 for (
double Phi : m_config.getParArray(prep +
"Phi", {0})) {
105 for (
double r_dia : m_config.getParArray(prep +
"r_dia", {0})) {
109 for (
double dX : m_config.getParArray(prep +
"deltaX", {0})) {
111 deltaX.push_back(dX);
113 for (
double addAngle : m_config.getParArray(prep +
"addAngle", {0})) {
114 svdAngle.push_back(addAngle);
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;}
119 for (
double x : m_config.getParArray(prep +
"x", {0})) {
123 for (
double y : m_config.getParArray(prep +
"y", {0})) {
128 for (
double ThetaX : m_config.getParArray(prep +
"ThetaX", {0})) {
129 thetaX.push_back(ThetaX);
131 for (
double ThetaY : m_config.getParArray(prep +
"ThetaY", {0})) {
132 thetaY.push_back(ThetaY);
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;}
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]);
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);
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 ");
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);
174 l_BEAMABORT->SetUserLimits(
new G4UserLimits(stepSize));
175 l_BEAMABORT->SetVisAttributes(orange);
178 if (m_config.getParameter(
"BeamBackgroundStudy")) l_BEAMABORT->SetSensitiveDetector(
new SensitiveDetector());
180 for (
unsigned int i = 0; i < dimz; i++) {
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);
190 new G4PVPlacement(transform, l_BEAMABORT, TString::Format(
"p_dia_%d", i).Data(), &topVolume,
false, i);
192 B2INFO(
"DIA-sensitive volume-" << i <<
" placed at: " << transform.getTranslation() <<
" mm "
193 <<
" at phi angle = " << phi[i] <<
" at theta angle = "
195 B2INFO(
"DIA-sensitive volume-" << i <<
" G4RotateZ3D of: phi= " << phi[i] <<
" G4RotateX3D = "
196 << (-M_PI / 2 - thetaZ[i]));
Sensitive Detector implementation of the BEAMABORT detector.
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.
Very simple class to provide an easy way to register creators with the CreatorManager.