Belle II Software  release-08-01-10
GeoVXDServiceCreator.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 <vxd/geometry/GeoVXDServiceCreator.h>
10 #include <vxd/geometry/GeoVXDComponents.h>
11 #include <geometry/CreatorFactory.h>
12 #include <geometry/Materials.h>
13 #include <simulation/background/BkgSensitiveDetector.h>
14 #include <framework/gearbox/GearDir.h>
15 #include <framework/logging/Logger.h>
16 #include <G4Transform3D.hh>
17 #include <G4LogicalVolume.hh>
18 #include <G4PVPlacement.hh>
19 #include <G4Tubs.hh>
20 #include <G4Box.hh>
21 #include <map>
22 
23 namespace Belle2 {
28  using namespace geometry;
29  namespace VXD {
30 
33 
35  VXDServiceGeometryPar GeoVXDServiceCreator::createConfiguration(const GearDir& content)
36  {
37  VXDServiceGeometryPar vxdServiceGeometryPar(content.getBool("RecordBackground", false));
38 
39  GearDir content2(content, "DockBoxes");
40 
41  // Read parameters to creates boxes
42  for (const GearDir& boxtype : content2.getNodes("BoxType")) {
43  VXDBoxTypesPar boxtypePar(
44  boxtype.getString("@name"),
45  boxtype.getString("material"),
46  boxtype.getInt("@identifier", 0),
47  boxtype.getLength("width"),
48  boxtype.getLength("length"),
49  boxtype.getLength("height")
50  );
51  vxdServiceGeometryPar.getBoxTypes().push_back(boxtypePar);
52  }
53 
54  // Read paramater to place boxes
55  for (const GearDir& position : content2.getNodes("Position")) {
56  VXDBoxPositionsPar positionPar(
57  position.getString("@name"),
58  position.getLength("minZ"),
59  position.getLength("maxZ"),
60  position.getLength("minR"),
61  position.getLength("maxR"),
62  position.getInt("divisions")
63  );
64  for (const GearDir& slot : position.getNodes("slots")) {
65  VXDSlotsPar slotsPar(slot.getString("@type"));
66  for (const double number : slot.getArray("")) {
67  slotsPar.getSlotNumbers().push_back(number);
68  }
69  positionPar.getSlots().push_back(slotsPar);
70  }
71  vxdServiceGeometryPar.getPositions().push_back(positionPar);
72  }
73 
74  return vxdServiceGeometryPar;
75  }
76 
77  void GeoVXDServiceCreator::createGeometry(const VXDServiceGeometryPar& parameters, G4LogicalVolume& topVolume, GeometryTypes)
78  {
79  m_defaultMaterial = topVolume.GetMaterial();
80  bool active = parameters.getRecordBackground();
81 
82  // Create the Boxes
83  std::map<std::string, VXDGeoComponent> boxes;
84 
85  for (const VXDBoxTypesPar& boxtype : parameters.getBoxTypes()) {
86  VXDGeoComponent box(
87  boxtype.getMaterial(), "",
88  boxtype.getWidth() / 2.0 / Unit::mm, 0,
89  boxtype.getLength() / 2.0 / Unit::mm,
90  boxtype.getHeight() / 2.0 / Unit::mm);
91  const std::string name = boxtype.getName();
92  G4VSolid* shape_box = new G4Box(name, box.getHeight(), box.getWidth(), box.getLength());
93  box.setVolume(new G4LogicalVolume(shape_box, Materials::get(box.getMaterial()), name));
94  B2DEBUG(50, "Created " << name << " DockBox with a mass of " << (box.getVolume()->GetMass(true) / CLHEP::kg) << "kg");
95  if (active) {
96  int identifier = boxtype.getIdentifier();
97  B2DEBUG(50, "Creating BkgSensitiveDetector for DockBox " << name << " with identifier " << identifier);
98  BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(name.c_str(), identifier);
99  box.getVolume()->SetSensitiveDetector(sensitive);
100  }
101  boxes[name] = box;
102  }
103 
104  // Now place the Boxes
105  for (const VXDBoxPositionsPar& position : parameters.getPositions()) {
106  const double minZ = position.getMinZ() / Unit::mm;
107  const double maxZ = position.getMaxZ() / Unit::mm;
108  const double minR = position.getMinR() / Unit::mm;
109  const double maxR = position.getMaxR() / Unit::mm;
110  const int divisions = position.getDivisions();
111  const std::string name = "VXD.DockBoxes." + position.getName();
112 
113  //Boxes are aligned to the side closer to the IP so we need the sign in
114  //which to shift
115  const int signZ = minZ < 0 ? -1 : +1;
116  double startPhiAngle = 0;
117  double deltaAngle = 2 * M_PI;
118  if (signZ > 0) {
119  startPhiAngle = 0.35; // Allow space for He3 tubes in forward envelope
120  deltaAngle = 2 * M_PI - startPhiAngle;
121  }
122  G4VSolid* shape_envelope = new G4Tubs(name, minR, maxR, (maxZ - minZ) / 2.0, startPhiAngle, deltaAngle);
123  G4LogicalVolume* envelope = new G4LogicalVolume(shape_envelope, m_defaultMaterial, name);
124  new G4PVPlacement(G4TranslateZ3D((minZ + maxZ) / 2.0), envelope, name, &topVolume, false, 1);
125  //We have divisions slots with always to slots joining at phi=0
126  //As such, the center phi of one slot is 2pi/divisions*(i+0.5);
127  //We start numbering with i=0 as the slot with the smallest phi>0
128  for (const VXDSlotsPar& slot : position.getSlots()) {
129  const std::string type = slot.getType();
130  const VXDGeoComponent& box = boxes[type];
131  if (!box.getVolume()) B2FATAL("Unknown DockBox type: " << type);
132  for (double number : slot.getSlotNumbers()) {
133  const double angle = (2 * M_PI / divisions) * (number + 0.5);
134  //Position boxes as close to beamline as envelope allows
135  const double r = minR + box.getHeight();
136  //Shift the box as close to the IP as the envelope allows
137  const double z = -signZ * ((maxZ - minZ) / 2.0 - box.getLength());
138  const G4Transform3D placement = G4RotateZ3D(angle) * G4Translate3D(r, 0, z);
139  new G4PVPlacement(placement, box.getVolume(), name + ".box", envelope, false, static_cast<int>(number));
140  }
141  }
142  }
143  }
144  } // VXD namespace
146 } // Belle2 namespace
The Class for BeamBackground Sensitive Detector.
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
static const double mm
[millimeters]
Definition: Unit.h:70
The Class for VXD doc box envelope.
const std::vector< VXDSlotsPar > & getSlots(void) const
Get slots.
The Class for VXD doc box.
Class holding all parameters for an VXD geometry component.
double getWidth() const
get the width of the component
G4LogicalVolume * getVolume() const
get the pointer to the logical volume, NULL if not yet created
double & getHeight()
get the height of the component
const std::string & getMaterial() const
get the name of the Material for the component
void setVolume(G4LogicalVolume *volume)
set the pointer to the logical volume
double getLength() const
get the length of the component
The Class for VXD service geometry.
const std::vector< VXDBoxPositionsPar > & getPositions(void) const
Get positions.
const std::vector< VXDBoxTypesPar > & getBoxTypes(void) const
Get boxes.
The Class for Slot types.
const std::vector< double > & getSlotNumbers(void) const
Get slot numbers.
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:21
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
geometry::CreatorFactory< GeoVXDServiceCreator > GeoVXDServiceFactory("VXDServiceCreator")
Create factory instance so that the framework can instantiate the VXDServiceCreator.
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.