DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EcalBarrel_geo.cpp
Go to the documentation of this file.
1 // $Id: $
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 //
15 // Specialized generic detector constructor
16 //
17 //==========================================================================
19 #include "XML/Layering.h"
20 
21 using namespace std;
22 using namespace DD4hep;
23 using namespace DD4hep::Geometry;
24 
26  static double tolerance = 0e0;
27  Layering layering (e);
28  xml_det_t x_det = e;
29  Material air = lcdd.air();
30  int det_id = x_det.id();
31  string det_name = x_det.nameStr();
32  xml_comp_t x_staves = x_det.staves();
33  xml_comp_t x_dim = x_det.dimensions();
34  int nsides = x_dim.numsides();
35  double inner_r = x_dim.rmin();
36  double dphi = (2*M_PI/nsides);
37  double hphi = dphi/2;
38  double mod_z = layering.totalThickness();
39  double outer_r = inner_r + mod_z;
40  double totThick = mod_z;
41  DetElement sdet (det_name,det_id);
42  Volume motherVol = lcdd.pickMotherVolume(sdet);
43  PolyhedraRegular hedra (nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
44  Volume envelope (det_name,hedra,air);
45  PlacedVolume env_phv = motherVol.placeVolume(envelope,RotationZYX(0,0,M_PI/nsides));
46 
47  env_phv.addPhysVolID("system",det_id);
48  env_phv.addPhysVolID("barrel",0);
49  sdet.setPlacement(env_phv);
50 
51  DetElement stave_det("stave0",det_id);
52  double dx = 0.0; //mod_z / std::sin(dphi); // dx per layer
53 
54  // Compute the top and bottom face measurements.
55  double trd_x2 = (2 * std::tan(hphi) * outer_r - dx)/2 - tolerance;
56  double trd_x1 = (2 * std::tan(hphi) * inner_r + dx)/2 - tolerance;
57  double trd_y1 = x_dim.z()/2 - tolerance;
58  double trd_y2 = trd_y1;
59  double trd_z = mod_z/2 - tolerance;
60 
61  // Create the trapezoid for the stave.
62  Trapezoid trd(trd_x1, // Outer side, i.e. the "short" X side.
63  trd_x2, // Inner side, i.e. the "long" X side.
64  trd_y1, // Corresponds to subdetector (or module) Z.
65  trd_y2, //
66  trd_z); // Thickness, in Y for top stave, when rotated.
67 
68  Volume mod_vol("stave",trd,air);
69 
70  sens.setType("calorimeter");
71  { // ===== buildBarrelStave(lcdd, sens, module_volume) =====
72  // Parameters for computing the layer X dimension:
73  double stave_z = trd_y1/2;
74  double l_dim_x = trd_x1/2; // Starting X dimension for the layer.
75  double adj = (l_dim_x-trd_x2/2)/2; // Adjacent angle of triangle.
76  double hyp = std::sqrt(trd_z*trd_z/4 + adj*adj); // Hypotenuse of triangle.
77  double beta = std::acos(adj / hyp); // Lower-right angle of triangle.
78  double tan_beta = std::tan(beta); // Primary coefficient for figuring X.
79  double l_pos_z = -(layering.totalThickness() / 2);
80 
81  // Loop over the sets of layer elements in the detector.
82  int l_num = 1;
83  for(xml_coll_t li(x_det,_U(layer)); li; ++li) {
84  xml_comp_t x_layer = li;
85  int repeat = x_layer.repeat();
86  // Loop over number of repeats for this layer.
87  for (int j=0; j<repeat; j++) {
88  string l_name = _toString(l_num,"layer%d");
89  double l_thickness = layering.layer(l_num-1)->thickness(); // Layer's thickness.
90  double xcut = (l_thickness / tan_beta); // X dimension for this layer.
91  l_dim_x -= xcut/2;
92 
93  Position l_pos(0,0,l_pos_z+l_thickness/2); // Position of the layer.
94  Box l_box(l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance);
95  Volume l_vol(l_name,l_box,air);
96  DetElement layer(stave_det, l_name, det_id);
97 
98  // Loop over the sublayers or slices for this layer.
99  int s_num = 1;
100  double s_pos_z = -(l_thickness / 2);
101  for(xml_coll_t si(x_layer,_U(slice)); si; ++si) {
102  xml_comp_t x_slice = si;
103  string s_name = _toString(s_num,"slice%d");
104  double s_thick = x_slice.thickness();
105  Box s_box(l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance);
106  Volume s_vol(s_name,s_box,lcdd.material(x_slice.materialStr()));
107  DetElement slice(layer,s_name,det_id);
108 
109  if ( x_slice.isSensitive() ) {
110  s_vol.setSensitiveDetector(sens);
111  }
112  slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
113 
114  // Slice placement.
115  PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2));
116  slice_phv.addPhysVolID("slice", s_num);
117  slice.setPlacement(slice_phv);
118  // Increment Z position of slice.
119  s_pos_z += s_thick;
120 
121  // Increment slice number.
122  ++s_num;
123  }
124 
125  // Set region, limitset, and vis of layer.
126  layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
127 
128  PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
129  layer_phv.addPhysVolID("layer", l_num);
130  layer.setPlacement(layer_phv);
131  // Increment to next layer Z position.
132  l_pos_z += l_thickness;
133  ++l_num;
134  }
135  }
136  }
137 
138  // Set stave visualization.
139  if ( x_staves ) {
140  mod_vol.setVisAttributes(lcdd.visAttributes(x_staves.visStr()));
141  }
142  // Phi start for a stave.
143  double phi = M_PI / nsides;
144  double mod_x_off = dx / 2; // Stave X offset, derived from the dx.
145  double mod_y_off = inner_r + mod_z/2; // Stave Y offset
146 
147  // Create nsides staves.
148  for (int i = 0; i < nsides; i++, phi -= dphi) { // i is module number
149  // Compute the stave position
150  double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi);
151  double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi);
152  Transform3D tr(RotationZYX(0,phi,M_PI*0.5),Translation3D(-m_pos_x,-m_pos_y,0));
153  PlacedVolume pv = envelope.placeVolume(mod_vol,tr);
154  pv.addPhysVolID("system",det_id);
155  pv.addPhysVolID("barrel",0);
156  pv.addPhysVolID("module",i+1);
157  DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
158  sd.setPlacement(pv);
159  sdet.add(sd);
160  }
161 
162  // Set envelope volume attributes.
163  envelope.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
164  return sdet;
165 }
166 
167 DECLARE_DETELEMENT(DD4hep_EcalBarrel,create_detector)
Handle class to hold the information of a sensitive detector.
Definition: Detector.h:47
Dimension staves(bool throw_if_not_present=true) const
Child access: staves.
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:135
virtual Volume pickMotherVolume(const DetElement &sd) const =0
Access mother volume by detector element.
double rmin() const
Access min/max parameters: rmin.
Handle class describing a material.
Definition: Objects.h:300
#define M_PI
Definition: Handle.h:39
std::string regionStr() const
Access region attribute as STL string. If not present empty return empty string.
Class to convert a layering object from the compact notation.
Definition: Layering.h:138
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:556
XML Handle class extending the XML handle Dimension.
Definition: XMLDetector.h:69
const Layer * layer(size_t which) const
Definition: Layering.cpp:86
#define _U(a)
Definition: XMLTags.h:27
Class describing a regular polyhedron shape.
Definition: Shapes.h:591
Class describing a box shape.
Definition: Shapes.h:120
return e
Definition: Volumes.cpp:297
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: Detector.cpp:434
double thickness() const
Access attribute values: thickness.
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:237
std::string visStr() const
Access vis attribute as STL string. If not present empty return empty string.
int numsides() const
Access attribute values: numsides.
bool isSensitive() const
Check if component is sensitive.
Definition: XMLDetector.cpp:29
std::string limitsStr() const
Access limits attribute as STL string. If not present empty return empty string.
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
Definition: Volumes.cpp:564
DetElement & add(DetElement sub_element)
Add new child to the detector structure.
Definition: Detector.cpp:255
double z() const
Access parameters: z.
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:98
double totalThickness() const
Definition: Layering.h:153
int id() const
Access parameters: id.
Definition: XMLDetector.cpp:57
#define DECLARE_DETELEMENT(name, func)
Definition: Factories.h:248
XML Handle class extending the XML handle Dimension.
Definition: XMLDetector.h:39
double thickness() const
Definition: Layering.h:75
DetElement & setPlacement(const PlacedVolume &volume)
Set the physical volumes of the detector element.
Definition: Detector.cpp:290
DetElement clone(const std::string &new_name) const
Clone (Deep copy) the DetElement structure with a new name.
Definition: Detector.cpp:268
ROOT::Math::XYZVector Position
Definition: Objects.h:75
#define DECLARE_DEPRECATED_DETELEMENT(name, func)
Definition: Factories.h:249
virtual Material air() const =0
Return handle to material describing air.
std::string materialStr() const
Access material attribute as STL string.
Definition: XMLDetector.cpp:25
Handle class describing a detector element.
Definition: Detector.h:172
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:87
ROOT::Math::Translation3D Translation3D
Definition: Objects.h:112
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
Definition: Volumes.cpp:377
The main interface to the DD4hep detector description package.
Definition: LCDD.h:82
DetElement & setAttributes(const LCDD &lcdd, const Volume &volume, const std::string &region, const std::string &limits, const std::string &vis)
Set all attributes in one go.
Definition: Detector.cpp:334
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:361
int repeat() const
Access attribute values: repeat.
virtual Material material(const std::string &name) const =0
Retrieve a matrial by it's name from the detector description.
const Volume & setSensitiveDetector(const SensitiveDetector &obj) const
Assign the sensitive detector structure.
Definition: Volumes.cpp:736
virtual const HandleMap & visAttributes() const =0
Accessor to the map of visualisation attributes.
std::string nameStr() const
Access "name" attribute as STL string.
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:110
Class describing a Trapezoid shape.
Definition: Shapes.h:437
Dimension dimensions(bool throw_if_not_present=true) const
Access child element with tag "dimensions" as Dimension object.
static Ref_t create_detector(LCDD &lcdd, xml_h e, SensitiveDetector sens)
PlacedVolume placeVolume(const Volume &vol) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:524
static std::string _toString(const DD4hep::XML::XmlChar *value)
std::string conversion of XML strings (e.g. Unicode for Xerces-C)