Belle II Software  release-05-01-25
GeoVXDCreator.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2014 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Martin Ritter, Jozef Koval, Benjamin Schwenker *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <vxd/geometry/GeoVXDCreator.h>
12 #include <vxd/geometry/GeoCache.h>
13 #include <vxd/simulation/SensitiveDetector.h>
14 #include <simulation/background/BkgSensitiveDetector.h>
15 
16 #include <geometry/CreatorFactory.h>
17 #include <geometry/Materials.h>
18 #include <geometry/utilities.h>
19 #include <framework/gearbox/GearDir.h>
20 
21 #include <boost/algorithm/string.hpp>
22 #include <boost/format.hpp>
23 
24 #include <G4ReflectionFactory.hh>
25 #include <G4LogicalVolume.hh>
26 #include <G4Trd.hh>
27 #include <G4Trap.hh>
28 #include <G4Box.hh>
29 #include <G4Tubs.hh>
30 #include <G4Polycone.hh>
31 #include <G4PVPlacement.hh>
32 #include <G4AssemblyVolume.hh>
33 #include <G4UserLimits.hh>
34 #include <G4Point3D.hh>
35 
36 #include <G4TessellatedSolid.hh>
37 #include <G4QuadrangularFacet.hh>
38 #include <G4TriangularFacet.hh>
39 
40 #include <CLHEP/Units/PhysicalConstants.h>
41 #include <CLHEP/Units/SystemOfUnits.h>
42 
43 #include <limits>
44 
45 using namespace std;
46 
47 namespace Belle2 {
53  using namespace geometry;
54  namespace VXD {
55 
56  GeoVXDCreator::GeoVXDCreator(const string& prefix) : m_prefix(prefix), m_radiationsensors(prefix)
57  {
58  m_UserLimits.clear();
59  }
60 
62  {
63  //Lets assume that it cannot be that only one part of the vxd gets destroyed
64  // FIXME: This causes problems: VXD::GeoCache::getInstance().clear();
65  //Delete all sensitive detectors
67  delete sensitive;
68  }
69  m_sensitive.clear();
70 
71  for (G4UserLimits* userLimit : m_UserLimits) delete userLimit;
72  m_UserLimits.clear();
73 
74  }
75 
77  vector<VXDGeoPlacement> placements, bool originCenter, bool allowOutside)
78  {
79  GeoVXDAssembly assembly;
80  B2DEBUG(100, "Creating component " << name);
81  vector<VXDGeoComponent> subComponents;
82  subComponents.reserve(placements.size());
83  //Go over all subcomponents and check if they will fit inside.
84  //If component.volume is zero we will create one so sum up needed space
85  bool widthResize = component.getWidth() <= 0;
86  bool lengthResize = component.getLength() <= 0;
87  bool heightResize = component.getHeight() <= 0;
88 
89  for (VXDGeoPlacement& p : placements) {
90  //Test component already exists
91  if (m_componentCache.find(p.getName()) == m_componentCache.end()) {
92  B2FATAL("A component is requested that was not created before!");
93  }
94  VXDGeoComponent sub = m_componentCache[p.getName()];
95 
96  B2DEBUG(100, "SubComponent " << p.getName());
97  B2DEBUG(100, boost::format("Placement: u:%1% cm, v:%2% cm, w:%3% + %4% cm") % p.getU() % p.getV() % p.getW() % p.getWOffset());
98  B2DEBUG(100, boost::format("Dimensions: %1%x%2%x%3% cm") % sub.getWidth() % sub.getLength() % sub.getHeight());
99 
100  if (p.getW() == VXDGeoPlacement::c_above || p.getW() == VXDGeoPlacement::c_below) {
101  //Below placement only valid if we are allowed to create a container around component
102  if (!allowOutside) B2FATAL("Cannot place component " << p.getName() << " outside of component " << name);
103  } else if (sub.getHeight() + p.getWOffset() > component.getHeight()) {
104  //Component will not fit heightwise. If we resize the volume anyway than we don't have problems
105  if (!heightResize) {
106  B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
107  << "height " << sub.getHeight() << " > " << component.getHeight());
108  }
109  component.getHeight() = sub.getHeight() + p.getWOffset();
110  }
111 
112  //Check if compoent will fit inside width,length. If we can resize do it if needed, otherwise bail
113  double minWidth = max(abs(p.getU() + sub.getWidth() / 2.0), abs(p.getU() - sub.getWidth() / 2.0));
114  double minLength = max(abs(p.getV() + sub.getLength() / 2.0), abs(p.getV() - sub.getLength() / 2.0));
115  if (minWidth > component.getWidth() + component.getWidth() * numeric_limits<double>::epsilon()) {
116  if (!widthResize) {
117  B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
118  << "minWidth " << minWidth << " > " << component.getWidth());
119  }
120  component.setWidth(minWidth * 2.0);
121  }
122  if (minLength > component.getLength() + component.getLength() * numeric_limits<double>::epsilon()) {
123  if (!lengthResize) {
124  B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
125  << "minLength " << minLength << " > " << component.getLength());
126  }
127  component.setLength(minLength * 2.0);
128  }
129  subComponents.push_back(sub);
130  }
131 
132  //zero dimensions are fine mathematically but we don't want them in the simulation
133  if (component.getWidth() <= 0 || component.getLength() <= 0 || component.getHeight() <= 0) {
134  B2FATAL("At least one dimension of component " << name << " is zero which does not make sense");
135  }
136 
137  //No volume yet, create a new one automatically assuming air material
138  if (!component.getVolume()) {
139  G4VSolid* componentShape = createTrapezoidal(name, component.getWidth(), component.getWidth2(), component.getLength(),
140  component.getHeight());
141  component.setVolume(new G4LogicalVolume(componentShape, Materials::get(component.getMaterial()), name));
142  }
143 
144  B2DEBUG(100, boost::format("Component %1% dimensions: %2%x%3%x%4% cm") % name % component.getWidth() % component.getLength() %
145  component.getHeight());
146 
147  //Ok, all volumes set up, now add them together
148  for (size_t i = 0; i < placements.size(); ++i) {
149  VXDGeoPlacement& p = placements[i];
150  VXDGeoComponent& s = subComponents[i];
151 
152  G4Transform3D transform = getPosition(component, s, p, originCenter);
153  if (p.getW() == VXDGeoPlacement::c_below || p.getW() == VXDGeoPlacement::c_above) {
154  //Add to selected mother (either component or container around component
155  assembly.add(s.getVolume(), transform);
156  } else {
157  new G4PVPlacement(transform, s.getVolume(), name + "." + p.getName(), component.getVolume(), false, i);
158  }
159  }
160 
161  //Set some visibility options for volume. Done here because all components including sensor go through here
162  if (component.getColor().empty()) {
163  B2DEBUG(200, "Component " << name << " is an Air volume, setting invisible");
164  setVisibility(*component.getVolume(), false);
165  } else {
166  B2DEBUG(200, "Component " << name << " color: " << component.getColor());
167  setColor(*component.getVolume(), component.getColor());
168  }
169  B2DEBUG(100, "--> Created component " << name);
170  //Return the difference in W between the origin of the original component and the including container
171  return assembly;
172  }
173 
174  G4Transform3D GeoVXDCreator::getAlignment(const VXDAlignmentPar& params)
175  {
176  G4RotationMatrix rotation(params.getAlpha(), params.getBeta(), params.getBeta());
177  G4ThreeVector translation(params.getDU() / Unit::mm, params.getDV() / Unit::mm, params.getDW() / Unit::mm);
178  return G4Transform3D(rotation, translation);
179  }
180 
181  G4Transform3D GeoVXDCreator::getPosition(const VXDGeoComponent& mother, const VXDGeoComponent& daughter,
182  const VXDGeoPlacement& placement, bool originCenter)
183  {
184  double u(placement.getU()), v(placement.getV()), w(0);
185  switch (placement.getW()) {
186  case VXDGeoPlacement::c_below: //Place below component
187  w = - mother.getHeight() / 2.0 - daughter.getHeight() / 2.0;
188  break;
189  case VXDGeoPlacement::c_bottom: //Place inside, at bottom of component
190  w = - mother.getHeight() / 2.0 + daughter.getHeight() / 2.0;
191  break;
192  case VXDGeoPlacement::c_center: //Place inside, centered
193  w = 0;
194  break;
195  case VXDGeoPlacement::c_top: //Place inside, at top of mother
196  w = mother.getHeight() / 2.0 - daughter.getHeight() / 2.0;
197  break;
198  case VXDGeoPlacement::c_above: //Place above mother
199  w = mother.getHeight() / 2.0 + daughter.getHeight() / 2.0;
200  break;
201  }
202  if (!originCenter) { //Sensor has coordinate origin in the corner, all submothers at their center
203  u -= mother.getWidth() / 2.0;
204  v -= mother.getLength() / 2.0;
205  }
206  return G4Translate3D(u, v, w + placement.getWOffset());
207  }
208 
209 
210 
211  void GeoVXDCreator::createDiamonds(const VXDGeoRadiationSensorsPar& params, G4LogicalVolume& topVolume,
212  G4LogicalVolume& envelopeVolume)
213  {
214  //Set the correct top volume to either global top or detector envelope
215  G4LogicalVolume* top = &topVolume;
216  if (params.getInsideEnvelope()) {
217  top = &envelopeVolume;
218  }
219 
220  //shape and material are the same for all sensors so create them now
221  const double width = params.getWidth();
222  const double length = params.getLength();
223  const double height = params.getHeight();
224  G4Box* shape = new G4Box("radiationSensorDiamond", width / 2 * CLHEP::cm, length / 2 * CLHEP::cm, height / 2 * CLHEP::cm);
225  G4Material* material = geometry::Materials::get(params.getMaterial());
226 
227  //Now loop over all positions
228  const std::vector<VXDGeoRadiationSensorsPositionPar>& Positions = params.getPositions();
229  for (const VXDGeoRadiationSensorsPositionPar& position : Positions) {
230  //get the radial and z position
231  const double r = position.getRadius();
232  const double z = position.getZ();
233  const double theta = position.getTheta();
234  //and loop over all phi positions
235  const std::map<int, double>& Sensors = position.getSensors();
236  for (const std::pair<const int, double>& sensor : Sensors) {
237  //for (GearDir& sensor : position.getNodes("phi")) {
238  //we need angle and Id
239  const double phi = sensor.second;
240  const int id = sensor.first;
241  //then we create a nice name
242  const std::string name = params.getSubDetector() + ".DiamondSensor." + std::to_string(id);
243  //and create the sensor volume
244  G4LogicalVolume* volume = new G4LogicalVolume(shape, material, name);
245  //add a sensitive detector implementation
246  BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(params.getSubDetector().c_str(), id);
247  volume->SetSensitiveDetector(sensitive);
248  //and place it at the correct position
249  G4Transform3D transform = G4RotateZ3D(phi - M_PI / 2) * G4Translate3D(0, r * CLHEP::cm,
250  z * CLHEP::cm) * G4RotateX3D(-M_PI / 2 - theta);
251  new G4PVPlacement(transform, volume, name, top, false, 1);
252  }
253  }
254  }
255 
256  G4VSolid* GeoVXDCreator::createTrapezoidal(const string& name, double width, double width2, double length, double& height,
257  double angle)
258  {
259  double offset(0);
260  if (angle > 0) {
261  const double tana = tan(angle);
262  height = min(tana * length, min(tana * width, height));
263  offset = height / tana;
264  }
265  const double hwidth = width / 2.0;
266  const double hwidth2 = width2 / 2.0;
267  const double hlength = length / 2.0;
268  const double hheight = height / 2.0;
269 
270  if (width2 <= 0 || width == width2) {
271  if (angle <= 0) {
272  return new G4Box(name, hwidth, hlength, hheight);
273  } else {
274  return new G4Trd(name, hwidth, hwidth - offset, hlength, hlength - offset, hheight);
275  }
276  }
277  //FIXME: offset not working, g4 complains about nonplanarity of face -X. But we do not need that shape at the moment
278  //so lets ignore it for now
279  return new G4Trap(name, hheight, 0, 0, hlength, hwidth, hwidth2, 0, hlength - offset, hwidth - offset, hwidth2 - offset, 0);
280  }
281 
282  G4Transform3D GeoVXDCreator::placeLadder(int ladderID, double phi, G4LogicalVolume* volume,
283  const G4Transform3D& placement,
284  const VXDGeometryPar& parameters)
285  {
286  VxdID ladder(m_ladder.getLayerID(), ladderID, 0);
287 
288  G4Translate3D ladderPos(m_ladder.getRadius(), m_ladder.getShift(), 0);
289  G4Transform3D ladderPlacement = placement * G4RotateZ3D(phi) * ladderPos * getAlignment(parameters.getAlignment(ladder));
290  // The actuall coordinate system of ladder (w still points to Z, there is only phi rotation + move to correct radius + shift)
292 
293 
294  vector<G4Point3D> lastSensorEdge;
295  for (const VXDGeoSensorPlacement& p : m_ladder.getSensors()) {
296  VxdID sensorID(ladder);
297  sensorID.setSensorNumber(p.getSensorID());
298 
299 
300  std::map<string, VXDGeoSensor>::iterator it = m_sensorMap.find(p.getSensorTypeID());
301  if (it == m_sensorMap.end()) {
302  B2FATAL("Invalid SensorTypeID " << p.getSensorTypeID() << ", please check the definition of " << sensorID);
303  }
304  VXDGeoSensor& s = it->second;
305  string name = m_prefix + "." + (string)sensorID;
306 
307  //Calculate the reflection transformation needed. Since we want the
308  //active area to be non reflected we apply this transformation on the
309  //sensor and on the active area
310  G4Transform3D reflection;
311  if (p.getFlipU()) reflection = reflection * G4ReflectX3D();
312  if (p.getFlipV()) reflection = reflection * G4ReflectY3D();
313  if (p.getFlipW()) reflection = reflection * G4ReflectZ3D();
314 
315  G4VSolid* sensorShape = createTrapezoidal(name, s.getWidth() , s.getWidth2() , s.getLength() ,
316  s.getHeight());
317  G4Material* sensorMaterial = Materials::get(s.getMaterial());
318  if (m_onlyActiveMaterial) {
319  s.setVolume(new G4LogicalVolume(sensorShape, Materials::get(m_defaultMaterial), name));
320  } else {
321  s.setVolume(new G4LogicalVolume(sensorShape, sensorMaterial, name));
322  }
323 
324  // Create sensitive Area: this Part is created separately since we want full control over the coordinate system:
325  // local x (called u) should point in RPhi direction
326  // local y (called v) should point in global z
327  // local z (called w) should away from the origin
328  G4VSolid* activeShape = createTrapezoidal(name + ".Active", s.getActiveArea().getWidth(), s.getActiveArea().getWidth2(),
329  s.getActiveArea().getLength(), s.getActiveArea().getHeight());
330 
331  //Create appropriate sensitive detector instance
332  SensitiveDetectorBase* sensitive = createSensitiveDetector(sensorID, s, p);
333 
336  m_sensitive.push_back(sensitive);
337  G4LogicalVolume* active = new G4LogicalVolume(activeShape, sensorMaterial, name + ".Active",
338  0, sensitive);
339  m_UserLimits.push_back(new G4UserLimits(m_activeStepSize));
340  active->SetUserLimits(m_UserLimits.back());
341 
342  setColor(*active, s.getActiveArea().getColor());
343 
344  //The coordinates of the active region are given as the distance between the corners, not to the center
345  //Place the active area
346  G4Transform3D activePosition = G4Translate3D(s.getActiveArea().getWidth() / 2.0, s.getActiveArea().getLength() / 2.0, 0) *
347  getPosition(s, s.getActiveArea(), s.getActivePlacement(), false);
348 
349  G4ReflectionFactory::Instance()->Place(activePosition * reflection, name + ".Active", active, s.getVolume(),
350  false, (int)sensorID, false);
351 
352  //Now create all the other components and place the Sensor
353  GeoVXDAssembly assembly;
354  if (!m_onlyActiveMaterial) assembly = createSubComponents(name, s, s.getComponents() , false, true);
355 
356  G4RotationMatrix rotation(0, -M_PI / 2.0, -M_PI / 2.0);
357  G4Transform3D sensorAlign = getAlignment(parameters.getAlignment(sensorID));
358  G4Transform3D sensorPlacement = G4Rotate3D(rotation) * sensorAlign * reflection;
359 
360  if (s.getSlanted()) {
361  sensorPlacement = G4TranslateX3D(m_ladder.getSlantedRadius() - m_ladder.getRadius()) * G4RotateY3D(
362  -m_ladder.getSlantedAngle()) * sensorPlacement;
363  }
364  sensorPlacement = G4Translate3D(0.0, 0.0, p.getZ()) * sensorPlacement;
365  // Remember the placement of sensor into ladder
366  VXD::GeoCache::getInstance().addSensorPlacement(ladder, sensorID, sensorPlacement * activePosition * reflection);
367  sensorPlacement = ladderPlacement * sensorPlacement;
368 
369  assembly.add(s.getVolume());
370  assembly.place(volume, sensorPlacement);
371 
372  //See if we want to glue the modules together
373  if (!m_ladder.getGlueMaterial().empty() && !m_onlyActiveMaterial) {
374  double u = s.getWidth() / 2.0 + m_ladder.getGlueSize();
375  double v = s.getLength() / 2.0;
376  double w = s.getHeight() / 2.0 + m_ladder.getGlueSize();
377  std::vector<G4Point3D> curSensorEdge(4);
378  //Lets get the forward corners of the sensor by applying the unreflected placement matrix
379  curSensorEdge[0] = sensorPlacement * reflection * G4Point3D(u, v, + w);
380  curSensorEdge[1] = sensorPlacement * reflection * G4Point3D(u, v, - w);
381  curSensorEdge[2] = sensorPlacement * reflection * G4Point3D(-u, v, - w);
382  curSensorEdge[3] = sensorPlacement * reflection * G4Point3D(-u, v, + w);
383  //If we already have backward edges this is not the first module so we can apply the glue
384  if (lastSensorEdge.size()) {
385  //Check that the modules don't overlap in z
386  bool glueOK = true;
387  for (int i = 0; i < 4; ++i) glueOK &= curSensorEdge[i].z() <= lastSensorEdge[i].z();
388  if (!glueOK) {
389  B2WARNING("Cannot place Glue at sensor " + (string)sensorID +
390  " since it overlaps with the last module in z");
391  } else {
392  //Create Glue which spans from last sensor to this sensor
393  G4TessellatedSolid* solidTarget = new G4TessellatedSolid(m_prefix + ".Glue." + (string)sensorID);
394 
395  //Face at end of last Sensor
396  solidTarget->AddFacet(new G4QuadrangularFacet(
397  curSensorEdge[3], curSensorEdge[2], curSensorEdge[1], curSensorEdge[0], ABSOLUTE));
398  //Face at begin of current Sensor
399  solidTarget->AddFacet(new G4QuadrangularFacet(
400  lastSensorEdge[0], lastSensorEdge[1], lastSensorEdge[2], lastSensorEdge[3], ABSOLUTE));
401 
402  //Top faces
403  solidTarget->AddFacet(new G4TriangularFacet(
404  curSensorEdge[3], curSensorEdge[0], lastSensorEdge[0], ABSOLUTE));
405  solidTarget->AddFacet(new G4TriangularFacet(
406  lastSensorEdge[0], lastSensorEdge[3], curSensorEdge[3], ABSOLUTE));
407  //Bottom faces
408  solidTarget->AddFacet(new G4TriangularFacet(
409  curSensorEdge[1], curSensorEdge[2], lastSensorEdge[2], ABSOLUTE));
410  solidTarget->AddFacet(new G4TriangularFacet(
411  lastSensorEdge[2], lastSensorEdge[1], curSensorEdge[1], ABSOLUTE));
412  //Right faces
413  solidTarget->AddFacet(new G4TriangularFacet(
414  curSensorEdge[0], curSensorEdge[1], lastSensorEdge[1], ABSOLUTE));
415  solidTarget->AddFacet(new G4TriangularFacet(
416  lastSensorEdge[1], lastSensorEdge[0], curSensorEdge[0], ABSOLUTE));
417  //Left faces
418  solidTarget->AddFacet(new G4TriangularFacet(
419  curSensorEdge[2], curSensorEdge[3], lastSensorEdge[3], ABSOLUTE));
420  solidTarget->AddFacet(new G4TriangularFacet(
421  lastSensorEdge[3], lastSensorEdge[2], curSensorEdge[2], ABSOLUTE));
422 
423  solidTarget->SetSolidClosed(true);
424 
425  G4LogicalVolume* glue = new G4LogicalVolume(solidTarget, Materials::get(m_ladder.getGlueMaterial()),
426  m_prefix + ".Glue." + (string)sensorID);
427  setColor(*glue, "#097");
428  new G4PVPlacement(G4Transform3D(), glue, m_prefix + ".Glue." + (string)sensorID, volume, false, 1);
429  }
430  }
431  //Remember the backward edge of this sensor to be glued to.
432  lastSensorEdge.resize(4);
433  lastSensorEdge[0] = sensorPlacement * reflection * G4Point3D(u, -v, + w);
434  lastSensorEdge[1] = sensorPlacement * reflection * G4Point3D(u, -v, - w);
435  lastSensorEdge[2] = sensorPlacement * reflection * G4Point3D(-u, -v, - w);
436  lastSensorEdge[3] = sensorPlacement * reflection * G4Point3D(-u, -v, + w);
437  }
438  }
439 
440  return ladderPlacement;
441  }
442 
443  void GeoVXDCreator::setCurrentLayer(int layer, const VXDGeometryPar& parameters)
444  {
445  const VXDGeoLadderPar& paramsLadder = parameters.getLadder(layer);
446 
448  layer,
449  paramsLadder.getShift() / Unit::mm,
450  paramsLadder.getRadius() / Unit::mm,
451  paramsLadder.getSlantedAngle(),
452  paramsLadder.getSlantedRadius() / Unit::mm,
453  paramsLadder.getGlueSize() / Unit::mm,
454  paramsLadder.getGlueMaterial()
455  );
456 
457 
458  for (const VXDGeoSensorPlacementPar& sensorInfo : paramsLadder.getSensors()) {
460  sensorInfo.getSensorID(),
461  sensorInfo.getSensorTypeID(),
462  sensorInfo.getZ() / Unit::mm,
463  sensorInfo.getFlipU(),
464  sensorInfo.getFlipV(),
465  sensorInfo.getFlipW()
466  ));
467  }
468  }
469 
470 
471 
472  void GeoVXDCreator::readLadderComponents(int layerID, int ladderID, GearDir content, VXDGeometryPar& vxdGeometryPar)
473  {
474  VxdID ladder(layerID, ladderID, 0);
475 
476  // Read alignment for ladder
477  string path = (boost::format("Align[@component='%1%']/") % ladder).str();
478  GearDir params(GearDir(content, "Alignment/"), path);
479  if (!params) {
480  B2WARNING("Could not find alignment parameters for ladder " << ladder);
481  return;
482  }
483  vxdGeometryPar.getAlignmentMap()[ladder] = VXDAlignmentPar(params.getLength("du"),
484  params.getLength("dv"),
485  params.getLength("dw"),
486  params.getAngle("alpha"),
487  params.getAngle("beta"),
488  params.getAngle("gamma")
489  );
490 
491 
492 
493  for (const VXDGeoSensorPlacementPar& p : vxdGeometryPar.getLadderMap()[layerID].getSensors()) {
494  VxdID sensorID(ladder);
495  sensorID.setSensorNumber(p.getSensorID());
496 
497  std::map<string, VXDGeoSensorPar>::iterator it = vxdGeometryPar.getSensorMap().find(p.getSensorTypeID());
498  if (it == vxdGeometryPar.getSensorMap().end()) {
499  B2FATAL("Invalid SensorTypeID " << p.getSensorTypeID() << ", please check the definition of " << sensorID);
500  }
501 
502  //Now create all the other components and place the Sensor
503  if (!vxdGeometryPar.getGlobalParams().getOnlyActiveMaterial()) {
504  VXDGeoSensorPar& s = it->second;
505  readSubComponents(s.getComponents() , GearDir(content, "Components/"), vxdGeometryPar);
506  }
507  // Read alignment for sensor
508  string pathSensor = (boost::format("Align[@component='%1%']/") % sensorID).str();
509  GearDir paramsSensor(GearDir(content, "Alignment/"), pathSensor);
510  if (!paramsSensor) {
511  B2WARNING("Could not find alignment parameters for sensorID " << sensorID);
512  return;
513  }
514  vxdGeometryPar.getAlignmentMap()[sensorID] = VXDAlignmentPar(paramsSensor.getLength("du"),
515  paramsSensor.getLength("dv"),
516  paramsSensor.getLength("dw"),
517  paramsSensor.getAngle("alpha"),
518  paramsSensor.getAngle("beta"),
519  paramsSensor.getAngle("gamma")
520  );
521  }
522  return;
523  }
524 
525  void GeoVXDCreator::readSubComponents(const std::vector<VXDGeoPlacementPar>& placements , const GearDir& componentsDir,
526  VXDGeometryPar& vxdGeometryPar)
527  {
528  for (const VXDGeoPlacementPar& p : placements) {
529  readComponent(p.getName(), componentsDir, vxdGeometryPar);
530  }
531  return;
532  }
533 
534  void GeoVXDCreator::readComponent(const std::string& name, GearDir componentsDir, VXDGeometryPar& vxdGeometryPar)
535  {
536 
537 
538  //Check if component already exists
539  if (vxdGeometryPar.getComponentMap().find(name) != vxdGeometryPar.getComponentMap().end()) {
540  return; // nothing to do
541  }
542 
543  //Component does not exist, so lets create a new one
544  string path = (boost::format("descendant::Component[@name='%1%']/") % name).str();
545  GearDir params(componentsDir, path);
546  if (!params) {
547  B2FATAL("Could not find definition for component " << name);
548  return;
549  }
550 
552  params.getString("Material", vxdGeometryPar.getGlobalParams().getDefaultMaterial()),
553  params.getString("Color", ""),
554  params.getLength("width", 0),
555  params.getLength("width2", 0),
556  params.getLength("length", 0),
557  params.getLength("height", 0),
558  params.getAngle("angle", 0)
559  );
560 
561  if (c.getWidth() <= 0 || c.getLength() <= 0 || c.getHeight() <= 0) {
562  B2DEBUG(100, "One dimension empty, using auto resize for component");
563  }
564 
565  c.setSubComponents(getSubComponents(params));
566  readSubComponents(c.getSubComponents(), componentsDir, vxdGeometryPar);
567 
568  if (vxdGeometryPar.getGlobalParams().getActiveChips() && params.exists("activeChipID")) {
569  int chipID = params.getInt("activeChipID");
570  vxdGeometryPar.getSensitiveChipIdMap()[name] = chipID;
571  }
572  vxdGeometryPar.getComponentMap()[name] = c;
573  vxdGeometryPar.getComponentInsertOder().push_back(name);
574  }
575 
576  void GeoVXDCreator::readLadder(int layer, GearDir components, VXDGeometryPar& geoparameters)
577  {
578  string path = (boost::format("Ladder[@layer=%1%]/") % layer).str();
579  GearDir paramsLadder(components, path);
580  if (!paramsLadder) {
581  B2FATAL("Could not find Ladder definition for layer " << layer);
582  }
583 
584  geoparameters.getLadderMap()[layer] = VXDGeoLadderPar(
585  layer,
586  paramsLadder.getLength("shift"),
587  paramsLadder.getLength("radius"),
588  paramsLadder.getAngle("slantedAngle", 0),
589  paramsLadder.getLength("slantedRadius", 0),
590  paramsLadder.getLength("Glue/oversize", 0),
591  paramsLadder.getString("Glue/Material", "")
592  );
593 
594  for (const GearDir& sensorInfo : paramsLadder.getNodes("Sensor")) {
595 
596  geoparameters.getLadderMap()[layer].addSensor(VXDGeoSensorPlacementPar(
597  sensorInfo.getInt("@id"),
598  sensorInfo.getString("@type"),
599  sensorInfo.getLength("."),
600  sensorInfo.getBool("@flipU", false),
601  sensorInfo.getBool("@flipV", false),
602  sensorInfo.getBool("@flipW", false)
603  ));
604  }
605  }
606 
607  std::vector<VXDGeoPlacementPar> GeoVXDCreator::getSubComponents(const GearDir& path)
608  {
609  vector<VXDGeoPlacementPar> result;
610  for (const GearDir& component : path.getNodes("Component")) {
611  string type;
612  if (!component.exists("@type")) {
613  type = component.getString("@name");
614  } else {
615  type = component.getString("@type");
616  }
617  int nPos = max(component.getNumberNodes("u"), component.getNumberNodes("v"));
618  nPos = max(nPos, component.getNumberNodes("w"));
619  nPos = max(nPos, component.getNumberNodes("woffset"));
620  for (int iPos = 1; iPos <= nPos; ++iPos) {
621  string index = (boost::format("[%1%]") % iPos).str();
622  result.push_back(VXDGeoPlacementPar(
623  type,
624  component.getLength("u" + index, 0),
625  component.getLength("v" + index, 0),
626  component.getString("w" + index, "bottom"),
627  component.getLength("woffset" + index, 0)
628  ));
629  }
630  }
631  return result;
632  }
633 
634  } // namespace VXD
636 } // namespace Belle2
Belle2::VXD::GeoVXDCreator::getAlignment
G4Transform3D getAlignment(const VXDAlignmentPar &params)
Get Alignment from paylead object.
Definition: GeoVXDCreator.cc:174
Belle2::VXDGeoLadder::getSlantedAngle
double getSlantedAngle() const
get the slant angle for slanted sensors
Definition: GeoVXDComponents.h:204
Belle2::VXDGeometryPar
The Class for VXD geometry.
Definition: VXDGeometryPar.h:46
Belle2::VXDGeoSensorPlacement
Struct holding the information where a sensor should be placed inside the ladder.
Definition: GeoVXDComponents.h:154
Belle2::VXD::GeoVXDCreator::getPosition
G4Transform3D getPosition(const VXDGeoComponent &mother, const VXDGeoComponent &daughter, const VXDGeoPlacement &placement, bool originCenter)
Return the position where a daughter component is to be placed.
Definition: GeoVXDCreator.cc:181
Belle2::VXD::GeoVXDCreator::placeLadder
G4Transform3D placeLadder(int ladderID, double phi, G4LogicalVolume *volume, const G4Transform3D &placement, const VXDGeometryPar &parameters)
Place ladder corresponding to the given ladder id into volume setLayer has to be called first to set ...
Definition: GeoVXDCreator.cc:282
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::VXDGeoPlacement::getU
double getU() const
get local u coordinate where to place the component
Definition: GeoVXDComponents.h:44
Belle2::VXDAlignmentPar
The Class for VXD Alignment payload.
Definition: VXDAlignmentPar.h:33
Belle2::VXD::GeoVXDCreator::createSubComponents
GeoVXDAssembly createSubComponents(const std::string &name, VXDGeoComponent &component, std::vector< VXDGeoPlacement > placements, bool originCenter=true, bool allowOutside=false)
Place a list of subcomponents into an component.
Definition: GeoVXDCreator.cc:76
Belle2::geometry::setColor
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition: utilities.cc:107
Belle2::VXDGeoPlacement::c_center
@ c_center
Place the component at the center of the mother.
Definition: GeoVXDComponents.h:34
Belle2::VXD::GeoVXDCreator::getSubComponents
std::vector< VXDGeoPlacementPar > getSubComponents(const GearDir &path)
Return vector of VXDGeoPlacements with all the components defined inside a given path.
Definition: GeoVXDCreator.cc:607
Belle2::gearbox::Interface::getAngle
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
Definition: Interface.h:301
Belle2::VXDGeoPlacement
Class holding all parameters to place a VXD geometry subcomponent.
Definition: GeoVXDComponents.h:28
Belle2::VXDGeoLadderPar
The Class for VXD Ladder payload.
Definition: VXDGeoLadderPar.h:39
Belle2::VXD::GeoVXDCreator::readComponent
void readComponent(const std::string &name, GearDir components, VXDGeometryPar &vxdGeometryPar)
Read parameters for component name from Gearbox into geometry payload.
Definition: GeoVXDCreator.cc:534
Belle2::VXDGeoLadder::getSensors
const std::vector< VXDGeoSensorPlacement > & getSensors() const
get list of sensors
Definition: GeoVXDComponents.h:212
Belle2::VXDGeoLadderPar::getSensors
const std::vector< VXDGeoSensorPlacementPar > & getSensors() const
get list of sensors
Definition: VXDGeoLadderPar.h:80
Belle2::VXDGeometryPar::getComponentMap
const std::map< std::string, VXDGeoComponentPar > & getComponentMap() const
get component maps
Definition: VXDGeometryPar.h:88
Belle2::VXDGeoSensorPar
The Class for VXD Sensor payload.
Definition: VXDGeoSensorPar.h:39
Belle2::VXDGeometryPar::getSensorMap
const std::map< std::string, VXDGeoSensorPar > & getSensorMap() const
get sensor map
Definition: VXDGeometryPar.h:84
Belle2::VXDGeoPlacement::c_below
@ c_below
Place the component below the mother.
Definition: GeoVXDComponents.h:32
Belle2::VXDGeoPlacementPar
The Class for VXD placement payload.
Definition: VXDGeoPlacementPar.h:36
Belle2::VXD::SensitiveDetectorBase
Base class for Sensitive Detector implementation of PXD and SVD.
Definition: SensitiveDetectorBase.h:47
Belle2::VXDGeometryPar::getGlobalParams
const VXDGlobalPar & getGlobalParams() const
get global parameters
Definition: VXDGeometryPar.h:56
Belle2::VXD::GeoCache::addSensorPlacement
void addSensorPlacement(VxdID ladder, VxdID sensor, const G4Transform3D &placement)
Remember how sensor is placed into ladder.
Definition: GeoCache.cc:221
Belle2::Simulation::SensitiveDetectorBase
Base class for all Sensitive Detectors to create hits during simulation.
Definition: SensitiveDetectorBase.h:32
Belle2::VXDGeoLadderPar::getGlueMaterial
const std::string & getGlueMaterial() const
get the glue material
Definition: VXDGeoLadderPar.h:76
Belle2::VXD::GeoVXDCreator::m_componentCache
std::map< std::string, VXDGeoComponent > m_componentCache
Cache of all previously created components.
Definition: GeoVXDCreator.h:187
Belle2::VXD::GeoVXDCreator::m_onlyActiveMaterial
bool m_onlyActiveMaterial
If this is true, only active Materials will be placed for tracking studies.
Definition: GeoVXDCreator.h:215
Belle2::BkgSensitiveDetector
The Class for BeamBackground Sensitive Detector.
Definition: BkgSensitiveDetector.h:34
Belle2::VXDGeoPlacement::getWOffset
double getWOffset() const
get offset to local w position where to place the component
Definition: GeoVXDComponents.h:50
Belle2::VXD::GeoVXDCreator::m_sensorMap
std::map< std::string, VXDGeoSensor > m_sensorMap
Map containing Information about all defined sensor types.
Definition: GeoVXDCreator.h:189
Belle2::VXDGlobalPar::getActiveChips
bool getActiveChips() const
Get whether chips are sensitive
Definition: VXDGlobalPar.h:58
Belle2::VXDGeoLadder::getGlueMaterial
const std::string & getGlueMaterial() const
get the glue material
Definition: GeoVXDComponents.h:210
Belle2::VXD::GeoVXDCreator::createDiamonds
void createDiamonds(const VXDGeoRadiationSensorsPar &params, G4LogicalVolume &topVolume, G4LogicalVolume &envelopeVolume)
Create diamond radiation sensors.
Definition: GeoVXDCreator.cc:211
Belle2::geometry::Materials::get
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:65
Belle2::VXD::GeoVXDAssembly
Class to group some Geant4 volumes and place them all at once with a given transformation matrix.
Definition: GeoVXDAssembly.h:31
Belle2::VXD::GeoCache::addLadderPlacement
void addLadderPlacement(VxdID halfShell, VxdID ladder, const G4Transform3D &placement)
Remember how ladder is placed into half-shell.
Definition: GeoCache.cc:226
Belle2::VXDGeoRadiationSensorsPar
The Class for VXD Radiation Sensor parameters.
Definition: VXDGeoRadiationSensorsPar.h:77
Belle2::VXD::GeoVXDCreator::m_minimumElectrons
float m_minimumElectrons
minimum number of electrons to be deposited by a particle to be saved
Definition: GeoVXDCreator.h:204
Belle2::VXD::GeoVXDCreator::m_ladder
VXDGeoLadder m_ladder
Parameters of the currently active ladder.
Definition: GeoVXDCreator.h:191
Belle2::VXDGeoLadder::getGlueSize
double getGlueSize() const
get the additional glue size, e.g.
Definition: GeoVXDComponents.h:208
Belle2::VXD::GeoVXDCreator::m_sensitive
std::vector< Simulation::SensitiveDetectorBase * > m_sensitive
List to all created sensitive detector instances.
Definition: GeoVXDCreator.h:193
Belle2::VXD::GeoVXDCreator::m_electronTolerance
float m_electronTolerance
tolerance for the energy deposition in electrons to be merged in a single step
Definition: GeoVXDCreator.h:202
Belle2::VXDGeoPlacement::c_bottom
@ c_bottom
Place the component at the bottom of the mother.
Definition: GeoVXDComponents.h:33
Belle2::VXD::GeoVXDCreator::readLadder
virtual void readLadder(int layer, GearDir components, VXDGeometryPar &geoparameters)
Read parameters for a ladder in layer with given ID from gearbox and layer store them in payload.
Definition: GeoVXDCreator.cc:576
Belle2::VXDGeoPlacement::c_top
@ c_top
Place the component at the top of the mother.
Definition: GeoVXDComponents.h:35
Belle2::VXD::GeoVXDCreator::m_onlyPrimaryTrueHits
bool m_onlyPrimaryTrueHits
If true only create TrueHits from primary particles and ignore secondaries.
Definition: GeoVXDCreator.h:212
Belle2::VXDGeoLadderPar::getSlantedRadius
double getSlantedRadius() const
get the radius for slanted sensors
Definition: VXDGeoLadderPar.h:68
Belle2::VXDGeoLadder::getRadius
double getRadius() const
get the radius of all sensors except slanted ones
Definition: GeoVXDComponents.h:202
Belle2::VXDGeometryPar::getSensitiveChipIdMap
std::map< std::string, int > & getSensitiveChipIdMap()
get sensitive chip id map
Definition: VXDGeometryPar.h:94
Belle2::VXD::GeoVXDCreator::m_seeNeutrons
bool m_seeNeutrons
Make sensitive detectors also see neutrons.
Definition: GeoVXDCreator.h:210
Belle2::VXD::GeoCache::getInstance
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:215
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::VXDGeometryPar::getLadderMap
std::map< int, VXDGeoLadderPar > & getLadderMap()
get ladder map
Definition: VXDGeometryPar.h:76
Belle2::geometry::setVisibility
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition: utilities.cc:115
Belle2::VXDGeoLadderPar::getSlantedAngle
double getSlantedAngle() const
get the slant angle for slanted sensors
Definition: VXDGeoLadderPar.h:64
Belle2::VXDGlobalPar::getDefaultMaterial
std::string getDefaultMaterial() const
Get default material.
Definition: VXDGlobalPar.h:69
Belle2::VXD::GeoVXDCreator::createSensitiveDetector
virtual SensitiveDetectorBase * createSensitiveDetector(VxdID sensorID, const VXDGeoSensor &sensor, const VXDGeoSensorPlacement &placement)=0
Return a SensitiveDetector implementation for a given sensor.
Belle2::PXD::Sensors
std::map< VxdID, Sensor > Sensors
Map of all hits in all Sensors.
Definition: PXDDigitizerModule.h:91
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::VXD::GeoVXDCreator::m_distanceTolerance
float m_distanceTolerance
tolerance for Geant4 steps to be merged to a single step
Definition: GeoVXDCreator.h:200
Belle2::VXDGeoLadderPar::getRadius
double getRadius() const
get the radius of all sensors except slanted ones
Definition: VXDGeoLadderPar.h:60
Belle2::VXDGeometryPar::getComponentInsertOder
const std::vector< std::string > & getComponentInsertOder() const
get component insert order
Definition: VXDGeometryPar.h:96
Belle2::VXD::GeoVXDCreator::m_defaultMaterial
std::string m_defaultMaterial
Name of the Material to be used for Air.
Definition: GeoVXDCreator.h:198
Belle2::VxdID::setSensorNumber
void setSensorNumber(baseType sensor)
Set the sensor id.
Definition: VxdID.h:121
Belle2::VXDGeoLadder
Struct containing all parameters of one ladder.
Definition: GeoVXDComponents.h:188
Belle2::VXD::GeoVXDCreator::m_prefix
std::string m_prefix
Prefix to prepend to all volume names.
Definition: GeoVXDCreator.h:180
Belle2::VXD::GeoVXDAssembly::add
void add(G4LogicalVolume *volume, const G4Transform3D &transform=G4Transform3D())
Add a volume to the assembly.
Definition: GeoVXDAssembly.h:46
Belle2::VXD::SensitiveDetectorBase::setOptions
void setOptions(bool seeNeutrons, bool onlyPrimaryTrueHits, float distanceTolerance, float electronTolerance, float minimumElectrons)
Set all common options.
Definition: SensitiveDetectorBase.h:70
Belle2::VXD::GeoVXDCreator::m_activeStepSize
double m_activeStepSize
Stepsize to be used inside active volumes.
Definition: GeoVXDCreator.h:206
Belle2::VXDGlobalPar::getOnlyActiveMaterial
bool getOnlyActiveMaterial() const
Get whether only active materials will be placed for tracking studies.
Definition: VXDGlobalPar.h:65
Belle2::gearbox::Interface::getLength
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:261
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::Unit::mm
static const double mm
[millimeters]
Definition: Unit.h:80
Belle2::VXDGeoLadderPar::getShift
double getShift() const
get the shift along the u coordinate for all sensors in the ladder
Definition: VXDGeoLadderPar.h:56
Belle2::VXDGeoPlacement::c_above
@ c_above
Place the component above the mother.
Definition: GeoVXDComponents.h:36
Belle2::VXDGeoSensor
Struct holding all parameters for a completeVXD Sensor.
Definition: GeoVXDComponents.h:112
Belle2::VXDGeoComponentPar
The Class for VXD geometry component.
Definition: VXDGeoComponentPar.h:36
Belle2::VXDGeoSensorPlacementPar
The Class for VXD Sensor Placement payload.
Definition: VXDGeoSensorPlacementPar.h:37
Belle2::VXD::GeoVXDCreator::m_UserLimits
std::vector< G4UserLimits * > m_UserLimits
Vector of G4UserLimit pointers.
Definition: GeoVXDCreator.h:217
Belle2::VXD::GeoVXDCreator::createTrapezoidal
G4VSolid * createTrapezoidal(const std::string &name, double width, double width2, double length, double &height, double angle=0)
Create a trapezoidal solid.
Definition: GeoVXDCreator.cc:256
Belle2::VXDGeoPlacement::getW
EPosW getW() const
get local w position where to place the component
Definition: GeoVXDComponents.h:48
Belle2::VXDGeoLadderPar::getGlueSize
double getGlueSize() const
get the additional glue size, e.g.
Definition: VXDGeoLadderPar.h:72
Belle2::VXDGeoLadder::getShift
double getShift() const
get the shift along the u coordinate for all sensors in the ladder
Definition: GeoVXDComponents.h:200
Belle2::VXD::GeoVXDCreator::setCurrentLayer
virtual void setCurrentLayer(int layer, const VXDGeometryPar &parameters)
Read parameters for given layer and store in m_ladder.
Definition: GeoVXDCreator.cc:443
Belle2::VXDGeoLadder::getLayerID
int getLayerID() const
get the layer id
Definition: GeoVXDComponents.h:198
Belle2::VXD::GeoVXDCreator::m_halfShellVxdIDs
std::map< std::string, Belle2::VxdID > m_halfShellVxdIDs
Used for translation of half-shell name into a VxdID to consitently handle it in hierarchy.
Definition: GeoVXDCreator.h:221
Belle2::VXD::GeoVXDAssembly::place
void place(G4LogicalVolume *mother, const G4Transform3D &transform)
Place all the volumes already added to the assembly in the given mother.
Definition: GeoVXDAssembly.cc:32
Belle2::VXD::GeoVXDCreator::~GeoVXDCreator
virtual ~GeoVXDCreator()
The destructor of the GeoVXDCreator class.
Definition: GeoVXDCreator.cc:61
Belle2::VXD::GeoVXDCreator::readSubComponents
void readSubComponents(const std::vector< VXDGeoPlacementPar > &placements, const GearDir &componentsDir, VXDGeometryPar &vxdGeometryPar)
Read parameters for all components in placement container from Gearbox into payload.
Definition: GeoVXDCreator.cc:525
Belle2::VXDGeoLadder::addSensor
void addSensor(const VXDGeoSensorPlacement &sensor)
add a sensor to the list of sensors in the ladder
Definition: GeoVXDComponents.h:214
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::VXDGeoComponent
Class holding all parameters for an VXD geometry component.
Definition: GeoVXDComponents.h:65
Belle2::VXD::GeoVXDCreator::m_currentHalfShell
std::string m_currentHalfShell
Current half-shell being processed (need to know ladder parent for hierarchy)
Definition: GeoVXDCreator.h:219
Belle2::VXD::GeoVXDCreator::readLadderComponents
virtual void readLadderComponents(int layerID, int ladderID, GearDir content, VXDGeometryPar &vxdGeometryPar)
Read parameters for ladder components and their alignment corresponding to the given ladder id.
Definition: GeoVXDCreator.cc:472
Belle2::VXDGeoPlacement::getV
double getV() const
get local v coordinate where to place the component
Definition: GeoVXDComponents.h:46
Belle2::VXDGeoRadiationSensorsPositionPar
The Class for VXD Radiation Sensor Position parameters.
Definition: VXDGeoRadiationSensorsPar.h:36
Belle2::VXDGeometryPar::getAlignmentMap
std::map< std::string, VXDAlignmentPar > & getAlignmentMap()
get alignmant map
Definition: VXDGeometryPar.h:68
Belle2::VXDGeoLadder::getSlantedRadius
double getSlantedRadius() const
get the radius for slanted sensors
Definition: GeoVXDComponents.h:206