CMS 3D CMS Logo

DDTECModuleAlgo.cc
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
2 #include <DD4hep/DD4hepUnits.h>
6 
7 using namespace std;
8 using namespace dd4hep;
9 using namespace cms;
10 using namespace angle_units::operators;
11 
12 static long algorithm(Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
13  cms::DDNamespace ns(ctxt, e, true);
14  DDAlgoArguments args(ctxt, e);
15  Volume mother = ns.volume(args.parentName());
16 
17  //variables:
18  //double noOverlapShift = args.value<double>("NoOverlapShift");
19  int ringNo = args.value<int>("RingNo");
20  bool isStereo = args.value<int>("isStereo") == 1;
21  bool isRing6 = (ringNo == 6);
22  double rPos =
23  args.value<double>("RPos"); //Position in R relativ to the center of the TEC ( this is the coord-sys of Tubs)
24  double posCorrectionPhi = isStereo ? args.value<double>("PosCorrectionPhi")
25  : 0e0; // the Phi position of the stereo Modules has to be corrected
26  string standardRot = args.value<string>(
27  "StandardRotation"); //Rotation that aligns the mother(Tub ) coordinate System with the components
28  string genMat = args.value<string>("GeneralMaterial"); //General material name
29  double moduleThick = args.value<double>("ModuleThick"); //Module thickness
30  double detTilt = args.value<double>("DetTilt"); //Tilt of stereo detector
31  double fullHeight = args.value<double>("FullHeight"); //Height
32  double dlTop = args.value<double>("DlTop"); //Width at top of wafer
33  double dlBottom = args.value<double>("DlBottom"); //Width at bottom of wafer
34  double dlHybrid = args.value<double>("DlHybrid"); //Width at the hybrid end
35  double frameWidth = args.value<double>("FrameWidth"); //Frame width
36  double frameThick = args.value<double>("FrameThick"); // thickness
37  double frameOver = args.value<double>("FrameOver"); // overlap (on sides)
38  string topFrameMat = args.value<string>("TopFrameMaterial"); //Top frame material
39  double topFrameHeight = args.value<double>("TopFrameHeight"); // height
40  double topFrameThick = args.value<double>("TopFrameThick"); // thickness
41  double topFrameTopWidth = args.value<double>("TopFrameTopWidth"); // Width at the top
42  double topFrameBotWidth = args.value<double>("TopFrameBotWidth"); // Width at the bottom
43  double topFrame2Width = isStereo ? args.value<double>("TopFrame2Width") : 0e0; // Stereo:2ndPart Width
44  double topFrame2LHeight = isStereo ? args.value<double>("TopFrame2LHeight") : 0e0; // left height
45  double topFrame2RHeight = isStereo ? args.value<double>("TopFrame2RHeight") : 0e0; // right height
46  double topFrameZ = args.value<double>("TopFrameZ"); // z-positions
47 
48  double resizeH = 0.96;
49  string sideFrameMat = args.value<string>("SideFrameMaterial"); //Side frame material
50  double sideFrameThick = args.value<double>("SideFrameThick"); // thickness
51  double sideFrameLWidth = args.value<double>("SideFrameLWidth"); // Left Width (for stereo modules upper one)
52  double sideFrameLWidthLow = isStereo ? args.value<double>("SideFrameLWidthLow")
53  : 0e0; // Width (only for stereo modules: lower Width)
54  double sideFrameLHeight = resizeH * args.value<double>("SideFrameLHeight"); // Height
55  double sideFrameLtheta = args.value<double>("SideFrameLtheta"); // angle of the trapezoid shift
56  double sideFrameRWidth = args.value<double>("SideFrameRWidth"); // Right Width (for stereo modules upper one)
57  double sideFrameRWidthLow = isStereo ? args.value<double>("SideFrameRWidthLow")
58  : 0e0; // Width (only for stereo modules: lower Width)
59  double sideFrameRHeight = resizeH * args.value<double>("SideFrameRHeight"); // Height
60  double sideFrameRtheta = args.value<double>("SideFrameRtheta"); // angle of the trapezoid shift
61  vector<double> siFrSuppBoxWidth = args.value<vector<double> >("SiFrSuppBoxWidth"); // Supp.Box Width
62  vector<double> siFrSuppBoxHeight = args.value<vector<double> >("SiFrSuppBoxHeight"); // Height
63  vector<double> siFrSuppBoxYPos = args.value<vector<double> >(
64  "SiFrSuppBoxYPos"); // y-position of the supplies box (with HV an thermal sensor...)
65  double sideFrameZ = args.value<double>("SideFrameZ"); // z-positions
66  double siFrSuppBoxThick = args.value<double>("SiFrSuppBoxThick"); // thickness
67  string siFrSuppBoxMat = args.value<string>("SiFrSuppBoxMaterial"); // material
68  string waferMat = args.value<string>("WaferMaterial"); //Wafer material
69  double waferPosition = args.value<double>(
70  "WaferPosition"); // position of the wafer (was formaly done by adjusting topFrameHeigt)
71  double sideWidthTop = args.value<double>("SideWidthTop"); // widths on the side Top
72  double sideWidthBottom = args.value<double>("SideWidthBottom"); // Bottom
73  string waferRot = args.value<string>("WaferRotation"); // rotation matrix
74  string activeMat = args.value<string>("ActiveMaterial"); //Sensitive material
75  double activeHeight = args.value<double>("ActiveHeight"); // height
76  double waferThick = args.value<double>("WaferThick"); // wafer thickness (active = wafer - backplane)
77  string activeRot = args.value<string>("ActiveRotation"); // Rotation matrix
78  double activeZ = args.value<double>("ActiveZ"); // z-positions
79  double backplaneThick = args.value<double>("BackPlaneThick"); // thickness
80  double inactiveDy = ringNo > 3 ? args.value<double>("InactiveDy") : 0e0; //InactiveStrip Hight of ( rings > 3)
81  double inactivePos = ringNo > 3 ? args.value<double>("InactivePos") : 0e0; // y-Position
82  string inactiveMat = ringNo > 3 ? args.value<string>("InactiveMaterial") : string(); // material
83  string hybridMat = args.value<string>("HybridMaterial"); //Hybrid material
84  double hybridHeight = args.value<double>("HybridHeight"); // height
85  double hybridWidth = args.value<double>("HybridWidth"); // width
86  double hybridThick = args.value<double>("HybridThick"); // thickness
87  double hybridZ = args.value<double>("HybridZ"); // z-positions
88  string pitchMat = args.value<string>("PitchMaterial"); //Pitch adapter material
89  double pitchWidth = args.value<double>("PitchWidth"); // width
90  double pitchHeight = args.value<double>("PitchHeight"); // height
91  double pitchThick = args.value<double>("PitchThick"); // thickness
92  double pitchZ = args.value<double>("PitchZ"); // z-positions
93  string pitchRot = args.value<string>("PitchRotation"); // rotation matrix
94  string bridgeMat = args.value<string>("BridgeMaterial"); //Bridge material
95  double bridgeWidth = args.value<double>("BridgeWidth"); // width
96  double bridgeThick = args.value<double>("BridgeThick"); // thickness
97  double bridgeHeight = args.value<double>("BridgeHeight"); // height
98  double bridgeSep = args.value<double>("BridgeSeparation"); // separation
99  vector<double> siReenforceHeight = args.value<vector<double> >("SiReenforcementHeight"); // SiReenforcement Height
100  vector<double> siReenforceWidth = args.value<vector<double> >("SiReenforcementWidth"); // Width
101  vector<double> siReenforceYPos = args.value<vector<double> >("SiReenforcementPosY"); // Y - Position
102  double siReenforceThick = args.value<double>("SiReenforcementThick"); // Thick
103  string siReenforceMat = args.value<string>("SiReenforcementMaterial"); // Materieal
104 
105  edm::LogVerbatim("TECGeom") << "debug: ModuleThick " << moduleThick << " Detector Tilt " << convertRadToDeg(detTilt)
106  << " Height " << fullHeight << " dl(Top) " << dlTop << " dl(Bottom) " << dlBottom
107  << " dl(Hybrid) " << dlHybrid << " rPos " << rPos << " standrad rotation " << standardRot;
108  edm::LogVerbatim("TECGeom") << "debug: Frame Width " << frameWidth << " Thickness " << frameThick << " Overlap "
109  << frameOver;
110  edm::LogVerbatim("TECGeom") << "debug: Top Frame Material " << topFrameMat << " Height " << topFrameHeight
111  << " Top Width " << topFrameTopWidth << " Bottom Width " << topFrameTopWidth
112  << " Thickness " << topFrameThick << " positioned at" << topFrameZ;
113  edm::LogVerbatim("TECGeom") << "debug : Side Frame Material " << sideFrameMat << " Thickness " << sideFrameThick
114  << " left Leg's Width: " << sideFrameLWidth << " left Leg's Height: " << sideFrameLHeight
115  << " left Leg's tilt(theta): " << sideFrameLtheta
116  << " right Leg's Width: " << sideFrameRWidth
117  << " right Leg's Height: " << sideFrameRHeight
118  << " right Leg's tilt(theta): " << sideFrameRtheta
119  << "Supplies Box's Material: " << siFrSuppBoxMat << " positioned at" << sideFrameZ;
120  for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++)
121  edm::LogVerbatim("TECGeom") << " Supplies Box" << i << "'s Width: " << siFrSuppBoxWidth[i] << " Supplies Box" << i
122  << "'s Height: " << siFrSuppBoxHeight[i] << " Supplies Box" << i
123  << "'s y Position: " << siFrSuppBoxYPos[i];
124  edm::LogVerbatim("TECGeom") << "debug: Wafer Material " << waferMat << " Side Width Top" << sideWidthTop
125  << " Side Width Bottom" << sideWidthBottom << " and positioned at " << waferPosition
126  << " positioned with rotation"
127  << " matrix:" << waferRot;
128  edm::LogVerbatim("TECGeom") << "debug: Active Material " << activeMat << " Height " << activeHeight << " rotated by "
129  << activeRot << " translated by (0,0," << -0.5 * backplaneThick << ")"
130  << " Thickness/Z" << waferThick - backplaneThick << "/" << activeZ;
131  edm::LogVerbatim("TECGeom") << "debug: Hybrid Material " << hybridMat << " Height " << hybridHeight << " Width "
132  << hybridWidth << " Thickness " << hybridThick << " Z" << hybridZ;
133  edm::LogVerbatim("TECGeom") << "debug: Pitch Adapter Material " << pitchMat << " Height " << pitchHeight
134  << " Thickness " << pitchThick << " position with "
135  << " rotation " << pitchRot << " at Z" << pitchZ;
136  edm::LogVerbatim("TECGeom") << "debug: Bridge Material " << bridgeMat << " Width " << bridgeWidth << " Thickness "
137  << bridgeThick << " Height " << bridgeHeight << " Separation " << bridgeSep;
138  edm::LogVerbatim("TECGeom") << "FALTBOOT DDTECModuleAlgo debug : Si-Reenforcement Material " << sideFrameMat
139  << " Thickness " << siReenforceThick;
140  for (int i = 0; i < (int)(siReenforceWidth.size()); i++)
141  edm::LogVerbatim("TECGeom") << " SiReenforcement" << i << "'s Width: " << siReenforceWidth[i] << " SiReenforcement"
142  << i << "'s Height: " << siReenforceHeight[i] << " SiReenforcement" << i
143  << "'s y Position: " << siReenforceYPos[i];
144 
145  if (!isStereo) {
146  edm::LogVerbatim("TECGeom") << "This is a normal module, in ring " << ringNo << "!";
147  } else {
148  edm::LogVerbatim("TECGeom") << "This is a stereo module, in ring " << ringNo << "!";
149  edm::LogVerbatim("TECGeom") << "Phi Position corrected by " << posCorrectionPhi << "*rad";
150  edm::LogVerbatim("TECGeom") << "debug: stereo Top Frame 2nd Part left Heigt " << topFrame2LHeight
151  << " right Height " << topFrame2RHeight << " Width " << topFrame2Width;
152  edm::LogVerbatim("TECGeom") << " left Leg's lower Width: " << sideFrameLWidthLow
153  << " right Leg's lower Width: " << sideFrameRWidthLow;
154  }
155 
156  // Execution part:
157 
158  edm::LogVerbatim("TECGeom") << "==>> Constructing DDTECModuleAlgo: ";
159  //declarations
160  double tmp;
161  //names
162  string name;
163  string tag("Rphi");
164  if (isStereo)
165  tag = "Stereo";
166  //usefull constants
167  const double topFrameEndZ = 0.5 * (-waferPosition + fullHeight) + pitchHeight + hybridHeight - topFrameHeight;
168  string idName = ns.noNamespace(mother.name());
169  edm::LogVerbatim("TECGeom") << "idName: " << idName << " parent " << mother.name() << " namespace " << ns.name();
170  Solid solid;
171 
172  //set global parameters
173  Material matter = ns.material(genMat);
174  double dzdif = fullHeight + topFrameHeight;
175  if (isStereo)
176  dzdif += 0.5 * (topFrame2LHeight + topFrame2RHeight);
177 
178  double dxbot = 0.5 * dlBottom + frameWidth - frameOver;
179  double dxtop = 0.5 * dlHybrid + frameWidth - frameOver;
180  // topfr = 0.5*dlBottom * sin(detTilt);
181  if (isRing6) {
182  dxbot = dxtop;
183  dxtop = 0.5 * dlTop + frameWidth - frameOver;
184  // topfr = 0.5*dlTop * sin(detTilt);
185  }
186  double dxdif = dxtop - dxbot;
187 
188  //Frame Sides
189  // left Frame
190  name = idName + "SideFrameLeft";
191  double h1 = 0.5 * sideFrameThick;
192  double dz = 0.5 * sideFrameLHeight;
193  double bl1 = 0.5 * sideFrameLWidth;
194  double bl2 = bl1;
195  double thet = sideFrameLtheta;
196  //for stereo modules
197  if (isStereo)
198  bl1 = 0.5 * sideFrameLWidthLow;
199  solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
200  ns.addSolidNS(ns.prepend(name), solid);
201  edm::LogVerbatim("TECGeom") << "Solid: " << name << " " << solid.name() << " Trap made of " << sideFrameMat
202  << " of dimensions " << dz << ", " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1
203  << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
204  Volume sideFrameLeft(ns.prepend(name), solid, ns.material(sideFrameMat));
205  ns.addVolumeNS(sideFrameLeft);
206  //translate
207  double xpos = -0.5 * topFrameBotWidth + bl2 + tan(fabs(thet)) * dz;
208  double ypos = sideFrameZ;
209  double zpos = topFrameEndZ - dz;
210  //flip ring 6
211  if (isRing6) {
212  zpos *= -1;
213  xpos -= 2 * tan(fabs(thet)) * dz; // because of the flip the tan(..) to be in the other direction
214  }
215  //the stereo modules are on the back of the normal ones...
216  if (isStereo) {
217  xpos = -0.5 * topFrameBotWidth + bl2 * cos(detTilt) + dz * sin(fabs(thet) + detTilt) / cos(fabs(thet));
218  xpos = -xpos;
219  zpos = topFrameEndZ - topFrame2LHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
220  dz * cos(detTilt + fabs(thet)) / cos(fabs(thet)) + bl2 * sin(detTilt) - 0.1 * dd4hep::mm;
221  }
222  //position
223  mother.placeVolume(
224  sideFrameLeft,
225  isStereo ? 2 : 1,
226  dd4hep::Transform3D(ns.rotation(waferRot),
227  dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
228 
229  //right Frame
230  name = idName + "SideFrameRight";
231  h1 = 0.5 * sideFrameThick;
232  dz = 0.5 * sideFrameRHeight;
233  bl1 = bl2 = 0.5 * sideFrameRWidth;
234  thet = sideFrameRtheta;
235  if (isStereo)
236  bl1 = 0.5 * sideFrameRWidthLow;
237  solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
238  ns.addSolidNS(ns.prepend(name), solid);
239  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << sideFrameMat
240  << " of dimensions " << dz << ", " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1
241  << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
242  Volume sideFrameRight(ns.prepend(name), solid, ns.material(sideFrameMat));
243  ns.addVolumeNS(sideFrameRight);
244  //translate
245  xpos = 0.5 * topFrameBotWidth - bl2 - tan(fabs(thet)) * dz;
246  ypos = sideFrameZ;
247  zpos = topFrameEndZ - dz;
248  if (isRing6) {
249  zpos *= -1;
250  xpos += 2 * tan(fabs(thet)) * dz; // because of the flip the tan(..) has to be in the other direction
251  }
252  if (isStereo) {
253  xpos = 0.5 * topFrameBotWidth - bl2 * cos(detTilt) - dz * sin(fabs(detTilt - fabs(thet))) / cos(fabs(thet));
254  xpos = -xpos;
255  zpos = topFrameEndZ - topFrame2RHeight + 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
256  dz * cos(detTilt - fabs(thet)) / cos(fabs(thet)) - bl2 * sin(detTilt) - 0.1 * dd4hep::mm;
257  }
258  //position it
259  mother.placeVolume(
260  sideFrameRight,
261  isStereo ? 2 : 1,
262  dd4hep::Transform3D(ns.rotation(waferRot),
263  dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
264  //Supplies Box(es)
265  matter = ns.material(siFrSuppBoxMat);
266  for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++) {
267  name = idName + "SuppliesBox" + std::to_string(i);
268 
269  h1 = 0.5 * siFrSuppBoxThick;
270  dz = 0.5 * siFrSuppBoxHeight[i];
271  bl1 = bl2 = 0.5 * siFrSuppBoxWidth[i];
272  thet = sideFrameRtheta;
273  if (isStereo)
274  thet = -atan(fabs(sideFrameRWidthLow - sideFrameRWidth) / (2 * sideFrameRHeight) - tan(fabs(thet)));
275  // ^-- this calculates the lower left angel of the tipped trapezoid, which is the SideFframe...
276 
277  solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
278  ns.addSolidNS(ns.prepend(name), solid);
279  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << siFrSuppBoxMat
280  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
281  << h1 << ", " << bl2 << ", " << bl2 << ", 0";
282  Volume siFrSuppBox(ns.prepend(name), solid, matter);
283  ns.addVolumeNS(siFrSuppBox);
284  //translate
285  xpos = 0.5 * topFrameBotWidth - sideFrameRWidth - bl1 - siFrSuppBoxYPos[i] * tan(fabs(thet));
286  ypos = sideFrameZ *
287  (0.5 + (siFrSuppBoxThick / sideFrameThick)); //via * so I do not have to worry about the sign of sideFrameZ
288  zpos = topFrameEndZ - siFrSuppBoxYPos[i];
289  if (isRing6) {
290  xpos += 2 * fabs(tan(thet)) * siFrSuppBoxYPos[i]; // the flipped issue again
291  zpos *= -1;
292  }
293  if (isStereo) {
294  xpos = 0.5 * topFrameBotWidth - (sideFrameRWidth + bl1) * cos(detTilt) -
295  sin(fabs(detTilt - fabs(thet))) *
296  (siFrSuppBoxYPos[i] + dz * (1 / cos(thet) - cos(detTilt)) + bl1 * sin(detTilt));
297  xpos = -xpos;
298  zpos = topFrameEndZ - topFrame2RHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
299  siFrSuppBoxYPos[i] - sin(detTilt) * sideFrameRWidth;
300  }
301  //position it;
302  mother.placeVolume(siFrSuppBox,
303  isStereo ? 2 : 1,
304  dd4hep::Transform3D(
305  ns.rotation(waferRot),
306  dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
307  }
308 
309  //The Hybrid
310  name = idName + "Hybrid";
311  double dx = 0.5 * hybridWidth;
312  double dy = 0.5 * hybridThick;
313  dz = 0.5 * hybridHeight;
314  solid = Box(dx, dy, dz);
315  ns.addSolidNS(ns.prepend(name), solid);
316  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << hybridMat
317  << " of dimensions " << dx << ", " << dy << ", " << dz;
318  Volume hybrid(ns.prepend(name), solid, ns.material(hybridMat));
319  ns.addVolumeNS(hybrid);
320 
321  ypos = hybridZ;
322  zpos = 0.5 * (-waferPosition + fullHeight + hybridHeight) + pitchHeight;
323  if (isRing6)
324  zpos *= -1;
325  //position it
326  mother.placeVolume(
327  hybrid,
328  isStereo ? 2 : 1,
329  dd4hep::Transform3D(ns.rotation(standardRot),
330  dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
331 
332  // Wafer
333  name = idName + tag + "Wafer";
334  bl1 = 0.5 * dlBottom;
335  bl2 = 0.5 * dlTop;
336  h1 = 0.5 * waferThick;
337  dz = 0.5 * fullHeight;
338  solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
339  ns.addSolidNS(ns.prepend(name), solid);
340  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << waferMat
341  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
342  << h1 << ", " << bl2 << ", " << bl2 << ", 0";
343  Volume wafer(name, solid, ns.material(waferMat));
344 
345  ypos = activeZ;
346  zpos = -0.5 * waferPosition; // former and incorrect topFrameHeight;
347  if (isRing6)
348  zpos *= -1;
349 
350  mother.placeVolume(
351  wafer,
352  isStereo ? 2 : 1,
353  dd4hep::Transform3D(ns.rotation(waferRot),
354  dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
355 
356  // Active
357  name = idName + tag + "Active";
358  bl1 -= sideWidthBottom;
359  bl2 -= sideWidthTop;
360  dz = 0.5 * (waferThick - backplaneThick); // inactive backplane
361  h1 = 0.5 * activeHeight;
362  if (isRing6) { //switch bl1 <->bl2
363  tmp = bl2;
364  bl2 = bl1;
365  bl1 = tmp;
366  }
367  solid = Trap(dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
368  ns.addSolidNS(ns.prepend(name), solid);
369  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << activeMat
370  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, "
371  << h1 << ", " << bl2 << ", " << bl1 << ", 0";
372  Volume active(ns.prepend(name), solid, ns.material(activeMat));
373  ns.addVolumeNS(active);
374 
375  wafer.placeVolume(
376  active, 1, dd4hep::Transform3D(ns.rotation(activeRot), dd4hep::Position(0., -0.5 * backplaneThick, 0.)));
377 
378  //inactive part in rings > 3
379  if (ringNo > 3) {
380  inactivePos -= fullHeight - activeHeight; //inactivePos is measured from the beginning of the _wafer_
381  name = idName + tag + "Inactive";
382  bl1 = 0.5 * dlBottom - sideWidthBottom +
383  ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
384  (activeHeight - inactivePos - inactiveDy);
385  bl2 = 0.5 * dlBottom - sideWidthBottom +
386  ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
387  (activeHeight - inactivePos + inactiveDy);
388  dz = 0.5 * (waferThick - backplaneThick); // inactive backplane
389  h1 = inactiveDy;
390  if (isRing6) { //switch bl1 <->bl2
391  tmp = bl2;
392  bl2 = bl1;
393  bl1 = tmp;
394  }
395  solid = Trap(dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
396  ns.addSolidNS(ns.prepend(name), solid);
397  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << inactiveMat
398  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, "
399  << h1 << ", " << bl2 << ", " << bl1 << ", 0";
400  Volume inactive(ns.prepend(name), solid, ns.material(inactiveMat));
401  ns.addVolumeNS(inactive);
402  ypos = inactivePos - 0.5 * activeHeight;
403 
404  active.placeVolume(inactive, 1, dd4hep::Position(0., ypos, 0.));
405  }
406  //Pitch Adapter
407  name = idName + "PA";
408  name = ns.prepend(name);
409  if (!isStereo) {
410  dx = 0.5 * pitchWidth;
411  dy = 0.5 * pitchThick;
412  dz = 0.5 * pitchHeight;
413  solid = Box(dx, dy, dz);
414  ns.addSolidNS(name, solid);
415  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << pitchMat
416  << " of dimensions " << dx << ", " << dy << ", " << dz;
417  } else {
418  dz = 0.5 * pitchWidth;
419  h1 = 0.5 * pitchThick;
420  bl1 = 0.5 * pitchHeight + 0.5 * dz * sin(detTilt);
421  bl2 = 0.5 * pitchHeight - 0.5 * dz * sin(detTilt);
422  thet = atan((bl1 - bl2) / (2. * dz));
423  solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
424  ns.addSolidNS(name, solid);
425  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << pitchMat
426  << " of dimensions " << dz << ", " << convertRadToDeg(thet) << ", 0, " << h1 << ", "
427  << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
428  }
429  xpos = 0;
430  ypos = pitchZ;
431  zpos = 0.5 * (-waferPosition + fullHeight + pitchHeight);
432  if (isRing6)
433  zpos *= -1;
434  if (isStereo)
435  xpos = 0.5 * fullHeight * sin(detTilt);
436 
437  Volume pa(name, solid, ns.material(pitchMat));
438  if (isStereo)
439  mother.placeVolume(pa,
440  2,
441  dd4hep::Transform3D(ns.rotation(pitchRot),
442  dd4hep::Position(zpos + rPos, xpos + rPos * sin(posCorrectionPhi), ypos)));
443  else
444  mother.placeVolume(pa, 1, dd4hep::Transform3D(ns.rotation(standardRot), dd4hep::Position(zpos + rPos, xpos, ypos)));
445 
446  //Top of the frame
447  name = idName + "TopFrame";
448  h1 = 0.5 * topFrameThick;
449  dz = 0.5 * topFrameHeight;
450  bl1 = 0.5 * topFrameBotWidth;
451  bl2 = 0.5 * topFrameTopWidth;
452  if (isRing6) { // ring 6 faces the other way!
453  bl1 = 0.5 * topFrameTopWidth;
454  bl2 = 0.5 * topFrameBotWidth;
455  }
456 
457  solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
458  ns.addSolid(ns.prepend(name), solid);
459  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << topFrameMat
460  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
461  << h1 << ", " << bl2 << ", " << bl2 << ", 0";
462  Volume topFrame(ns.prepend(name), solid, ns.material(topFrameMat));
463  ns.addVolumeNS(topFrame);
464 
465  if (isStereo) {
466  name = idName + "TopFrame2";
467  //additional object to build the not trapzoid geometry of the stereo topframes
468  dz = 0.5 * topFrame2Width;
469  h1 = 0.5 * topFrameThick;
470  bl1 = 0.5 * topFrame2LHeight;
471  bl2 = 0.5 * topFrame2RHeight;
472  thet = atan((bl1 - bl2) / (2. * dz));
473 
474  constexpr double minDimension = 5.e-8; // mm value == 5.e-11 meters
475  if (bl2 < minDimension) {
476  // If Trapezoid dimension is too tiny, reset to reasonable minimum value that is still effectively zero.
477  bl2 = minDimension;
478  }
479  solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
480  ns.addSolid(ns.prepend(name), solid);
481  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << topFrameMat
482  << " of dimensions " << dz << ", " << convertRadToDeg(thet) << ", 0, " << h1 << ", "
483  << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
484  }
485 
486  // Position the topframe
487  ypos = topFrameZ;
488  zpos = 0.5 * (-waferPosition + fullHeight - topFrameHeight) + pitchHeight + hybridHeight;
489  if (isRing6) {
490  zpos *= -1;
491  }
492 
493  mother.placeVolume(
494  topFrame,
495  isStereo ? 2 : 1,
496  dd4hep::Transform3D(ns.rotation(standardRot),
497  dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
498  if (isStereo) {
499  //create
500  Volume topFrame2(name, solid, ns.material(topFrameMat));
501  zpos -= 0.5 * (topFrameHeight + 0.5 * (topFrame2LHeight + topFrame2RHeight));
502  mother.placeVolume(
503  topFrame2,
504  2,
505  dd4hep::Transform3D(ns.rotation(pitchRot), dd4hep::Position(zpos + rPos, rPos * sin(posCorrectionPhi), ypos)));
506  }
507 
508  //Si - Reencorcement
509  matter = ns.material(siReenforceMat);
510  for (int i = 0; i < (int)(siReenforceWidth.size()); i++) {
511  name = idName + "SiReenforce" + std::to_string(i);
512  h1 = 0.5 * siReenforceThick;
513  dz = 0.5 * siReenforceHeight[i];
514  bl1 = bl2 = 0.5 * siReenforceWidth[i];
515  solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
516  ns.addSolid(ns.prepend(name), solid);
517  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << matter.name()
518  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
519  << h1 << ", " << bl2 << ", " << bl2 << ", 0";
520  Volume siReenforce(ns.prepend(name), solid, matter);
521  ns.addVolumeNS(siReenforce);
522  //translate
523  xpos = 0;
524  ypos = sideFrameZ;
525  zpos = topFrameEndZ - dz - siReenforceYPos[i];
526 
527  if (isRing6)
528  zpos *= -1;
529  if (isStereo) {
530  xpos = (-siReenforceYPos[i] + 0.5 * fullHeight) * sin(detTilt);
531  // thet = detTilt;
532  // if(topFrame2RHeight > topFrame2LHeight) thet *= -1;
533  // zpos -= topFrame2RHeight + sin(thet)*(sideFrameRWidth + 0.5*dlTop);
534  zpos -= topFrame2RHeight + sin(fabs(detTilt)) * 0.5 * topFrame2Width;
535  }
536 
537  mother.placeVolume(siReenforce,
538  isStereo ? 2 : 1,
539  dd4hep::Transform3D(
540  ns.rotation(waferRot),
541  dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
542  }
543 
544  //Bridge
545  if (bridgeMat != "None") {
546  name = idName + "Bridge";
547  bl2 = 0.5 * bridgeSep + bridgeWidth;
548  bl1 = bl2 - bridgeHeight * dxdif / dzdif;
549  h1 = 0.5 * bridgeThick;
550  dz = 0.5 * bridgeHeight;
551  solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
552  ns.addSolid(ns.prepend(name), solid);
553  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << bridgeMat
554  << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
555  << h1 << ", " << bl2 << ", " << bl2 << ", 0";
556  Volume bridge(ns.prepend(name), solid, ns.material(bridgeMat));
557  ns.addVolumeNS(bridge);
558 
559  name = idName + "BridgeGap";
560  bl1 = 0.5 * bridgeSep;
561  solid = Box(bl1, h1, dz);
562  ns.addSolid(ns.prepend(name), solid);
563  edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << genMat
564  << " of dimensions " << bl1 << ", " << h1 << ", " << dz;
565  Volume bridgeGap(ns.prepend(name), solid, ns.material(genMat));
566  ns.addVolumeNS(bridgeGap);
567  /* PlacedVolume pv = */ bridge.placeVolume(bridgeGap, 1);
568  edm::LogVerbatim("TECGeom") << "Solid: " << bridgeGap.name() << " number 1 positioned in " << bridge.name()
569  << " at (0,0,0) with no rotation";
570  }
571  edm::LogVerbatim("TECGeom") << "<<== End of DDTECModuleAlgo construction ...";
572  return 1;
573 }
574 
575 // first argument is the type from the xml file
576 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTECModuleAlgo, algorithm)
Log< level::Info, true > LogVerbatim
const dd4hep::Rotation3D & rotation(const std::string &name) const
Definition: DDNamespace.cc:182
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::string to_string(const V &value)
Definition: OMSAccess.h:71
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:166
std::string noNamespace(const std::string &) const
Definition: DDNamespace.cc:353
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:25
std::string_view name() const
Definition: DDNamespace.h:79
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
int32_t waferThick(const int32_t property)
dd4hep::Volume Volume
Namespace of DDCMS conversion namespace.
dd4hep::Solid addSolid(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:307
dd4hep::Volume addVolumeNS(dd4hep::Volume vol) const
Definition: DDNamespace.cc:202
tmp
align.sh
Definition: createJobs.py:716
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:276
static long algorithm(Detector &, cms::DDParsingContext &ctxt, xml_h e)
dd4hep::Solid addSolidNS(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:292
std::string prepend(const std::string &) const
Definition: DDNamespace.cc:99