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