DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
PolyhedraBarrelCalorimeter2_geo.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 //
14 // Specialized generic detector constructor
15 //
16 //==========================================================================
18 #include "XML/Layering.h"
19 
20 using namespace std;
21 using namespace dd4hep;
22 using namespace dd4hep::detail;
23 
24 static void placeStaves(DetElement& parent, DetElement& stave, double rmin, int numsides, double total_thickness,
25  Volume envelopeVolume, double innerAngle, Volume sectVolume) {
26  double innerRotation = innerAngle;
27  double offsetRotation = -innerRotation / 2;
28  double sectCenterRadius = rmin + total_thickness / 2;
29  double rotX = M_PI / 2;
30  double rotY = -offsetRotation;
31  double posX = -sectCenterRadius * std::sin(rotY);
32  double posY = sectCenterRadius * std::cos(rotY);
33 
34  for (int module = 1; module <= numsides; ++module) {
35  DetElement det = module > 1 ? stave.clone(_toString(module,"stave%d")) : stave;
36  Transform3D trafo(RotationZYX(0, rotY, rotX), Translation3D(-posX, -posY, 0));
37  PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,trafo);
38  // Not a valid volID: pv.addPhysVolID("stave", 0);
39  pv.addPhysVolID("module", module);
40  det.setPlacement(pv);
41  parent.add(det);
42  rotY -= innerRotation;
43  posX = -sectCenterRadius * std::sin(rotY);
44  posY = sectCenterRadius * std::cos(rotY);
45  }
46 }
47 
48 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
49  xml_det_t x_det = e;
50  Layering layering(x_det);
51  xml_comp_t staves = x_det.staves();
52  xml_dim_t dim = x_det.dimensions();
53  string det_name = x_det.nameStr();
54  Material air = description.air();
55  double totalThickness = layering.totalThickness();
56  double gap = xml_dim_t(x_det).gap();
57  int numSides = dim.numsides();
58  double detZ = dim.z();
59  double rmin = dim.rmin();
60  DetElement sdet(det_name, x_det.id());
61  DetElement stave("stave1", x_det.id());
62  Volume motherVol = description.pickMotherVolume(sdet);
63 
64 #if 0
65  int totalRepeat = 0;
66  int totalSlices = 0;
67  for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
68  xml_comp_t x_layer = c;
69  int repeat = x_layer.repeat();
70  totalRepeat += repeat;
71  totalSlices += x_layer.numChildren(_U(slice));
72  }
73 #endif
74  PolyhedraRegular polyhedra(numSides, rmin, rmin + totalThickness, detZ);
75  Volume envelopeVol(det_name, polyhedra, air);
76 
77  // Add the subdetector envelope to the structure.
78  double innerAngle = 2 * M_PI / numSides;
79  double halfInnerAngle = innerAngle / 2;
80  double tan_inner = std::tan(halfInnerAngle) * 2;
81  double innerFaceLen = rmin * tan_inner;
82  double outerFaceLen = (rmin + totalThickness) * tan_inner;
83  double staveThickness = totalThickness;
84 
85  Trapezoid staveTrdOuter(innerFaceLen / 2, outerFaceLen / 2, detZ / 2, detZ / 2, staveThickness / 2);
86  Volume staveOuterVol("stave_outer", staveTrdOuter, air);
87 
88  Trapezoid staveTrdInner(innerFaceLen / 2 - gap, outerFaceLen / 2 - gap, detZ / 2, detZ / 2, staveThickness / 2);
89  Volume staveInnerVol("stave_inner", staveTrdInner, air);
90 
91  double layerOuterAngle = (M_PI - innerAngle) / 2;
92  double layerInnerAngle = (M_PI / 2 - layerOuterAngle);
93  double layer_pos_z = -(staveThickness / 2);
94  double layer_dim_x = innerFaceLen / 2 - gap * 2;
95  int layer_num = 1;
96 
97  //#### LayeringExtensionImpl* layeringExtension = new LayeringExtensionImpl();
98  //#### Position layerNormal(0,0,1);
99 
100  for (xml_coll_t xc(x_det, _U(layer)); xc; ++xc) {
101  xml_comp_t x_layer = xc;
102  int repeat = x_layer.repeat(); // Get number of times to repeat this layer.
103  const Layer* lay = layering.layer(layer_num - 1); // Get the layer from the layering engine.
104  // Loop over repeats for this layer.
105  for (int j = 0; j < repeat; j++) {
106  string layer_name = _toString(layer_num, "layer%d");
107  double layer_thickness = lay->thickness();
108  DetElement layer(stave, layer_name, layer_num);
109  //### layeringExtension->setLayer(layer_num, layer, layerNormal);
110 
111  // Layer position in Z within the stave.
112  layer_pos_z += layer_thickness / 2;
113  // Layer box & volume
114  Volume layer_vol(layer_name, Box(layer_dim_x, detZ / 2, layer_thickness / 2), air);
115 
116  // Create the slices (sublayers) within the layer.
117  double slice_pos_z = -(layer_thickness / 2);
118  int slice_number = 1;
119  for (xml_coll_t xk(x_layer, _U(slice)); xk; ++xk) {
120  xml_comp_t x_slice = xk;
121  string slice_name = _toString(slice_number, "slice%d");
122  double slice_thickness = x_slice.thickness();
123  Material slice_material = description.material(x_slice.materialStr());
124  DetElement slice(layer, slice_name, slice_number);
125 
126  slice_pos_z += slice_thickness / 2;
127  // Slice volume & box
128  Volume slice_vol(slice_name, Box(layer_dim_x, detZ / 2, slice_thickness / 2), slice_material);
129 
130  if (x_slice.isSensitive()) {
131  sens.setType("calorimeter");
132  slice_vol.setSensitiveDetector(sens);
133  }
134  // Set region, limitset, and vis.
135  slice_vol.setAttributes(description, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
136  // slice PlacedVolume
137  PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
138  slice_phv.addPhysVolID("slice", slice_number);
139 
140  slice.setPlacement(slice_phv);
141  // Increment Z position for next slice.
142  slice_pos_z += slice_thickness / 2;
143  // Increment slice number.
144  ++slice_number;
145  }
146  // Set region, limitset, and vis.
147  layer_vol.setAttributes(description, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
148 
149  // Layer physical volume.
150  PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol, Position(0, 0, layer_pos_z));
151  layer_phv.addPhysVolID("layer", layer_num);
152  layer.setPlacement(layer_phv);
153 
154  // Increment the layer X dimension.
155  layer_dim_x += layer_thickness * std::tan(layerInnerAngle); // * 2;
156  // Increment the layer Z position.
157  layer_pos_z += layer_thickness / 2;
158  // Increment the layer number.
159  ++layer_num;
160  }
161  }
162 
163  // Add stave inner physical volume to outer stave volume.
164  staveOuterVol.placeVolume(staveInnerVol);
165  if ( staves ) {
166  // Set the vis attributes of the outer stave section.
167  stave.setVisAttributes(description, staves.visStr(), staveInnerVol);
168  stave.setVisAttributes(description, staves.visStr(), staveOuterVol);
169  }
170  // Place the staves.
171  placeStaves(sdet, stave, rmin, numSides, totalThickness, envelopeVol, innerAngle, staveOuterVol);
172  // Set envelope volume attributes.
173  envelopeVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
174 
175  double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0;
176  Transform3D transform(RotationZ(M_PI / numSides), Translation3D(0, 0, z_offset));
177  PlacedVolume env_phv = motherVol.placeVolume(envelopeVol, transform);
178  env_phv.addPhysVolID("system", sdet.id());
179  env_phv.addPhysVolID("barrel", 0);
180  sdet.setPlacement(env_phv);
181 
182  //#### sdet.addExtension<SubdetectorExtension>(new SubdetectorExtensionImpl(sdet));
183  //#### sdet.addExtension<LayeringExtension>(layeringExtension);
184  return sdet;
185 }
186 
187 DECLARE_DETELEMENT(DD4hep_PolyhedraBarrelCalorimeter2, create_detector)
dd4hep::xml::Collection_t
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:636
dd4hep::PolyhedraRegular
Class describing a regular polyhedron shape.
Definition: Shapes.h:1493
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:44
DECLARE_DETELEMENT
#define DECLARE_DETELEMENT(name, func)
Definition: Factories.h:339
M_PI
#define M_PI
Definition: Handle.h:33
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
dd4hep::DetElement::clone
DetElement clone(int flag) const
Clone (Deep copy) the DetElement structure.
Definition: DetElement.cpp:274
dd4hep::PlacedVolume::addPhysVolID
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
Definition: Volumes.cpp:485
dd4hep::Handle
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:84
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::Detector::pickMotherVolume
virtual Volume pickMotherVolume(const DetElement &sd) const =0
Access mother volume by detector element.
dd4hep::DetElement::add
DetElement & add(DetElement sub_element)
Add new child to the detector structure.
Definition: DetElement.cpp:258
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
dd4hep::Layer
Class to describe one layer in a layering stack.
Definition: Layering.h:56
dd4hep::Volume::placeVolume
PlacedVolume placeVolume(const Volume &volume) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:830
xml_comp_t
dd4hep::xml::Component xml_comp_t
Definition: XML.h:33
dd4hep::Trd2
Class describing a Trd2 shape.
Definition: Shapes.h:1163
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:272
dd4hep::Translation3D
ROOT::Math::Translation3D Translation3D
Definition: Objects.h:119
dd4hep::Detector::material
virtual Material material(const std::string &name) const =0
Retrieve a matrial by its name from the detector description.
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::Detector::air
virtual Material air() const =0
Return handle to material describing air.
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:378
dd4hep::detail
DD4hep internal namespace.
Definition: Alignments.h:32
dd4hep::RotationZ
ROOT::Math::RotationZ RotationZ
Definition: Objects.h:107
xml_det_t
dd4hep::xml::DetElement xml_det_t
Definition: XML.h:32
_U
#define _U(a)
Definition: Tags.h:23
Layering.h
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:117
dd4hep::Layering
Class to convert a layering object from the compact notation.
Definition: Layering.h:116
dd4hep::Layer::thickness
double thickness() const
Definition: Layering.h:70
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:81
DetFactoryHelper.h
dd4hep::Box
Class describing a box shape.
Definition: Shapes.h:294
std
Definition: Plugins.h:30
dd4hep::DetElement::setVisAttributes
DetElement & setVisAttributes(const Detector &description, const std::string &name, const Volume &volume)
Set Visualization attributes to the detector element.
Definition: DetElement.cpp:361
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::RotationZYX
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:105
xml_dim_t
dd4hep::xml::Dimension xml_dim_t
Definition: XML.h:31
dd4hep::SensitiveDetector::setType
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:403