EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FCChhTrackerTkLayout_Barrel.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FCChhTrackerTkLayout_Barrel.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 
10 
11 #include "../DetUtils.h"
12 #include "DD4hep/DetFactoryHelper.h"
13 
14 using dd4hep::DetElement;
15 using dd4hep::PlacedVolume;
16 using dd4hep::Volume;
17 using dd4hep::xml::Dimension;
18 
19 namespace det {
20 static dd4hep::Ref_t createTkLayoutTrackerBarrel(
21  dd4hep::Detector& lcdd, dd4hep::xml::Handle_t xmlElement,
22  dd4hep::SensitiveDetector sensDet) {
23  // shorthands
24  dd4hep::xml::DetElement xmlDet =
25  static_cast<dd4hep::xml::DetElement>(xmlElement);
26  Dimension dimensions(xmlDet.dimensions());
27  // get sensitive detector type from xml
28  dd4hep::xml::Dimension sdTyp = xmlElement.child(_Unicode(sensitive));
29  // sensitive detector used for all sensitive parts of this detector
30  sensDet.setType(sdTyp.typeStr());
31 
32  // definition of top volume
33  // has min/max dimensions of tracker for visualization etc.
34  std::string detectorName = xmlDet.nameStr();
35  DetElement topDetElement(detectorName, xmlDet.id());
36  // detElement owns extension
37  Acts::ActsExtension* detWorldExt = new Acts::ActsExtension();
38  detWorldExt->addType("barrel", "detector");
39  topDetElement.addExtension<Acts::ActsExtension>(detWorldExt);
40  dd4hep::Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(),
41  (dimensions.zmax() - dimensions.zmin()) * 0.5);
42  Volume topVolume(detectorName, topVolumeShape, lcdd.air());
43  topVolume.setVisAttributes(lcdd.invisible());
44 
45  // counts all layers - incremented in the inner loop over repeat - tags
46  unsigned int layerCounter = 0;
47  double integratedModuleComponentThickness = 0;
48  double phi = 0;
49  // loop over 'layer' nodes in xml
50  dd4hep::xml::Component xLayers = xmlElement.child(_Unicode(layers));
51  for (dd4hep::xml::Collection_t xLayerColl(xLayers, _U(layer));
52  nullptr != xLayerColl; ++xLayerColl) {
53  dd4hep::xml::Component xLayer =
54  static_cast<dd4hep::xml::Component>(xLayerColl);
55  dd4hep::xml::Component xRods = xLayer.child("rods");
56  dd4hep::xml::Component xRodEven = xRods.child("rodOdd");
57  dd4hep::xml::Component xRodOdd = xRods.child("rodEven");
58  dd4hep::xml::Component xModulesEven = xRodEven.child("modules");
59  dd4hep::xml::Component xModulePropertiesOdd =
60  xRodOdd.child("moduleProperties");
61  dd4hep::xml::Component xModulesOdd = xRodOdd.child("modules");
62  dd4hep::Tube layerShape(xLayer.rmin(), xLayer.rmax(), dimensions.zmax());
63  Volume layerVolume("layer", layerShape, lcdd.material("Air"));
64  // layerVolume.setVisAttributes(lcdd.invisible());
65  PlacedVolume placedLayerVolume = topVolume.placeVolume(layerVolume);
66  placedLayerVolume.addPhysVolID("layer", layerCounter);
67  DetElement lay_det(topDetElement, "layer" + std::to_string(layerCounter),
68  layerCounter);
69  // the local coordinate systems of modules in dd4hep and acts differ
70  // see http://acts.web.cern.ch/ACTS/latest/doc/group__DD4hepPlugins.html
71  // detElement owns extension
72  Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
73  layerExtension->addType("sensitive cylinder", "layer");
74  layerExtension->addType("axes", "definitions", "XzY");
75  lay_det.addExtension<Acts::ActsExtension>(layerExtension);
76  lay_det.setPlacement(placedLayerVolume);
77  dd4hep::xml::Component xModuleComponentsOdd =
78  xModulePropertiesOdd.child("components");
79  integratedModuleComponentThickness = 0;
80  int moduleCounter = 0;
81 
82  // collect tracker material
83  std::vector<std::pair<dd4hep::Material, double>> compMaterials;
84 
85  for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
86  _U(component));
87  nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
88  dd4hep::xml::Component xModuleComponentOdd =
89  static_cast<dd4hep::xml::Component>(xModuleComponentOddColl);
90  // collect module materials
91  compMaterials.push_back(
92  std::make_pair(lcdd.material(xModuleComponentOdd.materialStr()),
93  xModuleComponentOdd.thickness()));
94  }
95  for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
96  _U(component));
97  nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
98  dd4hep::xml::Component xModuleComponentOdd =
99  static_cast<dd4hep::xml::Component>(xModuleComponentOddColl);
100  auto moduleWidth = 0.5 * xModulePropertiesOdd.attr<double>("modWidth");
101  auto moduleThickness = 0.5 * xModuleComponentOdd.thickness();
102  auto moduleLength = 0.5 * xModulePropertiesOdd.attr<double>("modLength");
103  Volume moduleVolume = Volume(
104  "module", dd4hep::Box(moduleWidth, moduleThickness, moduleLength),
105  lcdd.material(xModuleComponentOdd.materialStr()));
106 
107  // Create digitization module
108  // with readout given by layer
109  auto digiModule = det::utils::rectangleDigiModuleXZ(
110  moduleWidth, moduleLength, moduleThickness, xLayer.X(), xLayer.Z());
111 
112  moduleVolume.setVisAttributes(lcdd.invisible());
113  unsigned int nPhi = xRods.repeat();
114  dd4hep::xml::Handle_t currentComp;
115  for (unsigned int phiIndex = 0; phiIndex < nPhi; ++phiIndex) {
116  double lX = 0;
117  double lY = 0;
118  double lZ = 0;
119  if (0 == phiIndex % 2) {
120  phi = 2 * M_PI * static_cast<double>(phiIndex) /
121  static_cast<double>(nPhi);
122  currentComp = xModulesEven;
123  } else {
124  currentComp = xModulesOdd;
125  }
126  for (dd4hep::xml::Collection_t xModuleColl(currentComp, _U(module));
127  nullptr != xModuleColl; ++xModuleColl) {
128  dd4hep::xml::Component xModule =
129  static_cast<dd4hep::xml::Component>(xModuleColl);
130  double currentPhi = atan2(xModule.Y(), xModule.X());
131  double componentOffset =
132  integratedModuleComponentThickness -
133  0.5 * xModulePropertiesOdd.attr<double>("modThickness") +
134  0.5 * xModuleComponentOdd.thickness();
135  lX = xModule.X() + cos(currentPhi) * componentOffset;
136  lY = xModule.Y() + sin(currentPhi) * componentOffset;
137  lZ = xModule.Z();
138  dd4hep::Translation3D moduleOffset(lX, lY, lZ);
139  dd4hep::Transform3D lTrafo(
140  dd4hep::RotationZ(atan2(lY, lX) + 0.5 * M_PI), moduleOffset);
141  dd4hep::RotationZ lRotation(phi);
142  PlacedVolume placedModuleVolume =
143  layerVolume.placeVolume(moduleVolume, lRotation * lTrafo);
144  if (xModuleComponentOdd.isSensitive()) {
145  placedModuleVolume.addPhysVolID("module", moduleCounter);
146  moduleVolume.setSensitiveDetector(sensDet);
147  DetElement mod_det(lay_det,
148  "module" + std::to_string(moduleCounter),
149  moduleCounter);
150  // add extension to hand over material
151  Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
152  mod_det.addExtension<Acts::ActsExtension>(moduleExtension);
153 
154  mod_det.setPlacement(placedModuleVolume);
155  ++moduleCounter;
156  }
157  }
158  }
159  integratedModuleComponentThickness += xModuleComponentOdd.thickness();
160  }
161  ++layerCounter;
162  }
163  Volume motherVol = lcdd.pickMotherVolume(topDetElement);
164  PlacedVolume placedGenericTrackerBarrel = motherVol.placeVolume(topVolume);
165  placedGenericTrackerBarrel.addPhysVolID("system", topDetElement.id());
166  topDetElement.setPlacement(placedGenericTrackerBarrel);
167  return topDetElement;
168 }
169 } // namespace det
170 
171 DECLARE_DETELEMENT(TkLayoutBrlTracker, det::createTkLayoutTrackerBarrel)