CMS 3D CMS Logo

DDTIDModulePosAlgo.cc
Go to the documentation of this file.
1 // File: DDTIDModulePosAlgo.cc
3 // Description: Position various components inside a TID Module
5 
12 #include "CLHEP/Units/GlobalPhysicalConstants.h"
13 #include "CLHEP/Units/GlobalSystemOfUnits.h"
14 
15 #include <string>
16 #include <vector>
17 
18 using namespace std;
19 
20 class DDTIDModulePosAlgo : public DDAlgorithm {
21 public:
22  //Constructor and Destructor
24  ~DDTIDModulePosAlgo() override;
25 
26  void initialize(const DDNumericArguments& nArgs,
27  const DDVectorArguments& vArgs,
28  const DDMapArguments& mArgs,
29  const DDStringArguments& sArgs,
30  const DDStringVectorArguments& vsArgs) override;
31  void execute(DDCompactView& cpv) override;
32 
33 private:
34  int detectorN; //Number of detectors
35  double detTilt; //Tilt of stereo detector
36  double fullHeight; //Height
37  string boxFrameName; //Top frame Name
38  double boxFrameHeight; // height
39  double boxFrameWidth; // width
40  double dlTop; //Width at top of wafer
41  double dlBottom; //Width at bottom of wafer
42  double dlHybrid; //Width at the hybrid end
43  vector<double> boxFrameZ; // z-positions
44  double bottomFrameHeight; //Bottom of the frame
45  double bottomFrameOver; // overlap
46  double topFrameHeight; //Top of the frame
47  double topFrameOver; // overlap
48 
49  vector<string> sideFrameName; //Side Frame name
50  vector<double> sideFrameZ; // z-positions
51  vector<string>
52  sideFrameRot; // rotation matrix (required for correct positiong of the hole in the StereoR)
53  double sideFrameWidth; // width
54  double sideFrameOver; // overlap (wrt wafer)
55 
56  vector<string> kaptonName; //Kapton Circuit name
57  vector<double> kaptonZ; // z-positions
58  vector<string> kaptonRot; // rotation matrix (required for correct positiong of the hole in the StereoR)
59  vector<string> waferName; //Wafer name
60  vector<double> waferZ; // z-positions
61  vector<string> waferRot; // rotation matrix
62  string hybridName; //Hybrid name
63  double hybridHeight; // height
64  vector<double> hybridZ; // z-positions
65  vector<string> pitchName; //Pitch adapter rotation matrix
66  double pitchHeight; // height
67  vector<double> pitchZ; // z-positions
68  vector<string> pitchRot; // rotation matrix
69  string coolName; //Cool Insert name
70  double coolHeight; // height
71  double coolZ; // z-position
72  double coolWidth; // width
73  vector<double> coolRadShift; //
74 
75  bool doSpacers; //Spacers (alumina) to be made (Should be "Yes" for DS modules only)
76  string botSpacersName; // Spacers at the "bottom" of the module
77  double botSpacersHeight; //
78  double botSpacersZ; // z-position
79  string sidSpacersName; //Spacers at the "sides" of the module
81  double sidSpacersZ; // z-position
82  double sidSpacersWidth; // width
83  double sidSpacersRadShift; //
84 };
85 
86 DDTIDModulePosAlgo::DDTIDModulePosAlgo() { LogDebug("TIDGeom") << "DDTIDModulePosAlgo info: Creating an instance"; }
87 
89 
91  const DDVectorArguments& vArgs,
92  const DDMapArguments&,
93  const DDStringArguments& sArgs,
94  const DDStringVectorArguments& vsArgs) {
95  int i;
96  DDName parentName = parent().name();
97  detectorN = (int)(nArgs["DetectorNumber"]);
98 
99  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: Parent " << parentName << " Detector Planes " << detectorN;
100 
101  detTilt = nArgs["DetTilt"];
102  fullHeight = nArgs["FullHeight"];
103  dlTop = nArgs["DlTop"];
104  dlBottom = nArgs["DlBottom"];
105  dlHybrid = nArgs["DlHybrid"];
106 
107  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: Detector Tilt " << detTilt / CLHEP::deg << " Height " << fullHeight
108  << " dl(Top) " << dlTop << " dl(Bottom) " << dlBottom << " dl(Hybrid) " << dlHybrid;
109 
110  boxFrameName = sArgs["BoxFrameName"];
111  boxFrameHeight = nArgs["BoxFrameHeight"];
112  boxFrameWidth = nArgs["BoxFrameWidth"];
113  boxFrameZ = vArgs["BoxFrameZ"];
114  bottomFrameHeight = nArgs["BottomFrameHeight"];
115  bottomFrameOver = nArgs["BottomFrameOver"];
116  topFrameHeight = nArgs["TopFrameHeight"];
117  topFrameOver = nArgs["TopFrameOver"];
118  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: " << boxFrameName << " positioned at Z";
119  for (i = 0; i < detectorN; i++)
120  LogDebug("TIDGeom") << "\tboxFrameZ[" << i << "] = " << boxFrameZ[i];
121  LogDebug("TIDGeom") << "\t Extra Height at Bottom " << bottomFrameHeight << " Overlap " << bottomFrameOver;
122 
123  sideFrameName = vsArgs["SideFrameName"];
124  sideFrameZ = vArgs["SideFrameZ"];
125  sideFrameRot = vsArgs["SideFrameRotation"];
126  sideFrameWidth = nArgs["SideFrameWidth"];
127  sideFrameOver = nArgs["SideFrameOver"];
128  for (i = 0; i < detectorN; i++)
129  LogDebug("TIDGeom") << "\tsideFrame[" << i << "] = " << sideFrameName[i] << " positioned at Z " << sideFrameZ[i]
130  << " with rotation " << sideFrameRot[i];
131 
132  kaptonName = vsArgs["KaptonName"];
133  kaptonZ = vArgs["KaptonZ"];
134  kaptonRot = vsArgs["KaptonRotation"];
135  for (i = 0; i < detectorN; i++)
136  LogDebug("TIDGeom") << "\tkapton[" << i << "] = " << kaptonName[i] << " positioned at Z " << kaptonZ[i]
137  << " with rotation " << kaptonRot[i];
138 
139  waferName = vsArgs["WaferName"];
140  waferZ = vArgs["WaferZ"];
141  waferRot = vsArgs["WaferRotation"];
142  for (i = 0; i < detectorN; i++)
143  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: " << waferName[i] << " positioned at Z " << waferZ[i]
144  << " with rotation " << waferRot[i];
145 
146  hybridName = sArgs["HybridName"];
147  hybridHeight = nArgs["HybridHeight"];
148  hybridZ = vArgs["HybridZ"];
149  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: " << hybridName << " Height " << hybridHeight << " Z";
150  for (i = 0; i < detectorN; i++)
151  LogDebug("TIDGeom") << "\thybridZ[" << i << "] = " << hybridZ[i];
152 
153  pitchName = vsArgs["PitchName"];
154  pitchHeight = nArgs["PitchHeight"];
155  pitchZ = vArgs["PitchZ"];
156  pitchRot = vsArgs["PitchRotation"];
157  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: Pitch Adapter Height " << pitchHeight;
158  for (i = 0; i < detectorN; i++)
159  LogDebug("TIDGeom") << "DDTIDModulePosAlgo debug: " << pitchName[i] << " position at Z " << pitchZ[i]
160  << " with rotation " << pitchRot[i];
161 
162  coolName = sArgs["CoolInsertName"];
163  coolHeight = nArgs["CoolInsertHeight"];
164  coolZ = nArgs["CoolInsertZ"];
165  coolWidth = nArgs["CoolInsertWidth"];
166  coolRadShift = vArgs["CoolInsertShift"];
167 
168  string comp = sArgs["DoSpacers"];
169  if (comp == "No" || comp == "NO" || comp == "no")
170  doSpacers = false;
171  else
172  doSpacers = true;
173 
174  botSpacersName = sArgs["BottomSpacersName"];
175  botSpacersHeight = nArgs["BottomSpacersHeight"];
176  botSpacersZ = nArgs["BottomSpacersZ"];
177  sidSpacersName = sArgs["SideSpacersName"];
178  sidSpacersHeight = nArgs["SideSpacersHeight"];
179  sidSpacersZ = nArgs["SideSpacersZ"];
180  sidSpacersWidth = nArgs["SideSpacersWidth"];
181  sidSpacersRadShift = nArgs["SideSpacersShift"];
182 }
183 
185  LogDebug("TIDGeom") << "==>> Constructing DDTIDModulePosAlgo...";
186 
187  DDName parentName = parent().name();
188 
189  double botfr; // width of side frame at the the bottom of the modules
190  double topfr; // width of side frame at the the top of the modules
191  double kaptonHeight;
192  if (dlHybrid > dlTop) {
193  // ring 1, ring 2
194  topfr = topFrameHeight - pitchHeight - topFrameOver;
195  botfr = bottomFrameHeight - bottomFrameOver;
196  kaptonHeight = fullHeight + botfr;
197  } else {
198  // ring 3
199  topfr = topFrameHeight - topFrameOver;
200  botfr = bottomFrameHeight - bottomFrameOver - pitchHeight;
201  kaptonHeight = fullHeight + topfr;
202  }
203 
204  double sideFrameHeight = fullHeight + pitchHeight + botfr + topfr;
205  double zCenter = 0.5 * (sideFrameHeight + boxFrameHeight);
206 
207  // (Re) Compute the envelope for positioning Cool Inserts and Side Spacers (Alumina).
208  double sidfr = sideFrameWidth - sideFrameOver; // width of side frame on the sides of module
209  double dxbot = 0.5 * dlBottom + sidfr;
210  double dxtop = 0.5 * dlTop + sidfr;
211  double dxtopenv, dxbotenv; // top/bot width of the module envelope trap
212 
213  double tanWafer = (dxtop - dxbot) / fullHeight; //
214  double thetaWafer = atan(tanWafer); // 1/2 of the wafer wedge angle
215 
216  if (dlHybrid > dlTop) {
217  // ring 1, ring 2
218  dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + pitchHeight + topfr + hybridHeight) / fullHeight;
219  dxbotenv = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
220  } else {
221  // ring 3
222  dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
223  dxbotenv = dxbot;
224  }
225 
226  double tanEnv = (dxtopenv - dxbotenv) / (sideFrameHeight + boxFrameHeight); // 1/2 of the envelope wedge angle
227 
228  double xpos = 0;
229  double ypos = 0;
230  double zpos = 0;
231 
232  // Cool Inserts
233  DDName name = DDName(DDSplit(coolName).first, DDSplit(coolName).second);
234  ypos = coolZ;
235 
236  double zCool;
237  int copy = 0;
238  DDRotation rot = DDRotation(); // should be different for different elements
239 
240  for (int j1 = 0; j1 < 2; j1++) { // j1: 0 inserts below the hybrid
241  // 1 inserts below the wafer
242  if (dlHybrid > dlTop) {
243  zCool = sideFrameHeight + boxFrameHeight - coolRadShift[j1];
244  if (j1 == 0)
245  zCool -= 0.5 * coolHeight;
246  } else {
247  zCool = coolRadShift[j1];
248  if (j1 == 0)
249  zCool += 0.5 * coolHeight;
250  }
251 
252  if (j1 == 0) {
253  xpos = -0.5 * (boxFrameWidth - coolWidth);
254  } else {
255  xpos = -(dxbotenv + (zCool - 0.5 * coolHeight) * tanEnv - 0.5 * coolWidth);
256  }
257 
258  zpos = zCool - zCenter;
259  for (int j2 = 0; j2 < 2; j2++) {
260  copy++;
261  cpv.position(name, parentName, copy, DDTranslation(xpos, ypos, zpos), rot);
262  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << copy << " positioned in "
263  << parentName << " at " << DDTranslation(xpos, ypos, zpos) << " with " << rot;
264  xpos = -xpos;
265  }
266  }
267 
268  if (doSpacers) {
269  // Bottom Spacers (Alumina)
270  DDName name = DDName(DDSplit(botSpacersName).first, DDSplit(botSpacersName).second);
271  ypos = botSpacersZ;
272 
273  double zBotSpacers;
274  if (dlHybrid > dlTop) {
275  zBotSpacers = sideFrameHeight + boxFrameHeight - 0.5 * botSpacersHeight;
276  } else {
277  zBotSpacers = 0.5 * botSpacersHeight;
278  }
279  zpos = zBotSpacers - zCenter;
280  rot = DDRotation();
281  cpv.position(name, parentName, 1, DDTranslation(0.0, ypos, zpos), rot);
282  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << 1 << " positioned in " << parentName
283  << " at " << DDTranslation(0.0, ypos, zpos) << " with no rotation";
284 
285  // Side Spacers (Alumina)
286  name = DDName(DDSplit(sidSpacersName).first, DDSplit(sidSpacersName).second);
287  ypos = sidSpacersZ;
288 
289  double zSideSpacers;
290  if (dlHybrid > dlTop) {
291  zSideSpacers = sideFrameHeight + boxFrameHeight - sidSpacersRadShift;
292  } else {
293  zSideSpacers = sidSpacersRadShift;
294  }
295  zpos = zSideSpacers - zCenter;
296 
297  copy = 0;
298  xpos = dxbotenv + (zSideSpacers - 0.5 * sidSpacersHeight) * tanEnv - 0.5 * sidSpacersWidth + sideFrameOver;
299 
300  double phix, phiy, phiz;
301  phix = 0. * CLHEP::deg;
302  phiy = 90. * CLHEP::deg;
303  phiz = 0. * CLHEP::deg;
304 
305  double thetay, thetax;
306  thetay = 90. * CLHEP::deg;
307  double thetaz = thetaWafer;
308 
309  for (int j1 = 0; j1 < 2; j1++) {
310  copy++;
311 
312  // tilt Side Spacers (parallel to Side Frame)
313  thetax = 90. * CLHEP::deg + thetaz;
314  double thetadeg = thetax / CLHEP::deg;
315  if (thetadeg != 0) {
316  string arotstr = DDSplit(sidSpacersName).first + to_string(thetadeg * 10.);
317  rot = DDrot(DDName(arotstr, DDSplit(sidSpacersName).second), thetax, phix, thetay, phiy, thetaz, phiz);
318  }
319 
320  cpv.position(name, parentName, copy, DDTranslation(xpos, ypos, zpos), rot);
321  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << copy << " positioned in "
322  << parentName << " at " << DDTranslation(xpos, ypos, zpos) << " with " << rot;
323  xpos = -xpos;
324  thetaz = -thetaz;
325  }
326  }
327 
328  // Loop over detectors to be placed
329  for (int k = 0; k < detectorN; k++) {
330  // Wafer
331  name = DDName(DDSplit(waferName[k]).first, DDSplit(waferName[k]).second);
332  xpos = 0;
333  ypos = waferZ[k];
334  double zWafer;
335  if (dlHybrid > dlTop) {
336  zWafer = botfr + 0.5 * fullHeight;
337  } else {
338  zWafer = boxFrameHeight + botfr + pitchHeight + 0.5 * fullHeight;
339  }
340  zpos = zWafer - zCenter;
341  DDTranslation tran(xpos, ypos, zpos);
342  string rotstr = DDSplit(waferRot[k]).first;
343  string rotns;
344  if (rotstr != "NULL") {
345  rotns = DDSplit(waferRot[k]).second;
346  rot = DDRotation(DDName(rotstr, rotns));
347  }
348  cpv.position(name, parentName, k + 1, tran, rot);
349  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
350  << " at " << tran << " with " << rot;
351 
352  //Pitch Adapter
353  name = DDName(DDSplit(pitchName[k]).first, DDSplit(pitchName[k]).second);
354  if (k == 0) {
355  xpos = 0;
356  } else {
357  xpos = 0.5 * fullHeight * sin(detTilt);
358  }
359  ypos = pitchZ[k];
360  double zPitch;
361  if (dlHybrid > dlTop) {
362  zPitch = botfr + fullHeight + 0.5 * pitchHeight;
363  } else {
364  zPitch = boxFrameHeight + botfr + 0.5 * pitchHeight;
365  }
366  zpos = zPitch - zCenter;
367  rotstr = DDSplit(pitchRot[k]).first;
368  if (rotstr != "NULL") {
369  rotns = DDSplit(pitchRot[k]).second;
370  rot = DDRotation(DDName(rotstr, rotns));
371  } else {
372  rot = DDRotation();
373  }
374  tran = DDTranslation(xpos, ypos, zpos);
375  cpv.position(name, parentName, k + 1, tran, rot);
376  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
377  << " at " << tran << " with " << rot;
378 
379  // Hybrid
380  name = DDName(DDSplit(hybridName).first, DDSplit(hybridName).second);
381  ypos = hybridZ[k];
382  double zHybrid;
383  if (dlHybrid > dlTop) {
384  zHybrid = botfr + fullHeight + pitchHeight + 0.5 * hybridHeight;
385  } else {
386  zHybrid = 0.5 * hybridHeight;
387  }
388  zpos = zHybrid - zCenter;
389  tran = DDTranslation(0, ypos, zpos);
390  rot = DDRotation();
391  cpv.position(name, parentName, k + 1, tran, rot);
392  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
393  << " at " << tran << " with " << rot;
394 
395  // Box frame
396  name = DDName(DDSplit(boxFrameName).first, DDSplit(boxFrameName).second);
397  ypos = boxFrameZ[k];
398  double zBoxFrame;
399  if (dlHybrid > dlTop) {
400  zBoxFrame = sideFrameHeight + 0.5 * boxFrameHeight;
401  } else {
402  zBoxFrame = 0.5 * boxFrameHeight;
403  }
404  zpos = zBoxFrame - zCenter;
405  tran = DDTranslation(0, ypos, zpos);
406  rot = DDRotation();
407  cpv.position(name, parentName, k + 1, tran, rot);
408  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
409  << " at " << tran << " with " << rot;
410 
411  // Side frame
412  name = DDName(DDSplit(sideFrameName[k]).first, DDSplit(sideFrameName[k]).second);
413  ypos = sideFrameZ[k];
414  double zSideFrame;
415  if (dlHybrid > dlTop) {
416  zSideFrame = 0.5 * sideFrameHeight;
417  } else {
418  zSideFrame = boxFrameHeight + 0.5 * sideFrameHeight;
419  }
420  zpos = zSideFrame - zCenter;
421  rotstr = DDSplit(sideFrameRot[k]).first;
422  if (rotstr != "NULL") {
423  rotns = DDSplit(sideFrameRot[k]).second;
424  rot = DDRotation(DDName(rotstr, rotns));
425  } else {
426  rot = DDRotation();
427  }
428  tran = DDTranslation(0, ypos, zpos);
429  cpv.position(name, parentName, k + 1, tran, rot);
430  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
431  << " at " << tran << " with " << rot;
432 
433  // Kapton circuit
434  name = DDName(DDSplit(kaptonName[k]).first, DDSplit(kaptonName[k]).second);
435  ypos = kaptonZ[k];
436  double zKapton;
437  double kaptonExtraHeight = 0;
438  if (dlHybrid > dlTop) {
439  if (k == 1)
440  kaptonExtraHeight = dlTop * sin(detTilt) - fullHeight * (1 - cos(detTilt));
441  kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
442  zKapton = 0.5 * (kaptonHeight + kaptonExtraHeight);
443  } else {
444  if (k == 1)
445  kaptonExtraHeight = dlBottom * sin(detTilt) - fullHeight * (1 - cos(detTilt));
446  kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
447  zKapton = boxFrameHeight + sideFrameHeight - 0.5 * (kaptonHeight + kaptonExtraHeight);
448  }
449  zpos = zKapton - zCenter;
450  rotstr = DDSplit(kaptonRot[k]).first;
451  if (rotstr != "NULL") {
452  rotns = DDSplit(kaptonRot[k]).second;
453  rot = DDRotation(DDName(rotstr, rotns));
454  } else {
455  rot = DDRotation();
456  }
457  tran = DDTranslation(0, ypos, zpos);
458  cpv.position(name, parentName, k + 1, tran, rot);
459  LogDebug("TIDGeom") << "DDTIDModulePosAlgo test: " << name << " number " << k + 1 << " positioned in " << parentName
460  << " at " << tran << " with " << rot;
461  }
462 
463  LogDebug("TIDGeom") << "<<== End of DDTIDModulePosAlgo positioning ...";
464 }
465 
466 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDTIDModulePosAlgo, "track:DDTIDModulePosAlgo");
static AlgebraicMatrix initialize()
void execute(DDCompactView &cpv) override
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=nullptr)
vector< string > pitchName
vector< string > waferRot
vector< double > waferZ
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
vector< double > kaptonZ
vector< string > pitchRot
vector< string > sideFrameName
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:17
std::string to_string(const V &value)
Definition: OMSAccess.h:71
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
vector< double > pitchZ
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
U second(std::pair< T, U > const &p)
vector< string > sideFrameRot
vector< double > boxFrameZ
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
vector< double > sideFrameZ
DDRotation DDrot(const DDName &name, std::unique_ptr< DDRotationMatrix > rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:67
vector< double > coolRadShift
vector< string > kaptonName
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
vector< string > kaptonRot
~DDTIDModulePosAlgo() override
vector< string > waferName
#define DEFINE_EDM_PLUGIN(factory, type, name)
vector< double > hybridZ
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
#define LogDebug(id)