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  //========= loop over layer elements in xml
59  //======================================
60 
61  for (xml_coll_t c(e, _U(layer)); c; ++c) {
62  xml_comp_t x_layer(c);
63 
64  // child elements: ladder and sensitive
65  xml_comp_t x_sensitive(x_layer.child(_U(sensitive)));
66  xml_comp_t x_ladder(x_layer.child(_U(ladder)));
67 
68  int layer_id = x_layer.id();
69  int nLadders = x_layer.attr<double>(_Unicode(nLadders));
70 
71  double dphi = 2. * M_PI / double(nLadders);
72 
73  std::string layername = name + _toString(layer_id, "_layer%d");
74 
75  // --- create an assembly and DetElement for the layer
76 
77  Assembly layer_assembly("layer_assembly" + _toString(layer_id, "_%d"));
78 
79  DetElement layerDE(tracker, _toString(layer_id, "layer_%d"), x_det.id());
80 
81  // add Extension for translation to ACTS TrackingGeometry
82  Acts::ActsExtension* detlayer = new Acts::ActsExtension("zyx");
83  detlayer->addValue(10. * Acts::UnitConstants::mm, "r", "envelope");
84  detlayer->addValue(10. * Acts::UnitConstants::mm, "z", "envelope");
85  detlayer->addType("sensitive plane", "layer");
86  layerDE.addExtension<Acts::ActsExtension>(detlayer);
87 
88  pv = assembly.placeVolume(layer_assembly);
89 
90  pv.addPhysVolID("layer", layer_id);
91 
92  layerDE.setPlacement(pv);
93 
94  //--------------------------------
95 
96  double supp_zhalf = x_ladder.length();
97  double supp_offset = x_ladder.offset();
98  double supp_distance = x_ladder.distance();
99  double supp_thickness = x_ladder.thickness();
100  double supp_width = x_ladder.width();
101 
102  std::string supp_vis = x_ladder.visStr();
103  std::string supp_matS = x_ladder.materialStr();
104 
105  double sens_zhalf = x_sensitive.length();
106  double sens_offset = x_sensitive.offset();
107  double sens_distance = x_sensitive.distance();
108  double sens_thickness = x_sensitive.thickness();
109  double sens_width = x_sensitive.width();
110 
111  std::string sens_view = x_sensitive.visStr();
112  std::string sens_matS = x_sensitive.materialStr();
113 
114  double phi0 = x_layer.phi0();
115 
116  if (sens_distance < minRadius)
117  minRadius = sens_distance;
118  if (supp_distance < minRadius)
119  minRadius = supp_distance;
120  if (sens_zhalf < minZhalf)
121  minZhalf = sens_zhalf;
122  if (supp_zhalf < minZhalf)
123  minZhalf = supp_zhalf;
124 
125  //-----------------------------------
126  // store the data in an extension to be used for reconstruction
127  /* DDRec::ZPlanarData::LayerLayout thisLayer;
128 
129  thisLayer.sensorsPerLadder = 1; // for now only one planar sensor
130  thisLayer.lengthSensor = 2. * sens_zhalf;
131 
132  thisLayer.distanceSupport = supp_distance;
133  thisLayer.offsetSupport = supp_offset;
134  thisLayer.thicknessSupport = supp_thickness;
135  thisLayer.zHalfSupport = supp_zhalf;
136  thisLayer.widthSupport = supp_width;
137 
138  thisLayer.distanceSensitive = sens_distance;
139  thisLayer.offsetSensitive = sens_offset;
140  thisLayer.thicknessSensitive = sens_thickness;
141  thisLayer.zHalfSensitive = sens_zhalf;
142  thisLayer.widthSensitive = sens_width;
143 
144  thisLayer.ladderNumber = nLadders;
145  thisLayer.phi0 = phi0;
146 
147  zPlanarData->layers.push_back(thisLayer);*/
148  //-----------------------------------
149 
150  Material supp_mat = lcdd.material(supp_matS);
151  Material sens_mat = lcdd.material(sens_matS);
152 
153  //-------
154  Box sens_box(sens_thickness / 2., sens_width / 2., sens_zhalf);
155  Box supp_box(supp_thickness / 2., supp_width / 2., supp_zhalf);
156 
157  Volume supp_vol(layername + "_supp", supp_box, supp_mat);
158  Volume sens_vol(layername + "_sens", sens_box, sens_mat);
159 
160  // -------- create a measurement plane for the tracking surface attched to
161  // the sensitive volume -----
162  /* Vector3D u(0., 1., 0.);
163  Vector3D v(0., 0., 1.);
164  Vector3D n(1., 0., 0.);
165  // Vector3D o( 0. , 0. , 0. ) ;
166 
167  // compute the inner and outer thicknesses that need to be assigned to
168  the
169  // tracking surface
170  // depending on wether the support is above or below the sensor
171  double inner_thickness
172  = (sens_distance > supp_distance
173  ? (sens_distance - supp_distance) + sens_thickness / 2
174  : sens_thickness / 2);
175  double outer_thickness
176  = (sens_distance > supp_distance
177  ? sens_thickness / 2
178  : (supp_distance - sens_distance) + supp_thickness
179  - sens_thickness / 2);
180 
181  SurfaceType type(SurfaceType::Sensitive);
182 
183  if (isStripDetector) type.setProperty(SurfaceType::Measurement1D, true);
184 
185  VolPlane surf(
186  sens_vol, type, inner_thickness, outer_thickness, u, v, n); //,o )
187  ;
188  */
189  //--------------------------------------------
190 
191  sens.setType("tracker");
192  sens_vol.setSensitiveDetector(sens);
193 
194  sens_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
195  sens_view);
196  supp_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
197  supp_vis);
198 
199  //--------- loop over ladders ---------------------------
200 
201  for (int j = 0; j < nLadders; ++j) {
202  double phi = phi0 + j * dphi;
203 
204  std::string laddername = layername + _toString(j, "_ladder%d");
205 
206  RotationZYX rot(phi, 0, 0);
207 
208  // --- place support -----
209  double lthick = supp_thickness;
210  double radius = supp_distance;
211  double offset = supp_offset;
212 
213  /* pv = */ layer_assembly.placeVolume(
214  supp_vol,
215  Transform3D(
216  rot,
217  Position((radius + lthick / 2.) * cos(phi) - offset * sin(phi),
218  (radius + lthick / 2.) * sin(phi) + offset * cos(phi),
219  0.)));
220 
221  // --- place sensitive -----
222  lthick = sens_thickness;
223  radius = sens_distance;
224  offset = sens_offset;
225 
226  pv = layer_assembly.placeVolume(
227  sens_vol,
228  Transform3D(
229  rot,
230  Position((radius + lthick / 2.0) * cos(phi) - offset * sin(phi),
231  (radius + lthick / 2.0) * sin(phi) + offset * cos(phi),
232  0.)));
233 
234  // pv.addPhysVolID("layer", layer_id ).addPhysVolID( "module" , j
235  // ).addPhysVolID("sensor", 0 ) ;
236  pv.addPhysVolID("module", j).addPhysVolID("sensor", 0);
237 
238  DetElement ladderDE(layerDE, laddername, x_det.id());
239  ladderDE.setPlacement(pv);
240 
241  // volSurfaceList(ladderDE)->push_back(surf);
242  }
243 
244  // tracker.setVisAttributes(lcdd, x_det.visStr(),laddervol);
245 
246  // is this needed ??
247  layer_assembly->GetShape()->ComputeBBox();
248  }
249 
250 #if 0 //-------- add an inscribing cylinder of air for tracking purposes
251  //-----------------
252  // this screw up the geometry and the material scan does not work
253  // anymore !!!!!?????
254 
255  /* double tube_thick = 1.0 * dd4hep::mm ;
256  double inner_r = minRadius - 1.1 * tube_thick ;
257  double outer_r = inner_r + tube_thick ;
258  double z_half = minZhalf ;
259 
260  Tube tubeSolid (inner_r, outer_r, z_half ) ;
261  Volume tube_vol( name+"_inner_cylinder_air", tubeSolid , lcdd.material("Air") ) ;
262 
263  assembly.placeVolume( tube_vol , Transform3D() ) ;
264 
265  Vector3D ocyl( inner_r + 0.5*tube_thick , 0. , 0. ) ;
266 
267  VolCylinder cylSurf( tube_vol , SurfaceType( SurfaceType::Helper ) , 0.5*tube_thick , 0.5*tube_thick , ocyl ) ;
268 
269  volSurfaceList( tracker )->push_back( cylSurf ) ;*/
270 
271 #endif //----------------------------------------------------------------------------------
272 
273  // tracker.addExtension<DDRec::ZPlanarData>(zPlanarData);
274 
275  Volume mother = lcdd.pickMotherVolume(tracker);
276 
277  pv = mother.placeVolume(assembly);
278 
279  pv.addPhysVolID("system", x_det.id()).addPhysVolID("side", 0);
280 
281  tracker.setPlacement(pv);
282 
283  assembly->GetShape()->ComputeBBox();
284 
285  return tracker;
286 }
287 
288 DECLARE_DETELEMENT(ZPlanarTracker, create_element)