Belle II Software  release-05-01-25
GeoSTRCreator.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2016 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Alexandre BEAULIEU *
7  * *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <structure/geometry/GeoSTRCreator.h>
13 #include "structure/dbobjects/STRGeometryPar.h"
14 
15 #include <geometry/Materials.h>
16 #include <geometry/CreatorFactory.h>
17 #include <geometry/utilities.h>
18 
19 #include <framework/logging/Logger.h>
20 
21 #include <math.h> // PI
22 #include <boost/format.hpp>
23 #include <iostream>
24 #include <fstream>
25 
26 #include <G4NistManager.hh>
27 #include <G4LogicalVolume.hh>
28 #include <G4PVPlacement.hh>
29 #include <G4Polycone.hh>
30 #include <G4VisAttributes.hh>
31 
32 
33 using namespace std;
34 
35 namespace Belle2 {
41  using namespace geometry;
42 
43  namespace structure {
44  //-----------------------------------------------------------------
45  // Register the Creator
46  //-----------------------------------------------------------------
48  geometry::CreatorFactory<GeoSTRCreator> GeoSTRFactory("STRCreator");
49  //-----------------------------------------------------------------
50  // Implementation
51  //-----------------------------------------------------------------
52  GeoSTRCreator::GeoSTRCreator()
53  {
54 
55  }
56 
57 
58  GeoSTRCreator::~GeoSTRCreator()
59  {
60 
61  }
62 
63 
64 
65  void GeoSTRCreator::createGeometry(const STRGeometryPar& parameters, G4LogicalVolume& topVolume, GeometryTypes)
66  {
67 
68 
69 
70 
71  for (int iShield = 0; iShield < parameters.NECLSHIELDS; iShield++) {
72  float _mass = 0;
73  string side;
74  if (iShield == parameters.FWD_ECLSHIELD) {
75  side = "FWD_Shield";
76  } else if (iShield == parameters.BWD_ECLSHIELD) {
77  side = "BWD_Shield";
78  } else {
79  B2FATAL("Only 2 ECL shields should be defined. Can't retrieve info for shield #" << iShield);
80  }
81 
82  int nLayers = parameters.getNLayers(iShield);
83 
84  for (int iLayer = 0; iLayer < nLayers; iLayer++) {
85  G4Material* LayerMat = Materials::get(parameters.getLayerMaterial(iShield, iLayer));
86  int nPlanes = parameters.getLayerNPlanes(iShield, iLayer);
87 
88  //Thread the strings
89  string shapeName = (boost::format("%1%Layer_%2%") % side % (iLayer + 1)).str();
90  string logiVolName = (boost::format("logi%1%Layer_%2%") % side % (iLayer + 1)).str();
91  string physVolName = (boost::format("phys%1%Layer_%2%") % side % (iLayer + 1)).str();
92 
93  G4Polycone* LayerShape = new G4Polycone(shapeName.c_str(), 0, 2 * M_PI, nPlanes,
94  parameters.getLayerPlaneZ(iShield, iLayer),
95  parameters.getLayerPlaneInnerRadius(iShield, iLayer),
96  parameters.getLayerPlaneOuterRadius(iShield, iLayer));
97 
98  // Create logical volume
99  G4LogicalVolume* logiShieldLayer = new G4LogicalVolume(LayerShape, LayerMat, logiVolName, 0, 0, 0);
100 
101  //Place physical volume
102  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logiShieldLayer, physVolName, &topVolume, false, 0);
103 
104  B2DEBUG(1, "Mass of " << side << " layer " << iLayer
105  << " = " << logiShieldLayer->GetMass() / CLHEP::kg << ".kg.");
106 
107  _mass += (logiShieldLayer->GetMass() / CLHEP::kg);
108  }
109 
110  B2DEBUG(1, "Total mass of side " << side << " = " << _mass << " kg");
111  }
112 
113  //Place pole pieces
114  for (int iPole = 0; iPole < parameters.NPOLEPIECES; iPole++) {
115 
116  string side;
117  if (iPole == parameters.FWD_POLEPIECE) {
118  side = "PolePieceR";
119  } else if (iPole == parameters.BWD_POLEPIECE) {
120  side = "PolePieceL";
121  } else {
122  B2FATAL("Only 2 pole pieces should be defined. Can't retrieve info for pole #" << iPole);
123  }
124 
125 
126  G4Material* PoleMat = Materials::get(parameters.getPoleMaterial(iPole));
127  int nPlanes = parameters.getPoleNPlanes(iPole);
128 
129  //Thread the strings
130  string shapeName = (boost::format("%1%") % side).str();
131  string logiVolName = (boost::format("logi%1%") % side).str();
132  string physVolName = (boost::format("phys%1%") % side).str();
133 
134  G4Polycone* PoleShape = new G4Polycone(shapeName.c_str(), 0, 2 * M_PI, nPlanes,
135  parameters.getPolePlaneZ(iPole),
136  parameters.getPolePlaneInnerRadius(iPole),
137  parameters.getPolePlaneOuterRadius(iPole));
138 
139  // Create logical volume
140  G4LogicalVolume* logiPole = new G4LogicalVolume(PoleShape, PoleMat, logiVolName, 0, 0, 0);
141 
142  //Place physical volume
143  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logiPole, physVolName, &topVolume, false, 0);
144 
145  B2DEBUG(1, "Total mass of " << side << " = " << logiPole->GetMass() / CLHEP::kg << " kg");
146  }
147 
148 
149  }
150 
151  STRGeometryPar GeoSTRCreator::createConfiguration(const GearDir& param)
152  {
153  STRGeometryPar strGeometryPar;
154 
155  // Get STR geometry parameters from Gearbox (no calculations here)
156  readShield(param, strGeometryPar, "FWD_Shield");
157  readShield(param, strGeometryPar, "BWD_Shield");
158  readPole(param, strGeometryPar, "PolePieceL");
159  readPole(param, strGeometryPar, "PolePieceR");
160 
161 
162  return strGeometryPar;
163  };
164 
165  void GeoSTRCreator::readPole(const GearDir& content, STRGeometryPar& parameters, std::string side)
166  {
167  // Check if method was called using the correct name for the shields
168  std::size_t foundF = side.find("PolePieceR");
169  std::size_t foundB = side.find("PolePieceL");
170 
171  int iPole = 0;
172  if (foundF != std::string::npos) { iPole = parameters.FWD_POLEPIECE; }
173  else if (foundB != std::string::npos) { iPole = parameters.BWD_POLEPIECE; }
174  else { B2FATAL("No data for the Pole Piece requested " << side << "(not found)");}
175 
176 
177  //Thread the strings
178  std::string polePath = (boost::format("/%1%/") % side).str();
179 
180  // Connect the appropriate Gearbox path
181  GearDir poleContent(content);
182  poleContent.append(polePath);
183 
184  // Retrieve material material
185  parameters.setPoleMaterial(iPole, poleContent.getString("Material", "Air"));
186 
187  // Read the shape parameters
188  const std::vector<GearDir> planes = poleContent.getNodes("Plane");
189  parameters.setPoleNPlanes(iPole, planes.size());
190  B2DEBUG(1, "Number of planes on side " << side << " : " << planes.size());
191 
192  for (unsigned int iPlane = 0; iPlane < planes.size(); iPlane++) {
193  parameters.setPolePlaneZ(iPole, iPlane, planes.at(iPlane).getLength("posZ") / Unit::mm);
194  parameters.setPolePlaneInnerRadius(iPole, iPlane, planes.at(iPlane).getLength("innerRadius") / Unit::mm);
195  parameters.setPolePlaneOuterRadius(iPole, iPlane, planes.at(iPlane).getLength("outerRadius") / Unit::mm);
196 
197  }
198  }
199 
200  void GeoSTRCreator::readShield(const GearDir& content, STRGeometryPar& parameters, std::string side)
201  {
202 
203  // Check if method was called using the correct name for the shields
204  std::size_t foundF = side.find("FWD_Shield");
205  std::size_t foundB = side.find("BWD_Shield");
206 
207  int iShield = 0;
208  if (foundF != std::string::npos) { iShield = parameters.FWD_ECLSHIELD; }
209  else if (foundB != std::string::npos) { iShield = parameters.BWD_ECLSHIELD; }
210  else { B2FATAL("No data for the ECL shield called " << side << "(not found)");}
211 
212 
213  std::string gearPath = (boost::format("%1%/Layers/Layer") % side).str();
214 
215  // Retrieve the number of layers in the shield
216  int nLayers = content.getNumberNodes(gearPath);
217  parameters.setNLayers(iShield, nLayers);
218 
219 
220  for (int iLayer = 0 ; iLayer < nLayers ; ++iLayer) {
221  //Thread the strings
222  std::string layerPath = (boost::format("/%1%[%2%]/") % gearPath % (iLayer + 1)).str();
223 
224  // Connect the appropriate Gearbox path
225  GearDir layerContent(content);
226  layerContent.append(layerPath);
227 
228  // Retrieve material material
229  parameters.setLayerMaterial(iShield, iLayer, layerContent.getString("Material", "Air"));
230 
231  // Read the shape parameters
232  const std::vector<GearDir> planes = layerContent.getNodes("Plane");
233  parameters.setLayerNPlanes(iShield, iLayer, planes.size());
234  B2DEBUG(1, "Number of planes on side " << side << " layer " << iLayer
235  << " : " << planes.size());
236 
237  for (unsigned int iPlane = 0; iPlane < planes.size(); iPlane++) {
238  parameters.setLayerPlaneZ(iShield, iLayer, iPlane, planes.at(iPlane).getLength("posZ") / Unit::mm);
239  parameters.setLayerPlaneInnerRadius(iShield, iLayer, iPlane, planes.at(iPlane).getLength("innerRadius") / Unit::mm);
240  parameters.setLayerPlaneOuterRadius(iShield, iLayer, iPlane, planes.at(iPlane).getLength("outerRadius") / Unit::mm);
241  }
242  }
243  }
244  }
246 }
Belle2::STRGeometryPar
The Class for STR geometry.
Definition: STRGeometryPar.h:35
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::GearDir::append
void append(const std::string &path)
Append something to the current path, modifying the GearDir in place.
Definition: GearDir.h:62
Belle2::GearDir::getString
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition: GearDir.h:79
Belle2::structure::GeoSTRFactory
geometry::CreatorFactory< GeoSTRCreator > GeoSTRFactory("STRCreator")
Create factory instance so that the framework can instantiate the STRCreator.
Belle2::gearbox::Interface::getNodes
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:31
Belle2::geometry::GeometryTypes
GeometryTypes
Flag indiciating the type of geometry to be used.
Definition: GeometryManager.h:39