9 #include <beast/pindiode/geometry/PindiodeCreator.h>
10 #include <beast/pindiode/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>
32 #include "G4Colour.hh"
33 #include <G4VisAttributes.hh>
36 using namespace boost;
51 PindiodeCreator::PindiodeCreator(): m_sensitive(0)
71 G4VisAttributes* red =
new G4VisAttributes(G4Colour(1, 0, 0));
72 red->SetForceAuxEdgeVisible(
true);
76 G4VisAttributes* green =
new G4VisAttributes(G4Colour(0, 1, 0));
77 green->SetForceAuxEdgeVisible(
true);
82 G4VisAttributes* gray =
new G4VisAttributes(G4Colour(.5, .5, .5));
83 gray->SetForceAuxEdgeVisible(
true);
84 G4VisAttributes* yellow =
new G4VisAttributes(G4Colour(1, 1, 0));
85 yellow->SetForceAuxEdgeVisible(
true);
98 double stepSize = content.getLength(
"stepSize", 5 * CLHEP::um);
110 BOOST_FOREACH(
const GearDir & activeParams, content.getNodes(
"Active")) {
112 int phase = activeParams.
getInt(
"phase");
113 G4double dx_pins = activeParams.
getLength(
"dx_pins") / 2.*CLHEP::cm;
114 G4double dy_pins = activeParams.
getLength(
"dy_pins") / 2.*CLHEP::cm;
115 G4double dz_pins = activeParams.
getLength(
"dz_pins") / 2.*CLHEP::cm;
130 for (
int wAu : activeParams.
getArray(
"Ch_wAu", {0})) {
131 ch_wAu[dimwAu] = wAu;
135 for (
int woAu : activeParams.
getArray(
"Ch_woAu", {0})) {
136 ch_woAu[dimwoAu] = woAu;
140 for (
double x : activeParams.
getArray(
"x", {0})) {
146 for (
double y : activeParams.
getArray(
"y", {0})) {
149 r[dimy] =
sqrt(x_pos[dimy] * x_pos[dimy] + y_pos[dimy] * y_pos[dimy]);
151 if (x_pos[dimy] >= 0) Phi = TMath::ASin(y_pos[dimy] / r[dimy]) * TMath::RadToDeg();
152 else Phi = -TMath::ASin(y_pos[dimy] / r[dimy]) * TMath::RadToDeg() + 180.;
154 phi[dimy] = Phi * CLHEP::deg - 90. * CLHEP::deg;
158 for (
double ThetaX : activeParams.
getArray(
"ThetaX", {0})) {
159 thetaX[dimThetaX] = ThetaX;
163 for (
double ThetaY : activeParams.
getArray(
"ThetaY", {0})) {
164 thetaY[dimThetaY] = ThetaY;
170 for (
int i = 0; i < 100; i++) {
175 for (
double Phi : activeParams.
getArray(
"Phi", {0})) {
176 phi[dimPhi] = Phi - 90. * CLHEP::deg;
180 for (
double r_pin : activeParams.
getArray(
"r_pin", {0})) {
187 for (
double z : activeParams.
getArray(
"z", {0})) {
193 for (
double ThetaZ : activeParams.
getArray(
"ThetaZ", {0})) {
194 thetaZ[dimThetaZ] = ThetaZ;
199 G4double InchtoCm = 2.54 * CLHEP::cm;
202 G4double dz_airbox = 0.563 / 2. * InchtoCm;
203 G4double dx_airbox = 1. / 2. * InchtoCm;
204 G4double dy_airbox = 0.315 / 2. * InchtoCm;
226 G4double dz_base = 0.5 / 2. * InchtoCm;
227 G4double dx_base = dx_airbox;
228 G4double dy_base = 0.25 / 2. * InchtoCm;
229 G4VSolid* s_base =
new G4Box(
"s_base", dx_base, dy_base, dz_base);
231 G4double ir_hole = 0.;
232 G4double or_hole = 5. / 2.*CLHEP::mm;
233 G4double h_hole = 0.382 / 2. * InchtoCm;
234 G4double sA_hole = 0.*CLHEP::deg;
235 G4double spA_hole = 360.*CLHEP::deg;
236 G4VSolid* s_hole =
new G4Tubs(
"s_hole", ir_hole, or_hole, h_hole, sA_hole, spA_hole);
237 G4double x_pos_hole = dx_base - 0.315 * InchtoCm;
238 G4double y_pos_hole = (0.187 - 0.250 / 2.) * InchtoCm;
239 G4double z_pos_hole = -(0.5 - 0.382) * InchtoCm;
240 s_base =
new G4SubtractionSolid(
"s_base_hole1", s_base, s_hole, 0, G4ThreeVector(x_pos_hole, y_pos_hole, z_pos_hole));
241 s_base =
new G4SubtractionSolid(
"s_base_hole2", s_base, s_hole, 0, G4ThreeVector(-x_pos_hole, y_pos_hole, z_pos_hole));
246 const double iTheta[4] = {0, 90, 180, 270};
247 G4LogicalVolume* l_base =
new G4LogicalVolume(s_base, G4Material::GetMaterial(
"Al6061"),
"l_base");
248 l_base->SetVisAttributes(yellow);
249 G4Transform3D transform;
250 for (
int i = 0; i < dimz; i++) {
252 transform = G4Translate3D(x_pos[i], y_pos[i],
253 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
255 new G4PVPlacement(transform, l_base, TString::Format(
"p_pin_base_%d", i).Data(), &topVolume,
false, 0);
256 B2INFO(
"PIN base-" << (
int)i / 4 <<
"-" << iTheta[i - ((
int)i / 4) * 4] <<
" placed at: " << transform.getTranslation() <<
" mm ");
266 G4double dz_cover1 = dz_airbox;
267 G4double dx_cover1 = dx_airbox;
268 G4double dy_cover1 = dy_airbox - dy_base;
269 G4VSolid* s_cover1 =
new G4Box(
"s_cover1", dx_cover1, dy_cover1, dz_cover1);
271 G4double dx_shole = (0.563 - 0.406) / 2. * InchtoCm;
272 G4VSolid* s_shole =
new G4Box(
"s_shole", dx_shole, dy_cover1, dx_shole);
273 G4double x_pos_cover_hole = dx_base - 0.392 * InchtoCm + dx_shole;
275 G4double z_pos_cover_hole = dz_airbox - 0.406 * InchtoCm + dx_shole;
276 s_cover1 =
new G4SubtractionSolid(
"s_cover1_hole1", s_cover1, s_shole, 0, G4ThreeVector(x_pos_cover_hole, 0, z_pos_cover_hole));
277 s_cover1 =
new G4SubtractionSolid(
"s_cover1_hole2", s_cover1, s_shole, 0, G4ThreeVector(-x_pos_cover_hole, 0, z_pos_cover_hole));
284 G4LogicalVolume* l_cover1 =
new G4LogicalVolume(s_cover1, G4Material::GetMaterial(
"Al6061"),
"l_cover1");
285 l_cover1->SetVisAttributes(yellow);
286 for (
int i = 0; i < dimz; i++) {
288 transform = G4Translate3D(x_pos[i], y_pos[i],
289 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
290 G4Translate3D(0., dy_base + dy_cover1, (dz_cover1 - dz_base) - dy_cover1 * 2.);
293 new G4PVPlacement(transform, l_cover1, TString::Format(
"p_pin_cover1_%d", i).Data(), &topVolume,
false, 0);
303 G4double dz_cover2 = dz_airbox - dz_base;
304 G4double dx_cover2 = dx_airbox;
305 G4double dy_cover2 = dy_base;
306 G4VSolid* s_cover2 =
new G4Box(
"s_cover2", dx_cover2, dy_cover2, dz_cover2);
307 G4LogicalVolume* l_cover2 =
new G4LogicalVolume(s_cover2, G4Material::GetMaterial(
"Al6061"),
"l_cover2");
308 l_cover2->SetVisAttributes(yellow);
309 for (
int i = 0; i < dimz; i++) {
311 transform = G4Translate3D(x_pos[i], y_pos[i],
312 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
313 G4Translate3D(0., -2.*dy_cover1, - dz_base - dz_cover2);
316 new G4PVPlacement(transform, l_cover2, TString::Format(
"p_pin_cover2_%d", i).Data(), &topVolume,
false, 0);
342 G4double dx_pin = dx_pins;
343 G4double dz_pin = dz_pins;
344 G4double dy_pin = dy_pins;
346 G4VSolid* s_pin =
new G4Box(
"s_pin", dx_pin, dy_pin, dz_pin);
348 l_pin->SetVisAttributes(yellow);
349 l_pin->SetUserLimits(
new G4UserLimits(stepSize));
351 for (
int i = 0; i < dimz; i++) {
353 int detID2 = 2 * i + 1;
363 transform = G4Translate3D(x_pos[i], y_pos[i],
364 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
365 G4Translate3D((0.5 - 0.392) * InchtoCm + dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_pin,
366 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - 0. - dz_pin);
372 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_1_%d", i).Data(), &topVolume,
false, detID1);
373 B2INFO(
"With Au PIN-" << detID1 <<
" placed at: " << transform.getTranslation() <<
" mm");
375 transform = G4Translate3D(x_pos[i], y_pos[i],
376 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
377 G4Translate3D(-(0.5 - 0.392) * InchtoCm - dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_pin,
378 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
379 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_2_%d", i).Data(), &topVolume,
false, detID2);
380 B2INFO(
" PIN-" << detID2 <<
" placed at: " << transform.getTranslation() <<
" mm");
397 for (
int j = 0; j < dimPhi; j++) {
398 transform = G4RotateZ3D(phi[j]) * G4Translate3D(0, r[i], z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[j]);
399 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_%d", i).Data(), &topVolume,
false, detID);
400 B2INFO(
"PIN-" << detID <<
" placed at: " << transform.getTranslation() <<
" mm");
434 G4double dx_layer = 2.65 / 2.*CLHEP::mm;
435 G4double dz_layer = 2.65 / 2.*CLHEP::mm;
436 G4double dy_layer1 = 0.01 / 2.*CLHEP::mm;
437 G4VSolid* s_layer1 =
new G4Box(
"s_layer1", dx_layer, dy_layer1, dz_layer);
439 l_layer1->SetVisAttributes(red);
440 for (
int i = 0; i < dimz; i++) {
442 transform = G4Translate3D(x_pos[i], y_pos[i],
443 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
444 G4Translate3D((0.5 - 0.392) * InchtoCm + dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_layer1 + 2.* dy_pin,
445 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
449 new G4PVPlacement(transform, l_layer1, TString::Format(
"p_pin_layer1_%d", i).Data(), &topVolume,
false, 0);
466 G4double dy_layer2 = 0.001 / 2.*InchtoCm;
467 G4VSolid* s_layer2 =
new G4Box(
"s_layer1", dx_layer, dy_layer2, dz_layer);
469 l_layer2->SetVisAttributes(green);
470 for (
int i = 0; i < dimz; i++) {
472 transform = G4Translate3D(x_pos[i], y_pos[i],
473 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
474 G4Translate3D(-(0.5 - 0.392) * InchtoCm - dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_layer2 + 2. * dy_pin,
475 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
479 new G4PVPlacement(transform, l_layer2, TString::Format(
"p_pin_layer2_%d", i).Data(), &topVolume,
false, 0);
GearDir is the basic class used for accessing the parameter store.
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.
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length 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.
virtual void create(const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Creation of the detector geometry from Gearbox (XML).
virtual ~PindiodeCreator()
Destructor.
SensitiveDetector * m_sensitive
SensitiveDetector PINDIODE.
Sensitive Detector implementation of the PINDIODE detector.
double sqrt(double a)
sqrt for double
GeometryTypes
Flag indiciating the type of geometry to be used.
geometry::CreatorFactory< PindiodeCreator > PindiodeFactory("PINDIODECreator")
Creator creates the PINDIODE geometry.
Abstract base class for different kinds of events.
Very simple class to provide an easy way to register creators with the CreatorManager.