CMS 3D CMS Logo

DDTIDModulePosAlgo.cc
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
5 
6 using namespace std;
7 using namespace dd4hep;
8 using namespace cms;
9 using namespace cms_units::operators;
10 
11 static long algorithm(Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
12  cms::DDNamespace ns(ctxt, e, true);
13  DDAlgoArguments args(ctxt, e);
14  string parentName = args.parentName();
15  int detectorN = args.integer("DetectorNumber"); //Number of detectors
16  double detTilt = args.dble("DetTilt"); //Tilt of stereo detector
17  double fullHeight = args.dble("FullHeight"); //Height
18  string boxFrameName = args.str("BoxFrameName"); //Top frame Name
19  double boxFrameHeight = args.dble("BoxFrameHeight"); // height
20  double boxFrameWidth = args.dble("BoxFrameWidth"); // width
21  double dlTop = args.dble("DlTop"); //Width at top of wafer
22  double dlBottom = args.dble("DlBottom"); //Width at bottom of wafer
23  double dlHybrid = args.dble("DlHybrid"); //Width at the hybrid end
24  vector<double> boxFrameZ = args.vecDble("BoxFrameZ"); // z-positions
25  double bottomFrameHeight = args.dble("BottomFrameHeight"); //Bottom of the frame
26  double bottomFrameOver = args.dble("BottomFrameOver"); // overlap
27  double topFrameHeight = args.dble("TopFrameHeight"); //Top of the frame
28  double topFrameOver = args.dble("TopFrameOver"); // overlap
29 
30  vector<string> sideFrameName = args.vecStr("SideFrameName"); //Side Frame name
31  vector<double> sideFrameZ = args.vecDble("SideFrameZ"); // z-positions
32  vector<string> sideFrameRot = args.vecStr(
33  "SideFrameRotation"); // rotation matrix (required for correct positiong of the hole in the StereoR)
34  double sideFrameWidth = args.dble("SideFrameWidth"); // width
35  double sideFrameOver = args.dble("SideFrameOver"); // overlap (wrt wafer)
36 
37  vector<string> kaptonName = args.vecStr("KaptonName"); //Kapton Circuit name
38  vector<double> kaptonZ = args.vecDble("KaptonZ"); // z-positions
39  vector<string> kaptonRot = args.vecStr(
40  "KaptonRotation"); // rotation matrix (required for correct positiong of the hole in the StereoR)
41  vector<string> waferName = args.vecStr("WaferName"); //Wafer name
42  vector<double> waferZ = args.vecDble("WaferZ"); // z-positions
43  vector<string> waferRot = args.vecStr("WaferRotation"); // rotation matrix
44  string hybridName = args.str("HybridName"); //Hybrid name
45  double hybridHeight = args.dble("HybridHeight"); // height
46  vector<double> hybridZ = args.vecDble("HybridZ"); // z-positions
47  vector<string> pitchName = args.vecStr("PitchName"); //Pitch adapter rotation matrix
48  double pitchHeight = args.dble("PitchHeight"); // height
49  vector<double> pitchZ = args.vecDble("PitchZ"); // z-positions
50  vector<string> pitchRot = args.vecStr("PitchRotation"); // rotation matrix
51  string coolName = args.str("CoolInsertName"); //Cool Insert name
52  double coolHeight = args.dble("CoolInsertHeight"); // height
53  double coolZ = args.dble("CoolInsertZ"); // z-position
54  double coolWidth = args.dble("CoolInsertWidth"); // width
55  vector<double> coolRadShift = args.vecDble("CoolInsertShift"); //
56 
57  bool doSpacers =
58  ::toupper(args.str("DoSpacers")[0]) != 'N'; //Spacers (alumina) to be made (Should be "Yes" for DS modules only)
59  string botSpacersName = args.str("BottomSpacersName"); // Spacers at the "bottom" of the module
60  double botSpacersHeight = args.dble("BottomSpacersHeight"); //
61  double botSpacersZ = args.dble("BottomSpacersZ"); // z-position
62  string sidSpacersName = args.str("SideSpacersName"); //Spacers at the "sides" of the module
63  double sidSpacersHeight = args.dble("SideSpacersHeight");
64  double sidSpacersZ = args.dble("SideSpacersZ"); // z-position
65  double sidSpacersWidth = args.dble("SideSpacersWidth"); // width
66  double sidSpacersRadShift = args.dble("SideSpacersShift"); //
67 
68  edm::LogVerbatim("TIDGeom") << "Parent " << parentName << " Detector Planes " << detectorN;
69  edm::LogVerbatim("TIDGeom") << "Detector Tilt " << convertRadToDeg(detTilt) << " Height " << fullHeight << " dl(Top) "
70  << dlTop << " dl(Bottom) " << dlBottom << " dl(Hybrid) " << dlHybrid;
71  edm::LogVerbatim("TIDGeom") << boxFrameName << " positioned at Z";
72  for (int i = 0; i < detectorN; i++)
73  edm::LogVerbatim("TIDGeom") << "\tboxFrameZ[" << i << "] = " << boxFrameZ[i];
74  edm::LogVerbatim("TIDGeom") << "\t Extra Height at Bottom " << bottomFrameHeight << " Overlap " << bottomFrameOver;
75  for (int i = 0; i < detectorN; i++)
76  edm::LogVerbatim("TIDGeom") << "\tsideFrame[" << i << "] = " << sideFrameName[i] << " positioned at Z "
77  << sideFrameZ[i] << " with rotation " << sideFrameRot[i];
78  for (int i = 0; i < detectorN; i++)
79  edm::LogVerbatim("TIDGeom") << "\tkapton[" << i << "] = " << kaptonName[i] << " positioned at Z " << kaptonZ[i]
80  << " with rotation " << kaptonRot[i];
81  for (int i = 0; i < detectorN; i++)
82  edm::LogVerbatim("TIDGeom") << waferName[i] << " positioned at Z " << waferZ[i] << " with rotation " << waferRot[i];
83  edm::LogVerbatim("TIDGeom") << hybridName << " Height " << hybridHeight << " Z";
84  for (int i = 0; i < detectorN; i++)
85  edm::LogVerbatim("TIDGeom") << "\thybridZ[" << i << "] = " << hybridZ[i];
86  edm::LogVerbatim("TIDGeom") << "Pitch Adapter Height " << pitchHeight;
87  for (int i = 0; i < detectorN; i++)
88  edm::LogVerbatim("TIDGeom") << pitchName[i] << " position at Z " << pitchZ[i] << " with rotation " << pitchRot[i];
89 
90  string name;
91  double botfr; // width of side frame at the the bottom of the modules
92  double topfr; // width of side frame at the the top of the modules
93  double kaptonHeight;
94  if (dlHybrid > dlTop) {
95  // ring 1, ring 2
96  topfr = topFrameHeight - pitchHeight - topFrameOver;
97  botfr = bottomFrameHeight - bottomFrameOver;
98  kaptonHeight = fullHeight + botfr;
99  } else {
100  // ring 3
101  topfr = topFrameHeight - topFrameOver;
102  botfr = bottomFrameHeight - bottomFrameOver - pitchHeight;
103  kaptonHeight = fullHeight + topfr;
104  }
105 
106  double sideFrameHeight = fullHeight + pitchHeight + botfr + topfr;
107  double zCenter = 0.5 * (sideFrameHeight + boxFrameHeight);
108 
109  // (Re) Compute the envelope for positioning Cool Inserts and Side Spacers (Alumina).
110  double sidfr = sideFrameWidth - sideFrameOver; // width of side frame on the sides of module
111  double dxbot = 0.5 * dlBottom + sidfr;
112  double dxtop = 0.5 * dlTop + sidfr;
113  double dxtopenv, dxbotenv; // top/bot width of the module envelope trap
114 
115  double tanWafer = (dxtop - dxbot) / fullHeight; //
116  double thetaWafer = atan(tanWafer); // 1/2 of the wafer wedge angle
117 
118  if (dlHybrid > dlTop) {
119  // ring 1, ring 2
120  dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + pitchHeight + topfr + hybridHeight) / fullHeight;
121  dxbotenv = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
122  } else {
123  // ring 3
124  dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
125  dxbotenv = dxbot;
126  }
127 
128  double tanEnv = (dxtopenv - dxbotenv) / (sideFrameHeight + boxFrameHeight); // 1/2 of the envelope wedge angle
129 
130  double xpos = 0;
131  double ypos = 0;
132  double zpos = 0;
133 
134  // Cool Inserts
135  name = coolName;
136  ypos = coolZ;
137 
138  double zCool;
139  int copy = 0;
140  Rotation3D rot; // should be different for different elements
141  Volume parentVol = ns.volume(parentName);
142 
143  for (int j1 = 0; j1 < 2; j1++) { // j1: 0 inserts below the hybrid
144  // 1 inserts below the wafer
145  if (dlHybrid > dlTop) {
146  zCool = sideFrameHeight + boxFrameHeight - coolRadShift[j1];
147  if (j1 == 0)
148  zCool -= 0.5 * coolHeight;
149  } else {
150  zCool = coolRadShift[j1];
151  if (j1 == 0)
152  zCool += 0.5 * coolHeight;
153  }
154 
155  if (j1 == 0) {
156  xpos = -0.5 * (boxFrameWidth - coolWidth);
157  } else {
158  xpos = -(dxbotenv + (zCool - 0.5 * coolHeight) * tanEnv - 0.5 * coolWidth);
159  }
160 
161  zpos = zCool - zCenter;
162  for (int j2 = 0; j2 < 2; j2++) {
163  copy++;
164  parentVol.placeVolume(ns.volume(name), copy, Position(xpos, ypos, zpos));
165  edm::LogVerbatim("TIDGeom") << name << " number " << copy << " positioned in " << parentName << " at "
166  << Position(xpos, ypos, zpos) << " with " << rot;
167  xpos = -xpos;
168  }
169  }
170 
171  if (doSpacers) {
172  // Bottom Spacers (Alumina)
173  name = botSpacersName;
174  ypos = botSpacersZ;
175  double zBotSpacers;
176  if (dlHybrid > dlTop) {
177  zBotSpacers = sideFrameHeight + boxFrameHeight - 0.5 * botSpacersHeight;
178  } else {
179  zBotSpacers = 0.5 * botSpacersHeight;
180  }
181  zpos = zBotSpacers - zCenter;
182  parentVol.placeVolume(ns.volume(name), 1, Position(0.0, ypos, zpos));
183  edm::LogVerbatim("TIDGeom") << name << " number " << 1 << " positioned in " << parentName << " at "
184  << Position(0.0, ypos, zpos) << " with no rotation";
185  // Side Spacers (Alumina)
186  name = sidSpacersName;
187  ypos = sidSpacersZ;
188  double zSideSpacers;
189  if (dlHybrid > dlTop) {
190  zSideSpacers = sideFrameHeight + boxFrameHeight - sidSpacersRadShift;
191  } else {
192  zSideSpacers = sidSpacersRadShift;
193  }
194  zpos = zSideSpacers - zCenter;
195 
196  copy = 0;
197  xpos = dxbotenv + (zSideSpacers - 0.5 * sidSpacersHeight) * tanEnv - 0.5 * sidSpacersWidth + sideFrameOver;
198 
199  double phiy = 0e0, phiz = 0e0;
200  double phix = 0._deg;
201  phiy = 90._deg;
202  phiz = 0._deg;
203 
204  double thetax = 0e0;
205  double thetay = 90._deg;
206  double thetaz = thetaWafer;
207 
208  for (int j1 = 0; j1 < 2; j1++) {
209  copy++;
210  // tilt Side Spacers (parallel to Side Frame)
211  thetax = 90._deg + thetaz;
212  rot = makeRotation3D(thetax, phix, thetay, phiy, thetaz, phiz);
213  parentVol.placeVolume(ns.volume(name), copy, Transform3D(rot, Position(xpos, ypos, zpos)));
214  edm::LogVerbatim("TIDGeom") << name << " number " << copy << " positioned in " << parentName << " at "
215  << Position(xpos, ypos, zpos) << " with " << rot;
216  xpos = -xpos;
217  thetaz = -thetaz;
218  }
219  }
220 
221  // Loop over detectors to be placed
222  for (int k = 0; k < detectorN; k++) {
223  // Wafer
224  name = waferName[k];
225  xpos = 0;
226  ypos = waferZ[k];
227  double zWafer;
228  if (dlHybrid > dlTop) {
229  zWafer = botfr + 0.5 * fullHeight;
230  } else {
231  zWafer = boxFrameHeight + botfr + pitchHeight + 0.5 * fullHeight;
232  }
233  zpos = zWafer - zCenter;
234  Position tran(xpos, ypos, zpos);
235  rot = ns.rotation(waferRot[k]);
236 
237  parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran)); // copyNr=k+1
238  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
239  << " with " << rot;
240 
241  //Pitch Adapter
242  name = pitchName[k];
243  if (k == 0) {
244  xpos = 0;
245  } else {
246  xpos = 0.5 * fullHeight * sin(detTilt);
247  }
248  ypos = pitchZ[k];
249  double zPitch;
250  if (dlHybrid > dlTop) {
251  zPitch = botfr + fullHeight + 0.5 * pitchHeight;
252  } else {
253  zPitch = boxFrameHeight + botfr + 0.5 * pitchHeight;
254  }
255  zpos = zPitch - zCenter;
256  rot = ns.rotation(pitchRot[k]);
257  tran = Position(xpos, ypos, zpos);
258  parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran)); // copyNr=k+1
259  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
260  << " with " << rot;
261 
262  // Hybrid
263  name = hybridName;
264  ypos = hybridZ[k];
265  double zHybrid;
266  if (dlHybrid > dlTop) {
267  zHybrid = botfr + fullHeight + pitchHeight + 0.5 * hybridHeight;
268  } else {
269  zHybrid = 0.5 * hybridHeight;
270  }
271  zpos = zHybrid - zCenter;
272  tran = Position(0, ypos, zpos);
273  parentVol.placeVolume(ns.volume(name), k + 1, tran); // copyNr=k+1
274  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran;
275 
276  // Box frame
277  name = boxFrameName;
278  ypos = boxFrameZ[k];
279  double zBoxFrame;
280  if (dlHybrid > dlTop) {
281  zBoxFrame = sideFrameHeight + 0.5 * boxFrameHeight;
282  } else {
283  zBoxFrame = 0.5 * boxFrameHeight;
284  }
285  zpos = zBoxFrame - zCenter;
286  tran = Position(0, ypos, zpos);
287  parentVol.placeVolume(ns.volume(name), k + 1, tran); // copyNr=k+1
288  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran;
289 
290  // Side frame
291  name = sideFrameName[k];
292  ypos = sideFrameZ[k];
293  double zSideFrame;
294  if (dlHybrid > dlTop) {
295  zSideFrame = 0.5 * sideFrameHeight;
296  } else {
297  zSideFrame = boxFrameHeight + 0.5 * sideFrameHeight;
298  }
299  zpos = zSideFrame - zCenter;
300  rot = ns.rotation(sideFrameRot[k]);
301  tran = Position(0, ypos, zpos);
302  parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));
303  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
304  << " with " << rot;
305  // Kapton circuit
306  name = kaptonName[k];
307  ypos = kaptonZ[k];
308  double zKapton;
309  double kaptonExtraHeight = 0;
310  if (dlHybrid > dlTop) {
311  if (k == 1)
312  kaptonExtraHeight = dlTop * sin(detTilt) - fullHeight * (1 - cos(detTilt));
313  kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
314  zKapton = 0.5 * (kaptonHeight + kaptonExtraHeight);
315  } else {
316  if (k == 1)
317  kaptonExtraHeight = dlBottom * sin(detTilt) - fullHeight * (1 - cos(detTilt));
318  kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
319  zKapton = boxFrameHeight + sideFrameHeight - 0.5 * (kaptonHeight + kaptonExtraHeight);
320  }
321  zpos = zKapton - zCenter;
322  rot = ns.rotation(kaptonRot[k]);
323  tran = Position(0, ypos, zpos);
324  parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));
325  edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
326  << " with " << rot;
327  }
328  edm::LogVerbatim("TIDGeom") << "<<== End of DDTIDModulePosAlgo positioning ...";
329  return 1;
330 }
331 
332 // first argument is the type from the xml file
333 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTIDModulePosAlgo, 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
DDRotationMatrix makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:25
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
dd4hep::Volume Volume
Namespace of DDCMS conversion namespace.
static long algorithm(Detector &, cms::DDParsingContext &ctxt, xml_h e)
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:276