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>
20#include <boost/format.hpp>
21#include <boost/foreach.hpp>
22#include <boost/algorithm/string.hpp>
24#include <G4LogicalVolume.hh>
25#include <G4PVPlacement.hh>
29#include "G4SubtractionSolid.hh"
30#include <G4UserLimits.hh>
35#include <G4VisAttributes.hh>
73 G4VisAttributes* red =
new G4VisAttributes(G4Colour(1, 0, 0));
74 red->SetForceAuxEdgeVisible(
true);
78 G4VisAttributes* green =
new G4VisAttributes(G4Colour(0, 1, 0));
79 green->SetForceAuxEdgeVisible(
true);
84 G4VisAttributes* gray =
new G4VisAttributes(G4Colour(.5, .5, .5));
85 gray->SetForceAuxEdgeVisible(
true);
86 G4VisAttributes* yellow =
new G4VisAttributes(G4Colour(1, 1, 0));
87 yellow->SetForceAuxEdgeVisible(
true);
100 double stepSize = content.getLength(
"stepSize", 5 * CLHEP::um);
112 BOOST_FOREACH(
const GearDir & activeParams, content.getNodes(
"Active")) {
114 int phase = activeParams.
getInt(
"phase");
115 G4double dx_pins = activeParams.
getLength(
"dx_pins") / 2.*CLHEP::cm;
116 G4double dy_pins = activeParams.
getLength(
"dy_pins") / 2.*CLHEP::cm;
117 G4double dz_pins = activeParams.
getLength(
"dz_pins") / 2.*CLHEP::cm;
132 for (
int wAu : activeParams.
getArray(
"Ch_wAu", {0})) {
133 ch_wAu[dimwAu] = wAu;
137 for (
int woAu : activeParams.
getArray(
"Ch_woAu", {0})) {
138 ch_woAu[dimwoAu] = woAu;
142 for (
double x : activeParams.
getArray(
"x", {0})) {
148 for (
double y : activeParams.
getArray(
"y", {0})) {
151 r[dimy] =
sqrt(x_pos[dimy] * x_pos[dimy] + y_pos[dimy] * y_pos[dimy]);
153 if (x_pos[dimy] >= 0) Phi = TMath::ASin(y_pos[dimy] / r[dimy]) * TMath::RadToDeg();
154 else Phi = -TMath::ASin(y_pos[dimy] / r[dimy]) * TMath::RadToDeg() + 180.;
156 phi[dimy] = Phi * CLHEP::deg - 90. * CLHEP::deg;
160 for (
double ThetaX : activeParams.
getArray(
"ThetaX", {0})) {
161 thetaX[dimThetaX] = ThetaX;
165 for (
double ThetaY : activeParams.
getArray(
"ThetaY", {0})) {
166 thetaY[dimThetaY] = ThetaY;
172 for (
int i = 0; i < 100; i++) {
177 for (
double Phi : activeParams.
getArray(
"Phi", {0})) {
178 phi[dimPhi] = Phi - 90. * CLHEP::deg;
182 for (
double r_pin : activeParams.
getArray(
"r_pin", {0})) {
189 for (
double z : activeParams.
getArray(
"z", {0})) {
195 for (
double ThetaZ : activeParams.
getArray(
"ThetaZ", {0})) {
196 thetaZ[dimThetaZ] = ThetaZ;
201 G4double InchtoCm = 2.54 * CLHEP::cm;
204 G4double dz_airbox = 0.563 / 2. * InchtoCm;
205 G4double dx_airbox = 1. / 2. * InchtoCm;
206 G4double dy_airbox = 0.315 / 2. * InchtoCm;
228 G4double dz_base = 0.5 / 2. * InchtoCm;
229 G4double dx_base = dx_airbox;
230 G4double dy_base = 0.25 / 2. * InchtoCm;
231 G4VSolid* s_base =
new G4Box(
"s_base", dx_base, dy_base, dz_base);
233 G4double ir_hole = 0.;
234 G4double or_hole = 5. / 2.*CLHEP::mm;
235 G4double h_hole = 0.382 / 2. * InchtoCm;
236 G4double sA_hole = 0.*CLHEP::deg;
237 G4double spA_hole = 360.*CLHEP::deg;
238 G4VSolid* s_hole =
new G4Tubs(
"s_hole", ir_hole, or_hole, h_hole, sA_hole, spA_hole);
239 G4double x_pos_hole = dx_base - 0.315 * InchtoCm;
240 G4double y_pos_hole = (0.187 - 0.250 / 2.) * InchtoCm;
241 G4double z_pos_hole = -(0.5 - 0.382) * InchtoCm;
242 s_base =
new G4SubtractionSolid(
"s_base_hole1", s_base, s_hole, 0, G4ThreeVector(x_pos_hole, y_pos_hole, z_pos_hole));
243 s_base =
new G4SubtractionSolid(
"s_base_hole2", s_base, s_hole, 0, G4ThreeVector(-x_pos_hole, y_pos_hole, z_pos_hole));
248 const double iTheta[4] = {0, 90, 180, 270};
249 G4LogicalVolume* l_base =
new G4LogicalVolume(s_base, G4Material::GetMaterial(
"Al6061"),
"l_base");
250 l_base->SetVisAttributes(yellow);
251 G4Transform3D transform;
252 for (
int i = 0; i < dimz; i++) {
254 transform = G4Translate3D(x_pos[i], y_pos[i],
255 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]);
257 new G4PVPlacement(transform, l_base, TString::Format(
"p_pin_base_%d", i).Data(), &topVolume,
false, 0);
258 B2INFO(
"PIN base-" << (
int)i / 4 <<
"-" << iTheta[i - ((
int)i / 4) * 4] <<
" placed at: " << transform.getTranslation() <<
" mm ");
268 G4double dz_cover1 = dz_airbox;
269 G4double dx_cover1 = dx_airbox;
270 G4double dy_cover1 = dy_airbox - dy_base;
271 G4VSolid* s_cover1 =
new G4Box(
"s_cover1", dx_cover1, dy_cover1, dz_cover1);
273 G4double dx_shole = (0.563 - 0.406) / 2. * InchtoCm;
274 G4VSolid* s_shole =
new G4Box(
"s_shole", dx_shole, dy_cover1, dx_shole);
275 G4double x_pos_cover_hole = dx_base - 0.392 * InchtoCm + dx_shole;
277 G4double z_pos_cover_hole = dz_airbox - 0.406 * InchtoCm + dx_shole;
278 s_cover1 =
new G4SubtractionSolid(
"s_cover1_hole1", s_cover1, s_shole, 0, G4ThreeVector(x_pos_cover_hole, 0, z_pos_cover_hole));
279 s_cover1 =
new G4SubtractionSolid(
"s_cover1_hole2", s_cover1, s_shole, 0, G4ThreeVector(-x_pos_cover_hole, 0, z_pos_cover_hole));
286 G4LogicalVolume* l_cover1 =
new G4LogicalVolume(s_cover1, G4Material::GetMaterial(
"Al6061"),
"l_cover1");
287 l_cover1->SetVisAttributes(yellow);
288 for (
int i = 0; i < dimz; i++) {
290 transform = G4Translate3D(x_pos[i], y_pos[i],
291 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
292 G4Translate3D(0., dy_base + dy_cover1, (dz_cover1 - dz_base) - dy_cover1 * 2.);
295 new G4PVPlacement(transform, l_cover1, TString::Format(
"p_pin_cover1_%d", i).Data(), &topVolume,
false, 0);
305 G4double dz_cover2 = dz_airbox - dz_base;
306 G4double dx_cover2 = dx_airbox;
307 G4double dy_cover2 = dy_base;
308 G4VSolid* s_cover2 =
new G4Box(
"s_cover2", dx_cover2, dy_cover2, dz_cover2);
309 G4LogicalVolume* l_cover2 =
new G4LogicalVolume(s_cover2, G4Material::GetMaterial(
"Al6061"),
"l_cover2");
310 l_cover2->SetVisAttributes(yellow);
311 for (
int i = 0; i < dimz; i++) {
313 transform = G4Translate3D(x_pos[i], y_pos[i],
314 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
315 G4Translate3D(0., -2.*dy_cover1, - dz_base - dz_cover2);
318 new G4PVPlacement(transform, l_cover2, TString::Format(
"p_pin_cover2_%d", i).Data(), &topVolume,
false, 0);
344 G4double dx_pin = dx_pins;
345 G4double dz_pin = dz_pins;
346 G4double dy_pin = dy_pins;
348 G4VSolid* s_pin =
new G4Box(
"s_pin", dx_pin, dy_pin, dz_pin);
350 l_pin->SetVisAttributes(yellow);
351 l_pin->SetUserLimits(
new G4UserLimits(stepSize));
353 for (
int i = 0; i < dimz; i++) {
355 int detID2 = 2 * i + 1;
365 transform = G4Translate3D(x_pos[i], y_pos[i],
366 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
367 G4Translate3D((0.5 - 0.392) * InchtoCm + dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_pin,
368 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - 0. - dz_pin);
374 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_1_%d", i).Data(), &topVolume,
false, detID1);
375 B2INFO(
"With Au PIN-" << detID1 <<
" placed at: " << transform.getTranslation() <<
" mm");
377 transform = G4Translate3D(x_pos[i], y_pos[i],
378 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
379 G4Translate3D(-(0.5 - 0.392) * InchtoCm - dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_pin,
380 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
381 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_2_%d", i).Data(), &topVolume,
false, detID2);
382 B2INFO(
" PIN-" << detID2 <<
" placed at: " << transform.getTranslation() <<
" mm");
399 for (
int j = 0; j < dimPhi; j++) {
400 transform = G4RotateZ3D(phi[j]) * G4Translate3D(0, r[i], z_pos[i]) * G4RotateX3D(-M_PI / 2 - thetaZ[j]);
401 new G4PVPlacement(transform, l_pin, TString::Format(
"p_pin_%d", i).Data(), &topVolume,
false, detID);
402 B2INFO(
"PIN-" << detID <<
" placed at: " << transform.getTranslation() <<
" mm");
436 G4double dx_layer = 2.65 / 2.*CLHEP::mm;
437 G4double dz_layer = 2.65 / 2.*CLHEP::mm;
438 G4double dy_layer1 = 0.01 / 2.*CLHEP::mm;
439 G4VSolid* s_layer1 =
new G4Box(
"s_layer1", dx_layer, dy_layer1, dz_layer);
441 l_layer1->SetVisAttributes(red);
442 for (
int i = 0; i < dimz; i++) {
444 transform = G4Translate3D(x_pos[i], y_pos[i],
445 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
446 G4Translate3D((0.5 - 0.392) * InchtoCm + dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_layer1 + 2.* dy_pin,
447 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
451 new G4PVPlacement(transform, l_layer1, TString::Format(
"p_pin_layer1_%d", i).Data(), &topVolume,
false, 0);
468 G4double dy_layer2 = 0.001 / 2.*InchtoCm;
469 G4VSolid* s_layer2 =
new G4Box(
"s_layer1", dx_layer, dy_layer2, dz_layer);
471 l_layer2->SetVisAttributes(green);
472 for (
int i = 0; i < dimz; i++) {
474 transform = G4Translate3D(x_pos[i], y_pos[i],
475 z_pos[i]) * G4RotateX3D(thetaX[i]) * G4RotateY3D(thetaY[i]) * G4RotateZ3D(thetaZ[i]) *
476 G4Translate3D(-(0.5 - 0.392) * InchtoCm - dx_shole, (0.187 - 0.250 / 2.) * InchtoCm + dy_layer2 + 2. * dy_pin,
477 (0.563 / 2. - 0.406) * InchtoCm + dx_shole * 2 - dz_pin);
481 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.
PindiodeCreator()
Constructor.
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.