Belle II Software  release-08-01-10
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 
34 using namespace std;
35 using namespace boost;
36 
37 namespace Belle2 {
43  using namespace geometry;
44 
46  namespace beamabort {
47 
48  // Register the creator
51 
52  BeamabortCreator::BeamabortCreator()
53  {}
54 
55  BeamabortCreator::~BeamabortCreator()
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 }
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.