ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ZPlanarTracker_geo.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ZPlanarTracker_geo.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 // This DD4hep Constructor is closely inspred from
10 // https://github.com/AIDASoft/DD4hep/tree/master/examples/SimpleDetector
11 
12 // $Id: $
13 //====================================================================
14 // Simple tracking detector made from planar sensors that are parallel
15 // to the z-axis. There are two materials per ladder: one sensitive
16 // and one support.
17 //--------------------------------------------------------------------
18 //
19 // Author : F.Gaede
20 //
21 //====================================================================
22 #include <exception>
23 
24 #include "DD4hep/DetFactoryHelper.h"
25 //#include "DDRec/DetectorData.h"
26 //#include "DDRec/Surface.h"
27 
28 using namespace dd4hep;
29 // using namespace DD4hep::DDRec;
30 // using namespace DDSurfaces;
31 
33 #include "Acts/Utilities/Units.hpp"
34 
35 static Ref_t create_element(Detector& lcdd, xml_h e, SensitiveDetector sens) {
36  xml_det_t x_det = e;
37  std::string name = x_det.nameStr();
38 
39  // put the whole detector into an assembly
40  // - should be replaced by an envelope volume ...
41 
42  Assembly assembly(name + "_assembly");
43 
44  DetElement tracker(name, x_det.id());
45 
46  // add Extension to Detlement for the RecoGeometry of ACTS
47  Acts::ActsExtension* detvolume = new Acts::ActsExtension();
48  detvolume->addType("barrel", "detector");
49  tracker.addExtension<Acts::ActsExtension>(detvolume);
50 
51  PlacedVolume pv;
52 
53  // DDRec::ZPlanarData* zPlanarData = new DDRec::ZPlanarData;
54 
55  double minRadius = 1e99;
56  double minZhalf = 1e99;
57 
58  bool isStripDetector = false;
59  try {
60  isStripDetector = x_det.attr<bool>(_Unicode(isStripDetector));
61 
62  } catch (std::runtime_error) {
63  }
64 
65  //========= loop over layer elements in xml
66  //======================================
67 
68  for (xml_coll_t c(e, _U(layer)); c; ++c) {
69  xml_comp_t x_layer(c);
70 
71  // child elements: ladder and sensitive
72  xml_comp_t x_sensitive(x_layer.child(_U(sensitive)));
73  xml_comp_t x_ladder(x_layer.child(_U(ladder)));
74 
75  int layer_id = x_layer.id();
76  int nLadders = x_layer.attr<double>(_Unicode(nLadders));
77 
78  double dphi = 2. * M_PI / double(nLadders);
79 
80  std::string layername = name + _toString(layer_id, "_layer%d");
81 
82  // --- create an assembly and DetElement for the layer
83 
84  Assembly layer_assembly("layer_assembly" + _toString(layer_id, "_%d"));
85 
86  DetElement layerDE(tracker, _toString(layer_id, "layer_%d"), x_det.id());
87 
88  // add Extension for translation to ACTS TrackingGeometry
89  Acts::ActsExtension* detlayer = new Acts::ActsExtension("zyx");
90  detlayer->addValue(10. * Acts::units::_mm, "r", "envelope");
91  detlayer->addValue(10. * Acts::units::_mm, "z", "envelope");
92  detlayer->addType("sensitive plane", "layer");
93  layerDE.addExtension<Acts::ActsExtension>(detlayer);
94 
95  pv = assembly.placeVolume(layer_assembly);
96 
97  pv.addPhysVolID("layer", layer_id);
98 
99  layerDE.setPlacement(pv);
100 
101  //--------------------------------
102 
103  double supp_zhalf = x_ladder.length();
104  double supp_offset = x_ladder.offset();
105  double supp_distance = x_ladder.distance();
106  double supp_thickness = x_ladder.thickness();
107  double supp_width = x_ladder.width();
108 
109  std::string supp_vis = x_ladder.visStr();
110  std::string supp_matS = x_ladder.materialStr();
111 
112  double sens_zhalf = x_sensitive.length();
113  double sens_offset = x_sensitive.offset();
114  double sens_distance = x_sensitive.distance();
115  double sens_thickness = x_sensitive.thickness();
116  double sens_width = x_sensitive.width();
117 
118  std::string sens_vis = x_sensitive.visStr();
119  std::string sens_matS = x_sensitive.materialStr();
120 
121  double phi0 = x_layer.phi0();
122 
123  if (sens_distance < minRadius)
124  minRadius = sens_distance;
125  if (supp_distance < minRadius)
126  minRadius = supp_distance;
127  if (sens_zhalf < minZhalf)
128  minZhalf = sens_zhalf;
129  if (supp_zhalf < minZhalf)
130  minZhalf = supp_zhalf;
131 
132  //-----------------------------------
133  // store the data in an extension to be used for reconstruction
134  /* DDRec::ZPlanarData::LayerLayout thisLayer;
135 
136  thisLayer.sensorsPerLadder = 1; // for now only one planar sensor
137  thisLayer.lengthSensor = 2. * sens_zhalf;
138 
139  thisLayer.distanceSupport = supp_distance;
140  thisLayer.offsetSupport = supp_offset;
141  thisLayer.thicknessSupport = supp_thickness;
142  thisLayer.zHalfSupport = supp_zhalf;
143  thisLayer.widthSupport = supp_width;
144 
145  thisLayer.distanceSensitive = sens_distance;
146  thisLayer.offsetSensitive = sens_offset;
147  thisLayer.thicknessSensitive = sens_thickness;
148  thisLayer.zHalfSensitive = sens_zhalf;
149  thisLayer.widthSensitive = sens_width;
150 
151  thisLayer.ladderNumber = nLadders;
152  thisLayer.phi0 = phi0;
153 
154  zPlanarData->layers.push_back(thisLayer);*/
155  //-----------------------------------
156 
157  Material supp_mat = lcdd.material(supp_matS);
158  Material sens_mat = lcdd.material(sens_matS);
159 
160  //-------
161  Box sens_box(sens_thickness / 2., sens_width / 2., sens_zhalf);
162  Box supp_box(supp_thickness / 2., supp_width / 2., supp_zhalf);
163 
164  Volume supp_vol(layername + "_supp", supp_box, supp_mat);
165  Volume sens_vol(layername + "_sens", sens_box, sens_mat);
166 
167  // -------- create a measurement plane for the tracking surface attched to
168  // the sensitive volume -----
169  /* Vector3D u(0., 1., 0.);
170  Vector3D v(0., 0., 1.);
171  Vector3D n(1., 0., 0.);
172  // Vector3D o( 0. , 0. , 0. ) ;
173 
174  // compute the inner and outer thicknesses that need to be assigned to
175  the
176  // tracking surface
177  // depending on wether the support is above or below the sensor
178  double inner_thickness
179  = (sens_distance > supp_distance
180  ? (sens_distance - supp_distance) + sens_thickness / 2
181  : sens_thickness / 2);
182  double outer_thickness
183  = (sens_distance > supp_distance
184  ? sens_thickness / 2
185  : (supp_distance - sens_distance) + supp_thickness
186  - sens_thickness / 2);
187 
188  SurfaceType type(SurfaceType::Sensitive);
189 
190  if (isStripDetector) type.setProperty(SurfaceType::Measurement1D, true);
191 
192  VolPlane surf(
193  sens_vol, type, inner_thickness, outer_thickness, u, v, n); //,o )
194  ;
195  */
196  //--------------------------------------------
197 
198  sens.setType("tracker");
199  sens_vol.setSensitiveDetector(sens);
200 
201  sens_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
202  sens_vis);
203  supp_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
204  supp_vis);
205 
206  //--------- loop over ladders ---------------------------
207 
208  for (int j = 0; j < nLadders; ++j) {
209  double phi = phi0 + j * dphi;
210 
211  std::string laddername = layername + _toString(j, "_ladder%d");
212 
213  RotationZYX rot(phi, 0, 0);
214 
215  // --- place support -----
216  double lthick = supp_thickness;
217  double radius = supp_distance;
218  double offset = supp_offset;
219 
220  /* pv = */ layer_assembly.placeVolume(
221  supp_vol,
222  Transform3D(
223  rot,
224  Position((radius + lthick / 2.) * cos(phi) - offset * sin(phi),
225  (radius + lthick / 2.) * sin(phi) + offset * cos(phi),
226  0.)));
227 
228  // --- place sensitive -----
229  lthick = sens_thickness;
230  radius = sens_distance;
231  offset = sens_offset;
232 
233  pv = layer_assembly.placeVolume(
234  sens_vol,
235  Transform3D(
236  rot,
237  Position((radius + lthick / 2.0) * cos(phi) - offset * sin(phi),
238  (radius + lthick / 2.0) * sin(phi) + offset * cos(phi),
239  0.)));
240 
241  // pv.addPhysVolID("layer", layer_id ).addPhysVolID( "module" , j
242  // ).addPhysVolID("sensor", 0 ) ;
243  pv.addPhysVolID("module", j).addPhysVolID("sensor", 0);
244 
245  DetElement ladderDE(layerDE, laddername, x_det.id());
246  ladderDE.setPlacement(pv);
247 
248  // volSurfaceList(ladderDE)->push_back(surf);
249  }
250 
251  // tracker.setVisAttributes(lcdd, x_det.visStr(),laddervol);
252 
253  // is this needed ??
254  layer_assembly->GetShape()->ComputeBBox();
255  }
256 
257 #if 0 //-------- add an inscribing cylinder of air for tracking purposes
258  //-----------------
259  // this screw up the geometry and the material scan does not work
260  // anymore !!!!!?????
261 
262  /* double tube_thick = 1.0 * dd4hep::mm ;
263  double inner_r = minRadius - 1.1 * tube_thick ;
264  double outer_r = inner_r + tube_thick ;
265  double z_half = minZhalf ;
266 
267  Tube tubeSolid (inner_r, outer_r, z_half ) ;
268  Volume tube_vol( name+"_inner_cylinder_air", tubeSolid , lcdd.material("Air") ) ;
269 
270  assembly.placeVolume( tube_vol , Transform3D() ) ;
271 
272  Vector3D ocyl( inner_r + 0.5*tube_thick , 0. , 0. ) ;
273 
274  VolCylinder cylSurf( tube_vol , SurfaceType( SurfaceType::Helper ) , 0.5*tube_thick , 0.5*tube_thick , ocyl ) ;
275 
276  volSurfaceList( tracker )->push_back( cylSurf ) ;*/
277 
278 #endif //----------------------------------------------------------------------------------
279 
280  // tracker.addExtension<DDRec::ZPlanarData>(zPlanarData);
281 
282  Volume mother = lcdd.pickMotherVolume(tracker);
283 
284  pv = mother.placeVolume(assembly);
285 
286  pv.addPhysVolID("system", x_det.id()).addPhysVolID("side", 0);
287 
288  tracker.setPlacement(pv);
289 
290  assembly->GetShape()->ComputeBBox();
291 
292  return tracker;
293 }
294 
295 DECLARE_DETELEMENT(ZPlanarTracker, create_element)