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;
50 BeamabortCreator::BeamabortCreator(): m_sensitive(0)
66 B2INFO(
"BeamabortCreator phase2");
68 G4VisAttributes* orange =
new G4VisAttributes(G4Colour(1, 2, 0));
69 orange->SetForceAuxEdgeVisible(
true);
70 G4VisAttributes* magenta =
new G4VisAttributes(G4Colour(1, 0, 1));
71 magenta->SetForceAuxEdgeVisible(
true);
73 double stepSize = content.getLength(
"stepSize", 5 * CLHEP::um);
77 const GearDir & activeParams, content.getNodes(
"Active")) {
79 int phase = activeParams.
getInt(
"phase");
81 std::vector<double> x_pos;
82 std::vector<double> y_pos;
83 std::vector<double> z_pos;
84 std::vector<double> phi;
85 std::vector<double> thetaX;
86 std::vector<double> thetaY;
87 std::vector<double> thetaZ;
88 std::vector<double> svdAngle;
89 std::vector<double> r;
90 std::vector<double> deltaX;
91 unsigned int dimz = 0;
93 for (
double z : activeParams.
getArray(
"z", {0})) {
99 for (
double ThetaZ : activeParams.
getArray(
"ThetaZ", {0})) {
100 thetaZ.push_back(ThetaZ);
103 if (thetaZ.size() != dimz) { B2ERROR(
"Diamond data not consistent (i.e. not same number of all position parmeters)");
return;}
105 if (phase == 2 || phase == 3) {
107 for (
double Phi : activeParams.
getArray(
"Phi", {0})) {
111 for (
double r_dia : activeParams.
getArray(
"r_dia", {0})) {
115 for (
double dX : activeParams.
getArray(
"deltaX", {0})) {
117 deltaX.push_back(dX);
119 for (
double addAngle : activeParams.
getArray(
"addAngle", {0})) {
120 svdAngle.push_back(addAngle);
122 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;}
125 for (
double x : activeParams.
getArray(
"x", {0})) {
129 for (
double y : activeParams.
getArray(
"y", {0})) {
134 for (
double ThetaX : activeParams.
getArray(
"ThetaX", {0})) {
135 thetaX.push_back(ThetaX);
137 for (
double ThetaY : activeParams.
getArray(
"ThetaY", {0})) {
138 thetaY.push_back(ThetaY);
140 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;}
145 G4double dx_opa = 12. / 2. * CLHEP::mm;
146 G4double dy_opa = 18. / 2. * CLHEP::mm;
147 G4double dz_opa = 3.1 / 2. * CLHEP::mm;
148 G4VSolid* s_pa =
new G4Box(
"s_opa", dx_opa, dy_opa, dz_opa);
149 G4double dx_ipa = 6. / 2. * CLHEP::mm;
150 G4double dy_ipa = 6. / 2. * CLHEP::mm;
151 G4double dz_ipa = 5.6 / 2. * CLHEP::mm;
152 G4VSolid* s_ipa =
new G4Box(
"s_ipa", dx_ipa, dy_ipa, dz_ipa);
153 s_pa =
new G4SubtractionSolid(
"s_pa", s_pa, s_ipa, 0, G4ThreeVector(0., 4.0, 0.));
154 G4LogicalVolume* l_pa =
new G4LogicalVolume(s_pa, G4Material::GetMaterial(
"Al6061"),
"l_pa");
155 l_pa->SetVisAttributes(magenta);
156 G4Transform3D transform;
157 for (
unsigned int i = 0; i < dimz; i++) {
158 B2INFO(
"DIA-" << i <<
"RotateZ3D phi: " << phi[i]);
161 transform = G4Translate3D(x_pos[i], y_pos[i], z_pos[i]) * G4RotateX3D(thetaX[i]) *
162 G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
163 }
else if (phase == 2 || phase == 3) {
164 transform = G4Translate3D(deltaX[i], 0, 0) * G4RotateZ3D(phi[i]) *
165 G4Translate3D(r[i], 0, z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[i]) *
166 G4RotateZ3D(svdAngle[i]) * G4RotateY3D(M_PI / 2);
168 new G4PVPlacement(transform, l_pa, TString::Format(
"p_dia_pa_%d", i).Data(), &topVolume,
false, 0);
169 B2INFO(
"DIA-" << i <<
" placed at: " << transform.getTranslation() <<
" mm ");
173 G4double dx_ba = 4.5 / 2. * CLHEP::mm;
174 G4double dy_ba = 4.5 / 2. * CLHEP::mm;
175 G4double dz_ba = 0.5 / 2. * CLHEP::mm;
176 G4Box* s_BEAMABORT =
new G4Box(
"s_BEAMABORT", dx_ba, dy_ba, dz_ba);
179 l_BEAMABORT->SetVisAttributes(orange);
182 l_BEAMABORT->SetUserLimits(
new G4UserLimits(stepSize));
183 l_BEAMABORT->SetVisAttributes(orange);
185 for (
unsigned int i = 0; i < dimz; i++) {
188 transform = G4Translate3D(x_pos[i], y_pos[i],
189 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
190 if (phase == 2 || phase == 3)
191 transform = G4Translate3D(deltaX[i], 0, 0) * G4RotateZ3D(phi[i]) *
192 G4Translate3D(r[i], 0, z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[i]) *
193 G4RotateZ3D(svdAngle[i]) * G4RotateY3D(M_PI / 2) * G4Translate3D(0, 4.2, 0);
195 new G4PVPlacement(transform, l_BEAMABORT, TString::Format(
"p_dia_%d", i).Data(), &topVolume,
false, i);
197 B2INFO(
"DIA-sensitive volume-" << i <<
" placed at: " << transform.getTranslation() <<
" mm "
198 <<
" at phi angle = " << phi[i] <<
" at theta angle = "
200 B2INFO(
"DIA-sensitive volume-" << i <<
" G4RotateZ3D of: phi= " << phi[i] <<
" G4RotateX3D = "
201 << (-M_PI / 2 - thetaZ[i]));
GearDir is the basic class used for accessing the parameter store.
virtual void create(const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Creation of the detector geometry from Gearbox (XML).
SensitiveDetector * m_sensitive
SensitiveDetector BEAMABORT.
virtual ~BeamabortCreator()
Destructor.
Sensitive Detector implementation of the BEAMABORT detector.
std::vector< double > getArray(const std::string &path) const noexcept(false)
Get the parameter path as a list of double values converted to the standard unit.
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
static G4Material * get(const std::string &name)
Find given material.
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.