CMS 3D CMS Logo

DDEcalEndcapAlgo.cc
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
5 // Header files for endcap supercrystal geometry
7 #include <CLHEP/Geometry/Transform3D.h>
8 
9 #include <string>
10 #include <vector>
11 
12 using namespace std;
13 using namespace cms;
14 using namespace dd4hep;
15 using namespace cms_units::operators;
16 
17 using DDTranslation = ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<double> >;
18 using DDRotation = ROOT::Math::Rotation3D;
19 
20 namespace {
21  struct Endcap {
22  string mat;
23  double zOff;
24 
25  string quaName;
26  string quaMat;
27 
28  string crysMat;
29  string wallMat;
30 
31  double crysLength;
32  double crysRear;
33  double crysFront;
34  double sCELength;
35  double sCERear;
36  double sCEFront;
37  double sCALength;
38  double sCARear;
39  double sCAFront;
40  double sCAWall;
41  double sCHLength;
42  double sCHSide;
43 
44  double nSCTypes;
45  vector<double> vecEESCProf;
46  double nColumns;
47  vector<double> vecEEShape;
48  double nSCCutaway;
49  vector<double> vecEESCCutaway;
50  double nSCquad;
51  vector<double> vecEESCCtrs;
52  double nCRSC;
53  vector<double> vecEECRCtrs;
54 
55  array<double, 3> cutParms;
56  string cutBoxName;
57 
58  string envName;
59  string alvName;
60  string intName;
61  string cryName;
62 
63  DDTranslation cryFCtr[5][5];
64  DDTranslation cryRCtr[5][5];
65  DDTranslation scrFCtr[10][10];
66  DDTranslation scrRCtr[10][10];
67 
68  double pFHalf;
69  double pFFifth;
70  double pF45;
71 
72  vector<double> vecEESCLims;
73 
74  double iLength;
75  double iXYOff;
76  double cryZOff;
77  double zFront;
78  };
79 
80  const Rotation3D& myrot(cms::DDNamespace& ns, const string& nam, const Rotation3D& r) {
81  ns.addRotation(nam, r);
82  return ns.rotation(ns.prepend(nam));
83  }
84 
85  string_view mynamespace(string_view input) {
86  string_view v = input;
87  auto trim_pos = v.find(':');
88  if (trim_pos != v.npos)
89  v.remove_suffix(v.size() - (trim_pos + 1));
90  return v;
91  }
92 } // namespace
93 
94 static long algorithm(dd4hep::Detector& /* description */,
96  xml_h e,
97  dd4hep::SensitiveDetector& /* sens */) {
98  BenchmarkGrd counter("DDEcalEndcapAlgo");
99  cms::DDNamespace ns(ctxt, e, true);
100  cms::DDAlgoArguments args(ctxt, e);
101 
102  // TRICK!
103  string myns{mynamespace(args.parentName()).data(), mynamespace(args.parentName()).size()};
104 
105  Endcap ee;
106  ee.mat = args.str("EEMat");
107  ee.zOff = args.dble("EEzOff");
108 
109  ee.quaName = args.str("EEQuaName");
110  ee.quaMat = args.str("EEQuaMat");
111  ee.crysMat = args.str("EECrysMat");
112  ee.wallMat = args.str("EEWallMat");
113  ee.crysLength = args.dble("EECrysLength");
114  ee.crysRear = args.dble("EECrysRear");
115  ee.crysFront = args.dble("EECrysFront");
116  ee.sCELength = args.dble("EESCELength");
117  ee.sCERear = args.dble("EESCERear");
118  ee.sCEFront = args.dble("EESCEFront");
119  ee.sCALength = args.dble("EESCALength");
120  ee.sCARear = args.dble("EESCARear");
121  ee.sCAFront = args.dble("EESCAFront");
122  ee.sCAWall = args.dble("EESCAWall");
123  ee.sCHLength = args.dble("EESCHLength");
124  ee.sCHSide = args.dble("EESCHSide");
125  ee.nSCTypes = args.dble("EEnSCTypes");
126  ee.nColumns = args.dble("EEnColumns");
127  ee.nSCCutaway = args.dble("EEnSCCutaway");
128  ee.nSCquad = args.dble("EEnSCquad");
129  ee.nCRSC = args.dble("EEnCRSC");
130  ee.vecEESCProf = args.vecDble("EESCProf");
131  ee.vecEEShape = args.vecDble("EEShape");
132  ee.vecEESCCutaway = args.vecDble("EESCCutaway");
133  ee.vecEESCCtrs = args.vecDble("EESCCtrs");
134  ee.vecEECRCtrs = args.vecDble("EECRCtrs");
135 
136  ee.cutBoxName = args.str("EECutBoxName");
137 
138  ee.envName = args.str("EEEnvName");
139  ee.alvName = args.str("EEAlvName");
140  ee.intName = args.str("EEIntName");
141  ee.cryName = args.str("EECryName");
142 
143  ee.pFHalf = args.dble("EEPFHalf");
144  ee.pFFifth = args.dble("EEPFFifth");
145  ee.pF45 = args.dble("EEPF45");
146 
147  ee.vecEESCLims = args.vecDble("EESCLims");
148  ee.iLength = args.dble("EEiLength");
149  ee.iXYOff = args.dble("EEiXYOff");
150  ee.cryZOff = args.dble("EECryZOff");
151  ee.zFront = args.dble("EEzFront");
152 
153  // Position supercrystals in EE Quadrant
154 
155  //********************************* cutbox for trimming edge SCs
156  const double cutWid(ee.sCERear / sqrt(2.));
157  ee.cutParms[0] = cutWid;
158  ee.cutParms[1] = cutWid;
159  ee.cutParms[2] = ee.sCELength / sqrt(2.);
160  Solid eeCutBox = Box(ee.cutBoxName, ee.cutParms[0], ee.cutParms[1], ee.cutParms[2]);
161  //**************************************************************
162 
163  const double zFix(ee.zFront - 3172_mm); // fix for changing z offset
164 
165  //** fill supercrystal front and rear center positions from xml input
166  for (unsigned int iC(0); iC != (unsigned int)ee.nSCquad; ++iC) {
167  const unsigned int iOff(8 * iC);
168  const unsigned int ix((unsigned int)ee.vecEESCCtrs[iOff + 0]);
169  const unsigned int iy((unsigned int)ee.vecEESCCtrs[iOff + 1]);
170 
171  assert(ix > 0 && ix < 11 && iy > 0 && iy < 11);
172 
173  ee.scrFCtr[ix - 1][iy - 1] =
174  DDTranslation(ee.vecEESCCtrs[iOff + 2], ee.vecEESCCtrs[iOff + 4], ee.vecEESCCtrs[iOff + 6] + zFix);
175 
176  ee.scrRCtr[ix - 1][iy - 1] =
177  DDTranslation(ee.vecEESCCtrs[iOff + 3], ee.vecEESCCtrs[iOff + 5], ee.vecEESCCtrs[iOff + 7] + zFix);
178  }
179 
180  //** fill crystal front and rear center positions from xml input
181  for (unsigned int iC(0); iC != 25; ++iC) {
182  const unsigned int iOff(8 * iC);
183  const unsigned int ix((unsigned int)ee.vecEECRCtrs[iOff + 0]);
184  const unsigned int iy((unsigned int)ee.vecEECRCtrs[iOff + 1]);
185 
186  assert(ix > 0 && ix < 6 && iy > 0 && iy < 6);
187 
188  ee.cryFCtr[ix - 1][iy - 1] =
189  DDTranslation(ee.vecEECRCtrs[iOff + 2], ee.vecEECRCtrs[iOff + 4], ee.vecEECRCtrs[iOff + 6]);
190 
191  ee.cryRCtr[ix - 1][iy - 1] =
192  DDTranslation(ee.vecEECRCtrs[iOff + 3], ee.vecEECRCtrs[iOff + 5], ee.vecEECRCtrs[iOff + 7]);
193  }
194 
195  Solid eeCRSolid = Trap(ee.cryName,
196  0.5 * ee.crysLength,
197  atan((ee.crysRear - ee.crysFront) / (sqrt(2.) * ee.crysLength)),
198  45._deg,
199  0.5 * ee.crysFront,
200  0.5 * ee.crysFront,
201  0.5 * ee.crysFront,
202  0._deg,
203  0.5 * ee.crysRear,
204  0.5 * ee.crysRear,
205  0.5 * ee.crysRear,
206  0._deg);
207  Volume eeCRLog = Volume(ee.cryName, eeCRSolid, ns.material(ee.crysMat));
208 
209  for (unsigned int isc(0); isc < ee.nSCTypes; ++isc) {
210  unsigned int iSCType = isc + 1;
211  const string anum(std::to_string(iSCType));
212  const double eFront(0.5 * ee.sCEFront);
213  const double eRear(0.5 * ee.sCERear);
214  const double eAng(atan((ee.sCERear - ee.sCEFront) / (sqrt(2.) * ee.sCELength)));
215  const double ffived(45_deg);
216  const double zerod(0_deg);
217  string eeSCEnvName(1 == iSCType ? ee.envName + std::to_string(iSCType)
218  : (ee.envName + std::to_string(iSCType) + "Tmp"));
219  Solid eeSCEnv = ns.addSolidNS(
220  eeSCEnvName,
221  Trap(eeSCEnvName, 0.5 * ee.sCELength, eAng, ffived, eFront, eFront, eFront, zerod, eRear, eRear, eRear, zerod));
222 
223  const double aFront(0.5 * ee.sCAFront);
224  const double aRear(0.5 * ee.sCARear);
225  const double aAng(atan((ee.sCARear - ee.sCAFront) / (sqrt(2.) * ee.sCALength)));
226  string eeSCAlvName(
227  (1 == iSCType ? ee.alvName + std::to_string(iSCType) : (ee.alvName + std::to_string(iSCType) + "Tmp")));
228  Solid eeSCAlv = ns.addSolidNS(
229  eeSCAlvName,
230  Trap(eeSCAlvName, 0.5 * ee.sCALength, aAng, ffived, aFront, aFront, aFront, zerod, aRear, aRear, aRear, zerod));
231 
232  const double dwall(ee.sCAWall);
233  const double iFront(aFront - dwall);
234  const double iRear(iFront);
235  const double iLen(ee.iLength);
236  string eeSCIntName(1 == iSCType ? ee.intName + std::to_string(iSCType)
237  : (ee.intName + std::to_string(iSCType) + "Tmp"));
238  Solid eeSCInt = ns.addSolidNS(eeSCIntName,
239  Trap(eeSCIntName,
240  iLen / 2.,
241  atan((ee.sCARear - ee.sCAFront) / (sqrt(2.) * ee.sCALength)),
242  ffived,
243  iFront,
244  iFront,
245  iFront,
246  zerod,
247  iRear,
248  iRear,
249  iRear,
250  zerod));
251 
252  const double dz(-0.5 * (ee.sCELength - ee.sCALength));
253  const double dxy(0.5 * dz * (ee.sCERear - ee.sCEFront) / ee.sCELength);
254  const double zIOff(-(ee.sCALength - iLen) / 2.);
255  const double xyIOff(ee.iXYOff);
256 
257  Volume eeSCELog;
258  Volume eeSCALog;
259  Volume eeSCILog;
260 
261  if (1 == iSCType) { // standard SC in this block
262  eeSCELog = ns.addVolumeNS(Volume(myns + ee.envName + std::to_string(iSCType), eeSCEnv, ns.material(ee.mat)));
263  eeSCALog = Volume(ee.alvName + std::to_string(iSCType), eeSCAlv, ns.material(ee.wallMat));
264  eeSCILog = Volume(ee.intName + std::to_string(iSCType), eeSCInt, ns.material(ee.mat));
265  } else { // partial SCs this block: create subtraction volumes as appropriate
266  const double half(ee.cutParms[0] - ee.pFHalf * ee.crysRear);
267  const double fifth(ee.cutParms[0] + ee.pFFifth * ee.crysRear);
268  const double fac(ee.pF45);
269 
270  const double zmm(0_mm);
271 
272  DDTranslation cutTra(
273  2 == iSCType ? DDTranslation(zmm, half, zmm)
274  : (3 == iSCType ? DDTranslation(half, zmm, zmm)
275  : (4 == iSCType ? DDTranslation(zmm, -fifth, zmm)
276  : (5 == iSCType ? DDTranslation(-half * fac, -half * fac, zmm)
277  : DDTranslation(-fifth, zmm, zmm)))));
278 
279  const CLHEP::HepRotationZ cutm(ffived);
280 
281  Rotation3D cutRot(5 != iSCType ? Rotation3D()
282  : myrot(ns,
283  "EECry5Rot",
284  Rotation3D(cutm.xx(),
285  cutm.xy(),
286  cutm.xz(),
287  cutm.yx(),
288  cutm.yy(),
289  cutm.yz(),
290  cutm.zx(),
291  cutm.zy(),
292  cutm.zz())));
293 
294  Solid eeCutEnv = SubtractionSolid(ee.envName + std::to_string(iSCType),
295  ns.solid(ee.envName + std::to_string(iSCType) + "Tmp"),
296  eeCutBox,
297  Transform3D(cutRot, cutTra));
298 
299  const DDTranslation extra(dxy, dxy, dz);
300 
301  Solid eeCutAlv = SubtractionSolid(ee.alvName + std::to_string(iSCType),
302  ns.solid(ee.alvName + std::to_string(iSCType) + "Tmp"),
303  eeCutBox,
304  Transform3D(cutRot, cutTra - extra));
305 
306  const double mySign(iSCType < 4 ? +1. : -1.);
307 
308  const DDTranslation extraI(xyIOff + mySign * 2_mm, xyIOff + mySign * 2_mm, zIOff);
309 
310  Solid eeCutInt = SubtractionSolid(ee.intName + std::to_string(iSCType),
311  ns.solid(ee.intName + std::to_string(iSCType) + "Tmp"),
312  eeCutBox,
313  Transform3D(cutRot, cutTra - extraI));
314 
315  eeSCELog = ns.addVolumeNS(Volume(myns + ee.envName + std::to_string(iSCType), eeCutEnv, ns.material(ee.mat)));
316  eeSCALog = Volume(ee.alvName + std::to_string(iSCType), eeCutAlv, ns.material(ee.wallMat));
317  eeSCILog = Volume(ee.intName + std::to_string(iSCType), eeCutInt, ns.material(ee.mat));
318  }
319  eeSCELog.placeVolume(eeSCALog, iSCType * 100 + 1, Position(dxy, dxy, dz));
320  eeSCALog.placeVolume(eeSCILog, iSCType * 100 + 1, Position(xyIOff, xyIOff, zIOff));
321 
322  DDTranslation croffset(0., 0., 0.);
323 
324  // Position crystals within parent supercrystal interior volume
325  static const unsigned int ncol(5);
326 
327  if (iSCType > 0 && iSCType <= ee.nSCTypes) {
328  const unsigned int icoffset((iSCType - 1) * ncol - 1);
329 
330  // Loop over columns of SC
331  for (unsigned int icol(1); icol <= ncol; ++icol) {
332  // Get column limits for this SC type from xml input
333  const int ncrcol((int)ee.vecEESCProf[icoffset + icol]);
334 
335  const int imin(0 < ncrcol ? 1 : (0 > ncrcol ? ncol + ncrcol + 1 : 0));
336  const int imax(0 < ncrcol ? ncrcol : (0 > ncrcol ? ncol : 0));
337 
338  if (imax > 0) {
339  // Loop over crystals in this row
340  for (int irow(imin); irow <= imax; ++irow) {
341  // Create crystal as a DDEcalEndcapTrap object and calculate rotation and
342  // translation required to position it in the SC.
343  DDEcalEndcapTrap crystal(1, ee.crysFront, ee.crysRear, ee.crysLength);
344 
345  crystal.moveto(ee.cryFCtr[icol - 1][irow - 1], ee.cryRCtr[icol - 1][irow - 1]);
346 
347  string rname("EECrRoC" + std::to_string(icol) + "R" + std::to_string(irow));
348 
349  eeSCALog.placeVolume(
350  eeCRLog,
351  100 * iSCType + 10 * (icol - 1) + (irow - 1),
352  Transform3D(
353  myrot(ns, rname, crystal.rotation()),
354  Position(crystal.centrePos().x(), crystal.centrePos().y(), crystal.centrePos().z() - ee.cryZOff)));
355  }
356  }
357  }
358  }
359  }
360 
361  //** Loop over endcap columns
362  for (int icol = 1; icol <= int(ee.nColumns); icol++) {
363  //** Loop over SCs in column, using limits from xml input
364  for (int irow = int(ee.vecEEShape[2 * icol - 2]); irow <= int(ee.vecEEShape[2 * icol - 1]); ++irow) {
365  if (ee.vecEESCLims[0] <= icol && ee.vecEESCLims[1] >= icol && ee.vecEESCLims[2] <= irow &&
366  ee.vecEESCLims[3] >= irow) {
367  // Find SC type (complete or partial) for this location
368  unsigned int isctype = 1;
369 
370  for (unsigned int ii = 0; ii < (unsigned int)(ee.nSCCutaway); ++ii) {
371  if ((ee.vecEESCCutaway[3 * ii] == icol) && (ee.vecEESCCutaway[3 * ii + 1] == irow)) {
372  isctype = int(ee.vecEESCCutaway[3 * ii + 2]);
373  }
374  }
375 
376  // Create SC as a DDEcalEndcapTrap object and calculate rotation and
377  // translation required to position it in the endcap.
378  DDEcalEndcapTrap scrys(1, ee.sCEFront, ee.sCERear, ee.sCELength);
379  scrys.moveto(ee.scrFCtr[icol - 1][irow - 1], ee.scrRCtr[icol - 1][irow - 1]);
380  scrys.translate(DDTranslation(0., 0., -ee.zOff));
381 
382  string rname(ee.envName + std::to_string(isctype) + std::to_string(icol) + "R" + std::to_string(irow));
383  // Position SC in endcap
384  Volume quaLog = ns.volume(ee.quaName);
385  Volume childEnvLog = ns.volume(myns + ee.envName + std::to_string(isctype));
386  quaLog.placeVolume(childEnvLog,
387  100 * isctype + 10 * (icol - 1) + (irow - 1),
388  Transform3D(scrys.rotation(), scrys.centrePos()));
389  }
390  }
391  }
392 
393  return 1;
394 }
395 
396 DECLARE_DDCMS_DETELEMENT(DDCMS_ecal_DDEcalEndcapAlgo, algorithm)
DDEcalEndcapTrap::rotation
DDRotationMatrix rotation()
Definition: DDEcalEndcapTrap.h:35
writedatasetfile.args
args
Definition: writedatasetfile.py:18
cms_units::operators
Definition: CMSUnits.h:13
input
static const std::string input
Definition: EdmProvDump.cc:48
cms::DDNamespace::addRotation
void addRotation(const std::string &name, const dd4hep::Rotation3D &rot) const
Definition: DDNamespace.cc:125
reco::HaloData::Endcap
Endcap
Definition: HaloData.h:14
cms::DDNamespace::solid
dd4hep::Solid solid(const std::string &name) const
Definition: DDNamespace.cc:225
DECLARE_DDCMS_DETELEMENT
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:30
cms::DDNamespace::material
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:121
cms::DDParsingContext
Definition: DDParsingContext.h:14
cms::DDNamespace
Definition: DDNamespace.h:16
std::data
constexpr auto data(C &c) -> decltype(c.data())
Definition: cuda_cxx17.h:40
cms::cuda::assert
assert(be >=bs)
findQualityFiles.v
v
Definition: findQualityFiles.py:179
DDEcalEndcapTrap
Definition: DDEcalEndcapTrap.h:11
std::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: cuda_cxx17.h:13
DDEcalEndcapTrap.h
DDTranslation
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
cms::DDNamespace::prepend
std::string prepend(const std::string &) const
Definition: DDNamespace.cc:66
PixelTestBeamValidation_cfi.Position
Position
Definition: PixelTestBeamValidation_cfi.py:62
cms::DDNamespace::rotation
const dd4hep::Rotation3D & rotation(const std::string &name) const
Definition: DDNamespace.cc:130
algorithm
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e, dd4hep::SensitiveDetector &)
Definition: DDEcalEndcapAlgo.cc:94
cms::Volume
dd4hep::Volume Volume
Definition: DDFilteredView.h:45
rname
const G4String rname[NREG]
Definition: ParametrisedEMPhysics.cc:46
DDPlugins.h
createfilelist.int
int
Definition: createfilelist.py:10
cms::DDNamespace::addSolidNS
dd4hep::Solid addSolidNS(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:206
cms::DDAlgoArguments
Definition: DDAlgoArguments.h:28
counter
static std::atomic< unsigned int > counter
Definition: SharedResourceNames.cc:15
BenchmarkGrd.h
cms::DDNamespace::addVolumeNS
dd4hep::Volume addVolumeNS(dd4hep::Volume vol) const
Definition: DDNamespace.cc:150
alignCSCRings.r
r
Definition: alignCSCRings.py:93
align::Detector
Definition: StructureType.h:86
std
Definition: JetResolutionObject.h:76
PVValHelper::dxy
Definition: PVValidationHelpers.h:47
PVValHelper::dz
Definition: PVValidationHelpers.h:50
dd4hep
Definition: DDPlugins.h:8
BenchmarkGrd
Definition: BenchmarkGrd.h:9
DDEcalEndcapTrap::translate
void translate(const DDTranslation &trans)
Definition: DDEcalEndcapTrap.cc:118
DDRotation
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
CMSUnits.h
DDEcalEndcapTrap::centrePos
DDTranslation centrePos()
Definition: DDEcalEndcapTrap.cc:220
DDEcalEndcapTrap::moveto
void moveto(const DDTranslation &frontCentre, const DDTranslation &rearCentre)
Definition: DDEcalEndcapTrap.cc:132
cuy.ii
ii
Definition: cuy.py:590
cms::DDNamespace::volume
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:190
cms
Namespace of DDCMS conversion namespace.
Definition: ProducerAnalyzer.cc:21
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
DDTranslation
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDEcalEndcapAlgo.cc:17