Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-05-16 02:05:06

0001 #include "Geometry/HGCalCommonData/interface/HGCalWaferMask.h"
0002 #include "Geometry/HGCalCommonData/interface/HGCalTypes.h"
0003 #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "Geometry/HGCalCommonData/interface/HGCalCell.h"
0006 
0007 #include <algorithm>
0008 #include <array>
0009 #include <sstream>
0010 #include <iostream>
0011 //#define EDM_ML_DEBUG
0012 
0013 bool HGCalWaferMask::maskCell(int u, int v, int n, int ncor, int fcor, int corners) {
0014   /*
0015 Masks each cell (or not) according to its wafer and cell position (detId) and to the user needs (corners).
0016 Each wafer has k_CornerSize corners which are defined in anti-clockwise order starting from the corner at the top, which is always #0. 'ncor' denotes the number of corners inside the physical region. 'fcor' is the defined to be the first corner that appears inside the detector's physical volume in anti-clockwise order. 
0017 The argument 'corners' controls the types of wafers the user wants: for instance, corners=3 masks all wafers that have at least 3 corners inside the physical region. 
0018  */
0019   bool mask(false);
0020   if (ncor < corners) {
0021     mask = true;
0022   } else {
0023     if (ncor == HGCalGeomTools::k_fourCorners) {
0024       switch (fcor) {
0025         case (0): {
0026           mask = (v >= n);
0027           break;
0028         }
0029         case (1): {
0030           mask = (u >= n);
0031           break;
0032         }
0033         case (2): {
0034           mask = (u > v);
0035           break;
0036         }
0037         case (3): {
0038           mask = (v < n);
0039           break;
0040         }
0041         case (4): {
0042           mask = (u < n);
0043           break;
0044         }
0045         default: {
0046           mask = (u <= v);
0047           break;
0048         }
0049       }
0050     } else {
0051       switch (fcor) {
0052         case (0): {
0053           if (ncor == HGCalGeomTools::k_threeCorners) {
0054             mask = !((u > 2 * v) && (v < n));
0055           } else {
0056             mask = ((u >= n) && (v >= n) && ((u + v) > (3 * n - 2)));
0057           }
0058           break;
0059         }
0060         case (1): {
0061           if (ncor == HGCalGeomTools::k_threeCorners) {
0062             mask = !((u + v) < n);
0063           } else {
0064             mask = ((u >= n) && (u > v) && ((2 * u - v) > 2 * n));
0065           }
0066           break;
0067         }
0068         case (2): {
0069           if (ncor == HGCalGeomTools::k_threeCorners) {
0070             mask = !((u < n) && (v > u) && (v > (2 * u - 1)));
0071           } else {
0072             mask = ((u > 2 * v) && (v < n));
0073           }
0074           break;
0075         }
0076         case (3): {
0077           if (ncor == HGCalGeomTools::k_threeCorners) {
0078             mask = !((v >= u) && ((2 * v - u) > (2 * n - 2)));
0079           } else {
0080             mask = ((u + v) < n);
0081           }
0082           break;
0083         }
0084         case (4): {
0085           if (ncor == HGCalGeomTools::k_threeCorners) {
0086             mask = !((u >= n) && (v >= n) && ((u + v) > (3 * n - 2)));
0087           } else {
0088             mask = ((u < n) && (v > u) && (v > (2 * u - 1)));
0089           }
0090           break;
0091         }
0092         default: {
0093           if (ncor == HGCalGeomTools::k_threeCorners) {
0094             mask = !((u >= n) && (u > v) && ((2 * u - v) > 2 * n));
0095           } else {
0096             mask = ((v >= u) && ((2 * v - u) > (2 * n - 2)));
0097           }
0098           break;
0099         }
0100       }
0101     }
0102   }
0103 #ifdef EDM_ML_DEBUG
0104   edm::LogVerbatim("HGCalGeom") << "Corners: " << ncor << ":" << fcor << " N " << n << " u " << u << " v " << v
0105                                 << " Mask " << mask;
0106 #endif
0107   return mask;
0108 }
0109 
0110 bool HGCalWaferMask::goodCell(int u, int v, int n, int type, int rotn) {
0111   // for V15 and V16
0112   bool good(false);
0113   int n2 = n / 2;
0114   int n4 = n / 4;
0115   int n3 = (n + 1) / 3;
0116   switch (type) {
0117     case (HGCalTypes::WaferFull): {  //WaferFull
0118       good = true;
0119       break;
0120     }
0121     case (HGCalTypes::WaferFive): {  //WaferFive
0122       switch (rotn) {
0123         case (HGCalTypes::WaferCorner0): {
0124           int u2 = u / 2;
0125           good = ((v - u2) <= n);
0126           break;
0127         }
0128         case (HGCalTypes::WaferCorner1): {
0129           good = ((v + u) < (3 * n));
0130           break;
0131         }
0132         case (HGCalTypes::WaferCorner2): {
0133           int v2 = (v + 1) / 2;
0134           good = ((u - v2) <= n);
0135           break;
0136         }
0137         case (HGCalTypes::WaferCorner3): {
0138           int u2 = (u - 1) / 2;
0139           good = (u2 <= v);
0140           break;
0141         }
0142         case (HGCalTypes::WaferCorner4): {
0143           good = ((v + u) >= n - 1);
0144           break;
0145         }
0146         default: {
0147           int v2 = v / 2;
0148           good = (u >= v2);
0149           break;
0150         }
0151       }
0152       break;
0153     }
0154     case (HGCalTypes::WaferChopTwo): {  //WaferChopTwo
0155       switch (rotn) {
0156         case (HGCalTypes::WaferCorner0): {
0157           good = (v < (3 * n2));
0158           break;
0159         }
0160         case (HGCalTypes::WaferCorner1): {
0161           good = (u < (3 * n2));
0162           break;
0163         }
0164         case (HGCalTypes::WaferCorner2): {
0165           good = ((u - v) <= n2);
0166           break;
0167         }
0168         case (HGCalTypes::WaferCorner3): {
0169           good = (v >= n2);
0170           break;
0171         }
0172         case (HGCalTypes::WaferCorner4): {
0173           good = (u >= n2 - 1);
0174           break;
0175         }
0176         default: {
0177           good = ((v - u) < n2);
0178           break;
0179         }
0180       }
0181       break;
0182     }
0183     case (HGCalTypes::WaferChopTwoM): {  //WaferChopTwoM
0184       switch (rotn) {
0185         case (HGCalTypes::WaferCorner0): {
0186           good = (v < (5 * n4));
0187           break;
0188         }
0189         case (HGCalTypes::WaferCorner1): {
0190           good = (u <= (5 * n4));
0191           break;
0192         }
0193         case (HGCalTypes::WaferCorner2): {
0194           good = ((u - v) <= n4);
0195           break;
0196         }
0197         case (HGCalTypes::WaferCorner3): {
0198           good = (v >= (3 * n4 - 1));
0199           break;
0200         }
0201         case (HGCalTypes::WaferCorner4): {
0202           good = (u >= (3 * n4));
0203           break;
0204         }
0205         default: {
0206           good = ((v - u) <= n4);
0207           break;
0208         }
0209       }
0210       break;
0211     }
0212     case (HGCalTypes::WaferHalf): {  //WaferHalf
0213       switch (rotn) {
0214         case (HGCalTypes::WaferCorner0): {
0215           good = (v < n);
0216           break;
0217         }
0218         case (HGCalTypes::WaferCorner1): {
0219           good = (u <= n);
0220           break;
0221         }
0222         case (HGCalTypes::WaferCorner2): {
0223           good = (v >= u);
0224           break;
0225         }
0226         case (HGCalTypes::WaferCorner3): {
0227           good = (v >= n - 1);
0228           break;
0229         }
0230         case (HGCalTypes::WaferCorner4): {
0231           good = (u >= n);
0232           break;
0233         }
0234         default: {
0235           good = (u >= v);
0236           break;
0237         }
0238       }
0239       break;
0240     }
0241     case (HGCalTypes::WaferSemi): {  //WaferSemi
0242       switch (rotn) {
0243         case (HGCalTypes::WaferCorner0): {
0244           good = ((u + v) <= (2 * n));
0245           break;
0246         }
0247         case (HGCalTypes::WaferCorner1): {
0248           good = ((2 * u - v) <= (n + 1));
0249           break;
0250         }
0251         case (HGCalTypes::WaferCorner2): {
0252           good = ((2 * v - u) >= (n - 2));
0253           break;
0254         }
0255         case (HGCalTypes::WaferCorner3): {
0256           good = ((u + v) >= (2 * n - 2));
0257           break;
0258         }
0259         case (HGCalTypes::WaferCorner4): {
0260           good = ((2 * u - v) >= (n - 1));
0261           break;
0262         }
0263         default: {
0264           good = ((2 * v - u) <= n);
0265           break;
0266         }
0267       }
0268       break;
0269     }
0270     case (HGCalTypes::WaferThree): {  //WaferThree
0271       switch (rotn) {
0272         case (HGCalTypes::WaferCorner0): {
0273           good = ((v + u) <= n);
0274           break;
0275         }
0276         case (HGCalTypes::WaferCorner1): {
0277           good = ((2 * u - v) <= 1);
0278           break;
0279         }
0280         case (HGCalTypes::WaferCorner2): {
0281           int u2 = ((u > 0) ? (u / 2) : 0);
0282           int uv = v - u2;
0283           good = (uv >= (n - 1));
0284           break;
0285         }
0286         case (HGCalTypes::WaferCorner3): {
0287           good = ((v + u) >= (3 * n - 2));
0288           break;
0289         }
0290         case (HGCalTypes::WaferCorner4): {
0291           int uv = 2 * u - v;
0292           good = (uv >= (2 * n - 1));
0293           break;
0294         }
0295         default: {
0296           int uv = u - 2 * v;
0297           good = (uv >= 0);
0298           break;
0299         }
0300       }
0301       break;
0302     }
0303     case (HGCalTypes::WaferSemi2): {  //WaferSemi2
0304       switch (rotn) {
0305         case (HGCalTypes::WaferCorner0): {
0306           good = ((u + v) <= (4 * n3 + 1));
0307           break;
0308         }
0309         case (HGCalTypes::WaferCorner1): {
0310           good = ((2 * u - v) <= n2);
0311           break;
0312         }
0313         case (HGCalTypes::WaferCorner2): {
0314           int u2 = ((u + 1) / 2);
0315           good = ((v - u2) >= (3 * n4 - 1));
0316           break;
0317         }
0318         case (HGCalTypes::WaferCorner3): {
0319           good = ((u + v) >= (5 * n2 - 1));
0320           break;
0321         }
0322         case (HGCalTypes::WaferCorner4): {
0323           good = ((2 * u - v) >= (3 * n2));
0324           break;
0325         }
0326         default: {
0327           int u2 = (u + 1) / 2;
0328           good = ((v - u2) < n4);
0329           break;
0330         }
0331       }
0332       break;
0333     }
0334     case (HGCalTypes::WaferFive2): {  //WaferFive2
0335       switch (rotn) {
0336         case (HGCalTypes::WaferCorner0): {
0337           good = ((2 * v - u) <= (3 * n2));
0338           break;
0339         }
0340         case (HGCalTypes::WaferCorner1): {
0341           good = ((u + v) < (5 * n2));
0342           break;
0343         }
0344         case (HGCalTypes::WaferCorner2): {
0345           good = ((2 * u - v) >= (3 * n2));
0346           break;
0347         }
0348         case (HGCalTypes::WaferCorner3): {
0349           good = ((2 * v - u) >= n3);
0350           break;
0351         }
0352         case (HGCalTypes::WaferCorner4): {
0353           good = ((u + v) > (4 * n3));
0354           break;
0355         }
0356         default: {
0357           good = ((2 * u - v) >= n2);
0358           break;
0359         }
0360       }
0361       break;
0362     }
0363     case (HGCalTypes::WaferHalf2): {  //WaferHalf2
0364       switch (rotn) {
0365         case (HGCalTypes::WaferCorner0): {
0366           good = (v <= (3 * n4));
0367           break;
0368         }
0369         case (HGCalTypes::WaferCorner1): {
0370           good = (u <= (3 * n4));
0371           break;
0372         }
0373         case (HGCalTypes::WaferCorner2): {
0374           good = ((v - u) >= n4 - 1);
0375           break;
0376         }
0377         case (HGCalTypes::WaferCorner3): {
0378           good = (v >= (5 * n4 - 1));
0379           break;
0380         }
0381         case (HGCalTypes::WaferCorner4): {
0382           good = (u >= (5 * n4 - 1));
0383           break;
0384         }
0385         default: {
0386           good = ((u - v) >= n4);
0387           break;
0388         }
0389       }
0390       break;
0391     }
0392   }
0393 #ifdef EDM_ML_DEBUG
0394   edm::LogVerbatim("HGCalGeom") << "u|v " << u << ":" << v << " N " << n << " type " << type << " rot " << rotn
0395                                 << " good " << good;
0396 #endif
0397   return good;
0398 }
0399 
0400 bool HGCalWaferMask::goodCell(int u, int v, int waferType) {
0401   // for V17
0402   bool good(false);
0403   switch (waferType) {
0404     case (HGCalTypes::WaferFull): {  //WaferFull
0405       good = true;
0406       break;
0407     }
0408     case (HGCalTypes::WaferLDTop): {
0409       good = (u * HGCalTypes::edgeWaferLDTop[0] + v * HGCalTypes::edgeWaferLDTop[1] <= HGCalTypes::edgeWaferLDTop[2]);
0410       break;
0411     }
0412     case (HGCalTypes::WaferLDBottom): {
0413       good = (u * HGCalTypes::edgeWaferLDBottom[0] + v * HGCalTypes::edgeWaferLDBottom[1] <=
0414               HGCalTypes::edgeWaferLDBottom[2]);
0415       break;
0416     }
0417     case (HGCalTypes::WaferLDLeft): {
0418       good =
0419           (u * HGCalTypes::edgeWaferLDLeft[0] + v * HGCalTypes::edgeWaferLDLeft[1] <= HGCalTypes::edgeWaferLDLeft[2]);
0420       break;
0421     }
0422     case (HGCalTypes::WaferLDRight): {
0423       good = (u * HGCalTypes::edgeWaferLDRight[0] + v * HGCalTypes::edgeWaferLDRight[1] <=
0424               HGCalTypes::edgeWaferLDRight[2]);
0425       break;
0426     }
0427     case (HGCalTypes::WaferLDFive): {
0428       good =
0429           (u * HGCalTypes::edgeWaferLDFive[0] + v * HGCalTypes::edgeWaferLDFive[1] <= HGCalTypes::edgeWaferLDFive[2]);
0430       break;
0431     }
0432     case (HGCalTypes::WaferLDThree): {
0433       good = (u * HGCalTypes::edgeWaferLDThree[0] + v * HGCalTypes::edgeWaferLDThree[1] <=
0434               HGCalTypes::edgeWaferLDThree[2]);
0435       if (((u == 1) && (v == 8)) || ((u == 15) && (v == 15)))
0436         good = false;
0437       break;
0438     }
0439     case (HGCalTypes::WaferHDTop): {
0440       good = (u * HGCalTypes::edgeWaferHDTop[0] + v * HGCalTypes::edgeWaferHDTop[1] <= HGCalTypes::edgeWaferHDTop[2]);
0441       break;
0442     }
0443     case (HGCalTypes::WaferHDBottom): {
0444       good = (u * HGCalTypes::edgeWaferHDBottom[0] + v * HGCalTypes::edgeWaferHDBottom[1] <=
0445               HGCalTypes::edgeWaferHDBottom[2]);
0446       break;
0447     }
0448     case (HGCalTypes::WaferHDLeft): {
0449       good =
0450           (u * HGCalTypes::edgeWaferHDLeft[0] + v * HGCalTypes::edgeWaferHDLeft[1] <= HGCalTypes::edgeWaferHDLeft[2]);
0451       break;
0452     }
0453     case (HGCalTypes::WaferHDRight): {
0454       good = (u * HGCalTypes::edgeWaferHDRight[0] + v * HGCalTypes::edgeWaferHDRight[1] <=
0455               HGCalTypes::edgeWaferHDRight[2]);
0456       break;
0457     }
0458     case (HGCalTypes::WaferHDFive): {
0459       good =
0460           (u * HGCalTypes::edgeWaferHDFive[0] + v * HGCalTypes::edgeWaferHDFive[1] <= HGCalTypes::edgeWaferHDFive[2]);
0461       break;
0462     }
0463   }
0464 #ifdef EDM_ML_DEBUG
0465   edm::LogVerbatim("HGCalGeom") << "u|v " << u << ":" << v << " WaferType " << waferType << " good " << good;
0466 #endif
0467   return good;
0468 }
0469 
0470 int HGCalWaferMask::getRotation(int zside, int type, int rotn) {
0471   // Needs extension for V17
0472   if (rotn >= HGCalTypes::WaferCornerMax)
0473     rotn = HGCalTypes::WaferCorner0;
0474   int newrotn(rotn);
0475   if ((zside < 0) && (type != HGCalTypes::WaferFull)) {
0476     if ((type == HGCalTypes::WaferFive) || (type == HGCalTypes::WaferFive2)) {  //WaferFive/WaferFive2
0477       static constexpr int rot1[HGCalTypes::WaferCornerMax] = {HGCalTypes::WaferCorner4,
0478                                                                HGCalTypes::WaferCorner3,
0479                                                                HGCalTypes::WaferCorner2,
0480                                                                HGCalTypes::WaferCorner1,
0481                                                                HGCalTypes::WaferCorner0,
0482                                                                HGCalTypes::WaferCorner5};
0483       newrotn = rot1[rotn];
0484     } else if ((type == HGCalTypes::WaferThree) || (type == HGCalTypes::WaferSemi) ||
0485                (type == HGCalTypes::WaferSemi2)) {  //WaferThree/WaferSemi/WaferSemi2
0486       static constexpr int rot2[HGCalTypes::WaferCornerMax] = {HGCalTypes::WaferCorner2,
0487                                                                HGCalTypes::WaferCorner1,
0488                                                                HGCalTypes::WaferCorner0,
0489                                                                HGCalTypes::WaferCorner5,
0490                                                                HGCalTypes::WaferCorner4,
0491                                                                HGCalTypes::WaferCorner3};
0492       newrotn = rot2[rotn];
0493     } else {  //WaferHalf/WaferChopTwo/WaferChopTwoM/WaferHalf2
0494       static constexpr int rot3[HGCalTypes::WaferCornerMax] = {HGCalTypes::WaferCorner3,
0495                                                                HGCalTypes::WaferCorner2,
0496                                                                HGCalTypes::WaferCorner1,
0497                                                                HGCalTypes::WaferCorner0,
0498                                                                HGCalTypes::WaferCorner5,
0499                                                                HGCalTypes::WaferCorner4};
0500       newrotn = rot3[rotn];
0501     }
0502   }
0503 #ifdef EDM_ML_DEBUG
0504   edm::LogVerbatim("HGCalGeom") << "zside " << zside << " type " << type << " rotn " << rotn << ":" << newrotn;
0505 #endif
0506   return newrotn;
0507 }
0508 
0509 std::pair<int, int> HGCalWaferMask::getTypeMode(const double& xpos,
0510                                                 const double& ypos,
0511                                                 const double& delX,
0512                                                 const double& delY,
0513                                                 const double& rin,
0514                                                 const double& rout,
0515                                                 const int& wType,
0516                                                 const int& mode,
0517                                                 const bool& v17OrLess,
0518                                                 const bool& debug) {
0519   // No need to extend this for V17 -- use flat file information only
0520   int ncor(0), iok(0);
0521   int type(HGCalTypes::WaferFull), rotn(HGCalTypes::WaferCorner0);
0522   double c22(HGCalTypes::c22), c27(HGCalTypes::c27), c61(HGCalTypes::c61);
0523   double c77(HGCalTypes::c77), c88(HGCalTypes::c88);
0524   if (v17OrLess) {
0525     c22 = HGCalTypes::c22O;
0526     c27 = HGCalTypes::c27O;
0527     c61 = HGCalTypes::c61O;
0528     c77 = HGCalTypes::c77O;
0529     c88 = HGCalTypes::c88O;
0530   }
0531 
0532   static constexpr int corners = 6;
0533   static constexpr int base = 10;
0534   double rin2 = rin * rin;
0535   double rout2 = rout * rout;
0536   double dx0[corners] = {HGCalTypes::c00 * delX,
0537                          HGCalTypes::c10 * delX,
0538                          HGCalTypes::c10 * delX,
0539                          HGCalTypes::c00 * delX,
0540                          -HGCalTypes::c10 * delX,
0541                          -HGCalTypes::c10 * delX};
0542   double dy0[corners] = {-HGCalTypes::c10 * delY,
0543                          -HGCalTypes::c50 * delY,
0544                          HGCalTypes::c50 * delY,
0545                          HGCalTypes::c10 * delY,
0546                          HGCalTypes::c50 * delY,
0547                          -HGCalTypes::c50 * delY};
0548   double xc[corners], yc[corners];
0549   for (int k = 0; k < corners; ++k) {
0550     xc[k] = xpos + dx0[k];
0551     yc[k] = ypos + dy0[k];
0552     double rpos2 = (xc[k] * xc[k] + yc[k] * yc[k]);
0553     if (rpos2 <= rout2 && rpos2 >= rin2) {
0554       ++ncor;
0555       iok = iok * base + 1;
0556     } else {
0557       iok *= base;
0558     }
0559   }
0560   if (debug)
0561     edm::LogVerbatim("HGCalGeom") << "I/p: xp " << xpos << " yp " << ypos << " dX " << delX << " dY " << delY << " rin "
0562                                   << rin << " rout " << rout << " wtype " << wType << " mode " << mode << " Corners "
0563                                   << ncor << " iok " << iok;
0564 
0565   static constexpr int ipat5[corners] = {101111, 110111, 111011, 111101, 111110, 11111};
0566   static constexpr int ipat4[corners] = {100111, 110011, 111001, 111100, 11110, 1111};
0567   static constexpr int ipat3[corners] = {100011, 110001, 111000, 11100, 1110, 111};
0568   static constexpr int ipat2[corners] = {11, 100001, 110000, 11000, 1100, 110};
0569   double dx1[corners] = {HGCalTypes::c50 * delX,
0570                          HGCalTypes::c10 * delX,
0571                          HGCalTypes::c50 * delX,
0572                          -HGCalTypes::c50 * delX,
0573                          -HGCalTypes::c10 * delX,
0574                          -HGCalTypes::c50 * delX};
0575   double dy1[corners] = {-HGCalTypes::c75 * delY,
0576                          HGCalTypes::c00 * delY,
0577                          HGCalTypes::c75 * delY,
0578                          HGCalTypes::c75 * delY,
0579                          HGCalTypes::c00 * delY,
0580                          -HGCalTypes::c75 * delY};
0581   double dx2[corners] = {HGCalTypes::c50 * delX,
0582                          -HGCalTypes::c50 * delX,
0583                          -HGCalTypes::c10 * delX,
0584                          -HGCalTypes::c50 * delX,
0585                          HGCalTypes::c50 * delX,
0586                          HGCalTypes::c10 * delX};
0587   double dy2[corners] = {HGCalTypes::c75 * delY,
0588                          HGCalTypes::c75 * delY,
0589                          HGCalTypes::c00 * delY,
0590                          -HGCalTypes::c75 * delY,
0591                          -HGCalTypes::c75 * delY,
0592                          HGCalTypes::c00 * delY};
0593   double dx3[corners] = {
0594       c22 * delX, HGCalTypes::c10 * delX, c77 * delX, -c22 * delX, -HGCalTypes::c10 * delX, -c77 * delX};
0595   double dy3[corners] = {-c88 * delY, -c27 * delY, c61 * delY, c88 * delY, c27 * delY, -c61 * delY};
0596   double dx4[corners] = {
0597       c22 * delX, -c77 * delX, -HGCalTypes::c10 * delX, -c22 * delX, c77 * delX, HGCalTypes::c10 * delX};
0598   double dy4[corners] = {c88 * delY, c61 * delY, -c27 * delY, -c88 * delY, -c61 * delY, c27 * delY};
0599   double dx5[corners] = {-HGCalTypes::c50 * delX,
0600                          -HGCalTypes::c10 * delX,
0601                          -HGCalTypes::c50 * delX,
0602                          HGCalTypes::c50 * delX,
0603                          HGCalTypes::c10 * delX,
0604                          HGCalTypes::c50 * delX};
0605   double dy5[corners] = {HGCalTypes::c75 * delY,
0606                          HGCalTypes::c00 * delY,
0607                          -HGCalTypes::c75 * delY,
0608                          -HGCalTypes::c75 * delY,
0609                          HGCalTypes::c00 * delY,
0610                          HGCalTypes::c75 * delY};
0611   double dx6[corners] = {
0612       -c77 * delX, -HGCalTypes::c10 * delX, -c22 * delX, c77 * delX, HGCalTypes::c10 * delX, c22 * delX};
0613   double dy6[corners] = {c61 * delY, -c27 * delY, -c88 * delY, -c61 * delY, c27 * delY, c88 * delY};
0614   double dx7[corners] = {
0615       -c22 * delX, -HGCalTypes::c10 * delX, -c77 * delX, c22 * delX, HGCalTypes::c10 * delX, c77 * delX};
0616   double dy7[corners] = {c88 * delY, c27 * delY, -c61 * delY, -c88 * delY, -c27 * delY, c61 * delY};
0617   double dx8[corners] = {
0618       c77 * delX, HGCalTypes::c10 * delX, c22 * delX, -c77 * delX, -HGCalTypes::c10 * delX, -c22 * delX};
0619   double dy8[corners] = {-c61 * delY, c27 * delY, c88 * delY, c61 * delY, -c27 * delY, -c88 * delY};
0620   double dx9[corners] = {
0621       -c22 * delX, c77 * delX, HGCalTypes::c10 * delX, c22 * delX, -c77 * delX, -HGCalTypes::c10 * delX};
0622   double dy9[corners] = {-c88 * delY, -c61 * delY, c27 * delY, c88 * delY, c61 * delY, -c27 * delY};
0623 
0624   if (ncor == HGCalGeomTools::k_allCorners) {
0625   } else if (ncor == HGCalGeomTools::k_fiveCorners) {
0626     rotn = static_cast<int>(std::find(ipat5, ipat5 + 6, iok) - ipat5);
0627     type = HGCalTypes::WaferFive;
0628   } else if (ncor == HGCalGeomTools::k_fourCorners) {
0629     rotn = static_cast<int>(std::find(ipat4, ipat4 + 6, iok) - ipat4);
0630     type = HGCalTypes::WaferHalf;
0631     double rpos12 = ((xpos + dx1[rotn]) * (xpos + dx1[rotn]) + (ypos + dy1[rotn]) * (ypos + dy1[rotn]));
0632     double rpos22(0);
0633     if (rpos12 <= rout2 && rpos12 >= rin2) {
0634       rpos22 = ((xpos + dx2[rotn]) * (xpos + dx2[rotn]) + (ypos + dy2[rotn]) * (ypos + dy2[rotn]));
0635       if (rpos22 <= rout2 && rpos22 >= rin2)
0636         type = HGCalTypes::WaferChopTwo;
0637     }
0638     if (debug)
0639       edm::LogVerbatim("HGCalGeom") << "Test for Chop2 " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0640                                     << type;
0641     if ((type == HGCalTypes::WaferHalf) && (wType == 0)) {
0642       rpos12 = ((xpos + dx3[rotn]) * (xpos + dx3[rotn]) + (ypos + dy3[rotn]) * (ypos + dy3[rotn]));
0643       if (rpos12 <= rout2 && rpos12 >= rin2) {
0644         rpos22 = ((xpos + dx4[rotn]) * (xpos + dx4[rotn]) + (ypos + dy4[rotn]) * (ypos + dy4[rotn]));
0645         if (rpos22 <= rout2 && rpos22 >= rin2)
0646           type = HGCalTypes::WaferChopTwoM;
0647       }
0648       if (debug)
0649         edm::LogVerbatim("HGCalGeom") << "Test for Chop2M " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0650                                       << type;
0651     }
0652   } else if (ncor == HGCalGeomTools::k_threeCorners) {
0653     rotn = static_cast<int>(std::find(ipat3, ipat3 + 6, iok) - ipat3);
0654     type = HGCalTypes::WaferThree;
0655     double rpos12 = ((xpos + dx7[rotn]) * (xpos + dx7[rotn]) + (ypos + dy7[rotn]) * (ypos + dy7[rotn]));
0656     double rpos22(0);
0657     if (rpos12 <= rout2 && rpos12 >= rin2) {
0658       rpos22 = ((xpos + dx8[rotn]) * (xpos + dx8[rotn]) + (ypos + dy8[rotn]) * (ypos + dy8[rotn]));
0659       if (rpos22 <= rout2 && rpos22 >= rin2)
0660         type = HGCalTypes::WaferFive2;
0661     }
0662     if (debug)
0663       edm::LogVerbatim("HGCalGeom") << "Test for Five2 " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0664                                     << type;
0665     if ((type == HGCalTypes::WaferThree) && (wType == 0)) {
0666       rpos12 = ((xpos + dx1[rotn]) * (xpos + dx1[rotn]) + (ypos + dy1[rotn]) * (ypos + dy1[rotn]));
0667       if (rpos12 <= rout2 && rpos12 >= rin2) {
0668         rpos22 = ((xpos + dx5[rotn]) * (xpos + dx5[rotn]) + (ypos + dy5[rotn]) * (ypos + dy5[rotn]));
0669         if (rpos22 <= rout2 && rpos22 >= rin2)
0670           type = HGCalTypes::WaferSemi;
0671       }
0672       if (debug)
0673         edm::LogVerbatim("HGCalGeom") << "Test for Semi " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0674                                       << type;
0675     }
0676     if ((type == HGCalTypes::WaferThree) && (wType == 0)) {
0677       rpos12 = ((xpos + dx3[rotn]) * (xpos + dx3[rotn]) + (ypos + dy3[rotn]) * (ypos + dy3[rotn]));
0678       if (rpos12 <= rout2 && rpos12 >= rin2) {
0679         rpos22 = ((xpos + dx6[rotn]) * (xpos + dx6[rotn]) + (ypos + dy6[rotn]) * (ypos + dy6[rotn]));
0680         if (rpos22 <= rout2 && rpos22 >= rin2)
0681           type = HGCalTypes::WaferSemi2;
0682       }
0683       if (debug)
0684         edm::LogVerbatim("HGCalGeom") << "Test for SemiM " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0685                                       << type;
0686     }
0687   } else if (ncor == HGCalGeomTools::k_twoCorners) {
0688     rotn = static_cast<int>(std::find(ipat2, ipat2 + 6, iok) - ipat2);
0689     type = HGCalTypes::WaferOut;
0690     double rpos12 = ((xpos + dx7[rotn]) * (xpos + dx7[rotn]) + (ypos + dy7[rotn]) * (ypos + dy7[rotn]));
0691     double rpos22(0);
0692     if (rpos12 <= rout2 && rpos12 >= rin2) {
0693       rpos22 = ((xpos + dx9[rotn]) * (xpos + dx9[rotn]) + (ypos + dy9[rotn]) * (ypos + dy9[rotn]));
0694       if (rpos22 <= rout2 && rpos22 >= rin2)
0695         type = HGCalTypes::WaferHalf2;
0696       else
0697         rotn = HGCalTypes::WaferCorner0;
0698     }
0699     if (debug)
0700       edm::LogVerbatim("HGCalGeom") << "Test for Half2 " << std::sqrt(rpos12) << ":" << std::sqrt(rpos22) << " Type "
0701                                     << type;
0702   } else {
0703     type = HGCalTypes::WaferOut;
0704   }
0705 
0706   if (debug)
0707     edm::LogVerbatim("HGCalGeom") << "I/p: xpos " << xpos << " ypos " << ypos << " dX " << delX << " dY " << delY
0708                                   << " rin " << rin << " rout " << rout << " wType " << wType << " mode " << mode
0709                                   << " O/p: ok " << iok << " ncor " << ncor << " type " << type << " rotn " << rotn;
0710   return ((mode == 0) ? std::make_pair(ncor, rotn) : std::make_pair(type, (rotn + HGCalTypes::k_OffsetRotation)));
0711 }
0712 
0713 bool HGCalWaferMask::goodTypeMode(const double& xpos,
0714                                   const double& ypos,
0715                                   const double& delX,
0716                                   const double& delY,
0717                                   const double& rin,
0718                                   const double& rout,
0719                                   const int& part,
0720                                   const int& rotn,
0721                                   const bool& v17OrLess,
0722                                   const bool& debug) {
0723   // Needs extension for V17 or above
0724   double c22(HGCalTypes::c22), c27(HGCalTypes::c27), c61(HGCalTypes::c61);
0725   double c77(HGCalTypes::c77), c88(HGCalTypes::c88);
0726   if (v17OrLess) {
0727     c22 = HGCalTypes::c22O;
0728     c27 = HGCalTypes::c27O;
0729     c61 = HGCalTypes::c61O;
0730     c77 = HGCalTypes::c77O;
0731     c88 = HGCalTypes::c88O;
0732   }
0733 
0734   if (part < 0 || part > HGCalTypes::WaferSizeMax)
0735     return false;
0736   if (rotn < 0 || rotn > HGCalTypes::WaferCornerMax)
0737     return false;
0738   double rin2 = rin * rin;
0739   double rout2 = rout * rout;
0740   double rpos2(0);
0741   static constexpr int corners = HGCalTypes::WaferCornerMax;
0742   static constexpr int corner2 = 2 * HGCalTypes::WaferCornerMax;
0743   static constexpr int base = 10;
0744   static constexpr int base2 = 100;
0745   double dx0[corners] = {HGCalTypes::c00 * delX,
0746                          HGCalTypes::c10 * delX,
0747                          HGCalTypes::c10 * delX,
0748                          HGCalTypes::c00 * delX,
0749                          -HGCalTypes::c10 * delX,
0750                          -HGCalTypes::c10 * delX};
0751   double dy0[corners] = {-HGCalTypes::c10 * delY,
0752                          -HGCalTypes::c50 * delY,
0753                          HGCalTypes::c50 * delY,
0754                          HGCalTypes::c10 * delY,
0755                          HGCalTypes::c50 * delY,
0756                          -HGCalTypes::c50 * delY};
0757   double dx1[corners] = {HGCalTypes::c50 * delX,
0758                          HGCalTypes::c10 * delX,
0759                          HGCalTypes::c50 * delX,
0760                          -HGCalTypes::c50 * delX,
0761                          -HGCalTypes::c10 * delX,
0762                          -HGCalTypes::c50 * delX};
0763   double dy1[corners] = {-HGCalTypes::c75 * delY,
0764                          HGCalTypes::c00 * delY,
0765                          HGCalTypes::c75 * delY,
0766                          HGCalTypes::c75 * delY,
0767                          HGCalTypes::c00 * delY,
0768                          -HGCalTypes::c75 * delY};
0769   double dx2[corner2] = {c22 * delX,
0770                          c77 * delX,
0771                          HGCalTypes::c10 * delX,
0772                          HGCalTypes::c10 * delX,
0773                          c77 * delX,
0774                          c22 * delX,
0775                          -c22 * delX,
0776                          -c77 * delX,
0777                          -HGCalTypes::c10 * delX,
0778                          -HGCalTypes::c10 * delX,
0779                          -c77 * delX,
0780                          -c22 * delX};
0781   double dy2[corner2] = {-c88 * delY,
0782                          -c61 * delY,
0783                          -c27 * delY,
0784                          c27 * delY,
0785                          c61 * delY,
0786                          c88 * delY,
0787                          c88 * delY,
0788                          c61 * delY,
0789                          c27 * delY,
0790                          -c27 * delY,
0791                          -c61 * delY,
0792                          -c88 * delY};
0793   bool ok(true);
0794   int ncf(-1);
0795   switch (part) {
0796     case (HGCalTypes::WaferThree): {
0797       static constexpr int nc0[corners] = {450, 150, 201, 312, 423, 534};
0798       int nc = nc0[rotn];
0799       for (int k1 = 0; k1 < 3; ++k1) {
0800         int k = nc % base;
0801         double xc1 = xpos + dx0[k];
0802         double yc1 = ypos + dy0[k];
0803         rpos2 = (xc1 * xc1 + yc1 * yc1);
0804         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0805           ok = false;
0806           ncf = k;
0807           break;
0808         }
0809         nc /= base;
0810       }
0811       break;
0812     }
0813     case (HGCalTypes::WaferSemi2): {
0814       static constexpr int nc10[corners] = {450, 150, 201, 312, 423, 534};
0815       static constexpr int nc11[corners] = {700, 902, 1104, 106, 308, 510};
0816       int nc = nc10[rotn];
0817       for (int k1 = 0; k1 < 3; ++k1) {
0818         int k = nc % base;
0819         double xc1 = xpos + dx0[k];
0820         double yc1 = ypos + dy0[k];
0821         rpos2 = (xc1 * xc1 + yc1 * yc1);
0822         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0823           ok = false;
0824           ncf = k;
0825           break;
0826         }
0827         nc /= base;
0828       }
0829       nc = nc11[rotn];
0830       for (int k1 = 0; k1 < 2; ++k1) {
0831         int k = nc % base2;
0832         double xc1 = xpos + dx2[k];
0833         double yc1 = ypos + dy2[k];
0834         rpos2 = (xc1 * xc1 + yc1 * yc1);
0835         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0836           ok = false;
0837           ncf = k + base2;
0838           break;
0839         }
0840         nc /= base2;
0841       }
0842       break;
0843     }
0844     case (HGCalTypes::WaferSemi): {
0845       static constexpr int nc20[corners] = {450, 150, 201, 312, 423, 534};
0846       static constexpr int nc21[corners] = {30, 14, 25, 30, 41, 52};
0847       int nc = nc20[rotn];
0848       for (int k1 = 0; k1 < 3; ++k1) {
0849         int k = nc % base;
0850         double xc1 = xpos + dx0[k];
0851         double yc1 = ypos + dy0[k];
0852         rpos2 = (xc1 * xc1 + yc1 * yc1);
0853         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0854           ok = false;
0855           ncf = k;
0856           break;
0857         }
0858         nc /= base;
0859       }
0860       nc = nc21[rotn];
0861       for (int k1 = 0; k1 < 2; ++k1) {
0862         int k = nc % base;
0863         double xc1 = xpos + dx1[k];
0864         double yc1 = ypos + dy1[k];
0865         rpos2 = (xc1 * xc1 + yc1 * yc1);
0866         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0867           ok = false;
0868           ncf = k + base2;
0869           break;
0870         }
0871         nc /= base;
0872       }
0873       break;
0874     }
0875     case (HGCalTypes::WaferHalf): {
0876       static constexpr int nc3[corners] = {3450, 1450, 2501, 3012, 4123, 5234};
0877       int nc = nc3[rotn];
0878       for (int k1 = 0; k1 < 4; ++k1) {
0879         int k = nc % base;
0880         double xc1 = xpos + dx0[k];
0881         double yc1 = ypos + dy0[k];
0882         rpos2 = (xc1 * xc1 + yc1 * yc1);
0883         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0884           ok = false;
0885           ncf = k;
0886           break;
0887         }
0888         nc /= base;
0889       }
0890       break;
0891     }
0892     case (HGCalTypes::WaferChopTwoM): {
0893       static constexpr int nc40[corners] = {3450, 1450, 2501, 3012, 4123, 5234};
0894       static constexpr int nc41[corners] = {500, 702, 904, 1106, 108, 310};
0895       int nc = nc40[rotn];
0896       for (int k1 = 0; k1 < 4; ++k1) {
0897         int k = nc % base;
0898         double xc1 = xpos + dx0[k];
0899         double yc1 = ypos + dy0[k];
0900         rpos2 = (xc1 * xc1 + yc1 * yc1);
0901         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0902           ok = false;
0903           ncf = k;
0904           break;
0905         }
0906         nc /= base;
0907       }
0908       nc = nc41[rotn];
0909       for (int k1 = 0; k1 < 2; ++k1) {
0910         int k = nc % base2;
0911         double xc1 = xpos + dx2[k];
0912         double yc1 = ypos + dy2[k];
0913         rpos2 = (xc1 * xc1 + yc1 * yc1);
0914         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0915           ok = false;
0916           ncf = k + base2;
0917           break;
0918         }
0919         nc /= base2;
0920       }
0921       break;
0922     }
0923     case (HGCalTypes::WaferChopTwo): {
0924       static constexpr int nc50[corners] = {3450, 1450, 2501, 3012, 4123, 5234};
0925       static constexpr int nc51[corners] = {20, 13, 24, 35, 40, 51};
0926       int nc = nc50[rotn];
0927       for (int k1 = 0; k1 < 4; ++k1) {
0928         int k = nc % base;
0929         double xc1 = xpos + dx0[k];
0930         double yc1 = ypos + dy0[k];
0931         rpos2 = (xc1 * xc1 + yc1 * yc1);
0932         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0933           ok = false;
0934           ncf = k;
0935           break;
0936         }
0937         nc /= base;
0938       }
0939       nc = nc51[rotn];
0940       for (int k1 = 0; k1 < 2; ++k1) {
0941         int k = nc % base;
0942         double xc1 = xpos + dx1[k];
0943         double yc1 = ypos + dy1[k];
0944         rpos2 = (xc1 * xc1 + yc1 * yc1);
0945         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0946           ok = false;
0947           ncf = k + base2;
0948           break;
0949         }
0950         nc /= base;
0951       }
0952       break;
0953     }
0954     case (HGCalTypes::WaferFive): {
0955       static constexpr int nc6[corners] = {23450, 13450, 24501, 35012, 40123, 51234};
0956       int nc = nc6[rotn];
0957       for (int k1 = 0; k1 < 5; ++k1) {
0958         int k = nc % base;
0959         double xc1 = xpos + dx0[k];
0960         double yc1 = ypos + dy0[k];
0961         rpos2 = (xc1 * xc1 + yc1 * yc1);
0962         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0963           ok = false;
0964           ncf = k;
0965           break;
0966         }
0967       }
0968       break;
0969     }
0970     case (HGCalTypes::WaferFive2): {
0971       static constexpr int nc60[corners] = {450, 150, 201, 312, 423, 534};
0972       static constexpr int nc61[corners] = {601, 803, 1005, 7, 209, 411};
0973       int nc = nc60[rotn];
0974       for (int k1 = 0; k1 < 3; ++k1) {
0975         int k = nc % base;
0976         double xc1 = xpos + dx0[k];
0977         double yc1 = ypos + dy0[k];
0978         rpos2 = (xc1 * xc1 + yc1 * yc1);
0979         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0980           ok = false;
0981           ncf = k;
0982           break;
0983         }
0984         nc /= base;
0985       }
0986       nc = nc61[rotn];
0987       for (int k1 = 0; k1 < 2; ++k1) {
0988         int k = nc % base2;
0989         double xc1 = xpos + dx2[k];
0990         double yc1 = ypos + dy2[k];
0991         rpos2 = (xc1 * xc1 + yc1 * yc1);
0992         if ((rpos2 > rout2) || (rpos2 < rin2)) {
0993           ok = false;
0994           ncf = k + base2;
0995           break;
0996         }
0997         nc /= base2;
0998       }
0999       break;
1000     }
1001     case (HGCalTypes::WaferHalf2): {
1002       static constexpr int nc70[corners] = {45, 50, 1, 12, 23, 34};
1003       static constexpr int nc71[corners] = {611, 801, 1003, 5, 207, 409};
1004       int nc = nc70[rotn];
1005       for (int k1 = 0; k1 < 2; ++k1) {
1006         int k = nc % base;
1007         double xc1 = xpos + dx0[k];
1008         double yc1 = ypos + dy0[k];
1009         rpos2 = (xc1 * xc1 + yc1 * yc1);
1010         if ((rpos2 > rout2) || (rpos2 < rin2)) {
1011           ok = false;
1012           ncf = k;
1013           break;
1014         }
1015         nc /= base;
1016       }
1017       nc = nc71[rotn];
1018       for (int k1 = 0; k1 < 2; ++k1) {
1019         int k = nc % base2;
1020         double xc1 = xpos + dx2[k];
1021         double yc1 = ypos + dy2[k];
1022         rpos2 = (xc1 * xc1 + yc1 * yc1);
1023         if ((rpos2 > rout2) || (rpos2 < rin2)) {
1024           ok = false;
1025           ncf = k + base2;
1026           break;
1027         }
1028         nc /= base2;
1029       }
1030       break;
1031     }
1032     default: {
1033       for (int k = 0; k < corners; ++k) {
1034         double xc1 = xpos + dx0[k];
1035         double yc1 = ypos + dy0[k];
1036         rpos2 = (xc1 * xc1 + yc1 * yc1);
1037         if ((rpos2 > rout2) || (rpos2 < rin2)) {
1038           ok = false;
1039           ncf = k;
1040           break;
1041         }
1042       }
1043       break;
1044     }
1045   }
1046   if (debug || (!ok))
1047     edm::LogVerbatim("HGCalGeom") << "I/p: xpos " << xpos << " ypos " << ypos << " dX " << delX << " dY " << delY
1048                                   << " rin " << rin << " rout " << rout << " part " << part << " rotn " << rotn
1049                                   << " Results: ok " << ok << " ncf " << ncf << " rin " << rin2 << " rout " << rout2
1050                                   << " rpos " << rpos2;
1051   return ok;
1052 }
1053 
1054 std::vector<std::pair<double, double> > HGCalWaferMask::waferXY(const int& part,
1055                                                                 const int& ori,
1056                                                                 const int& zside,
1057                                                                 const double& waferSize,
1058                                                                 const double& offset,
1059                                                                 const double& xpos,
1060                                                                 const double& ypos,
1061                                                                 const bool& v17OrLess) {
1062   // Good for V15 and V16 versions
1063   std::vector<std::pair<double, double> > xy;
1064   int orient = getRotation(-zside, part, ori);
1065 #ifdef EDM_ML_DEBUG
1066   edm::LogVerbatim("HGCalGeom") << "Part " << part << " zSide " << zside << " Orient " << ori << ":" << orient;
1067 #endif
1068   double c22(HGCalTypes::c22), c27(HGCalTypes::c27), c61(HGCalTypes::c61);
1069   double c77(HGCalTypes::c77), c88(HGCalTypes::c88);
1070   if (v17OrLess) {
1071     c22 = HGCalTypes::c22O;
1072     c27 = HGCalTypes::c27O;
1073     c61 = HGCalTypes::c61O;
1074     c77 = HGCalTypes::c77O;
1075     c88 = HGCalTypes::c88O;
1076   }
1077   /*
1078     The exact contour of partial wafers are obtained by joining points on
1079     the circumference of a full wafer.
1080     Numbering the points along the edges of a hexagonal wafer, starting from
1081     the bottom corner:
1082 
1083                                    3
1084                                15     18
1085                              9           8
1086                           19               14
1087                         4                     2 
1088                        16                    23
1089                        10                     7
1090                        20                    13
1091                         5                     1
1092                           17               22
1093                             11           6
1094                                21     12
1095                                    0
1096 
1097     Depending on the wafer type and orientation index, the corners
1098     are chosen in the variable *np*
1099   */
1100   double delX = 0.5 * waferSize;
1101   double delY = delX / sin_60_;
1102   double dx[48] = {HGCalTypes::c00 * delX,
1103                    HGCalTypes::c10 * delX,
1104                    HGCalTypes::c10 * delX,
1105                    HGCalTypes::c00 * delX,
1106                    -HGCalTypes::c10 * delX,
1107                    -HGCalTypes::c10 * delX,
1108                    HGCalTypes::c50 * delX,
1109                    HGCalTypes::c10 * delX,
1110                    HGCalTypes::c50 * delX,
1111                    -HGCalTypes::c50 * delX,
1112                    -HGCalTypes::c10 * delX,
1113                    -HGCalTypes::c50 * delX,
1114                    c22 * delX,
1115                    HGCalTypes::c10 * delX,
1116                    c77 * delX,
1117                    -c22 * delX,
1118                    -HGCalTypes::c10 * delX,
1119                    -c77 * delX,
1120                    c22 * delX,
1121                    -c77 * delX,
1122                    -HGCalTypes::c10 * delX,
1123                    -c22 * delX,
1124                    c77 * delX,
1125                    HGCalTypes::c10 * delX,
1126                    HGCalTypes::c50 * delX,
1127                    HGCalTypes::c10 * delX,
1128                    HGCalTypes::c50 * delX,
1129                    -HGCalTypes::c50 * delX,
1130                    -HGCalTypes::c10 * delX,
1131                    -HGCalTypes::c50 * delX,
1132                    HGCalTypes::c50 * delX,
1133                    HGCalTypes::c10 * delX,
1134                    HGCalTypes::c50 * delX,
1135                    -HGCalTypes::c50 * delX,
1136                    -HGCalTypes::c10 * delX,
1137                    -HGCalTypes::c50 * delX,
1138                    c22 * delX,
1139                    HGCalTypes::c10 * delX,
1140                    c77 * delX,
1141                    -c22 * delX,
1142                    -HGCalTypes::c10 * delX,
1143                    -c77 * delX,
1144                    c22 * delX,
1145                    -c77 * delX,
1146                    -HGCalTypes::c10 * delX,
1147                    -c22 * delX,
1148                    c77 * delX,
1149                    HGCalTypes::c10 * delX};
1150   double dy[48] = {-HGCalTypes::c10 * delY,
1151                    -HGCalTypes::c50 * delY,
1152                    HGCalTypes::c50 * delY,
1153                    HGCalTypes::c10 * delY,
1154                    HGCalTypes::c50 * delY,
1155                    -HGCalTypes::c50 * delY,
1156                    -HGCalTypes::c75 * delY,
1157                    HGCalTypes::c00 * delY,
1158                    HGCalTypes::c75 * delY,
1159                    HGCalTypes::c75 * delY,
1160                    HGCalTypes::c00 * delY,
1161                    -HGCalTypes::c75 * delY,
1162                    -c88 * delY,
1163                    -c27 * delY,
1164                    c61 * delY,
1165                    c88 * delY,
1166                    c27 * delY,
1167                    -c61 * delY,
1168                    c88 * delY,
1169                    c61 * delY,
1170                    -c27 * delY,
1171                    -c88 * delY,
1172                    -c61 * delY,
1173                    c27 * delY,
1174                    -HGCalTypes::c75 * delY,
1175                    HGCalTypes::c00 * delY,
1176                    -HGCalTypes::c75 * delY,
1177                    HGCalTypes::c00 * delY,
1178                    HGCalTypes::c75 * delY,
1179                    HGCalTypes::c75 * delY,
1180                    HGCalTypes::c00 * delY,
1181                    -HGCalTypes::c75 * delY,
1182                    HGCalTypes::c75 * delY,
1183                    HGCalTypes::c75 * delY,
1184                    HGCalTypes::c00 * delY,
1185                    -HGCalTypes::c75 * delY,
1186                    -c88 * delY,
1187                    -c27 * delY,
1188                    c61 * delY,
1189                    c88 * delY,
1190                    c27 * delY,
1191                    -c61 * delY,
1192                    c88 * delY,
1193                    c61 * delY,
1194                    -c27 * delY,
1195                    -c88 * delY,
1196                    -c61 * delY,
1197                    c27 * delY};
1198 
1199   double offsetx[48] = {0.0,
1200                         -offset,
1201                         -offset,
1202                         0.0,
1203                         offset,
1204                         offset,
1205                         -offset * cos_60_,
1206                         -offset,
1207                         -offset * cos_60_,
1208                         offset * cos_60_,
1209                         offset,
1210                         offset * cos_60_,
1211                         -offset * cos_60_,
1212                         -offset,
1213                         -offset * cos_60_,
1214                         offset * cos_60_,
1215                         offset,
1216                         offset * cos_60_,
1217                         -offset * cos_60_,
1218                         offset * cos_60_,
1219                         offset,
1220                         offset * cos_60_,
1221                         -offset * cos_60_,
1222                         -offset,
1223                         0.0,
1224                         -offset,
1225                         -offset,
1226                         0.0,
1227                         offset,
1228                         offset,
1229                         0.0,
1230                         offset,
1231                         offset,
1232                         0.0,
1233                         -offset,
1234                         -offset,
1235                         0.0,
1236                         -offset,
1237                         -offset,
1238                         0.0,
1239                         offset,
1240                         offset,
1241                         0.0,
1242                         offset,
1243                         offset,
1244                         0.0,
1245                         -offset,
1246                         -offset};
1247   double offsety[48] = {offset / sin_60_,
1248                         offset / tan_60_,
1249                         -offset / tan_60_,
1250                         -offset / sin_60_,
1251                         -offset / tan_60_,
1252                         offset / tan_60_,
1253                         offset * sin_60_,
1254                         0.0,
1255                         -offset * sin_60_,
1256                         -offset * sin_60_,
1257                         0.0,
1258                         offset * sin_60_,
1259                         offset * sin_60_,
1260                         0.0,
1261                         -offset * sin_60_,
1262                         -offset * sin_60_,
1263                         0.0,
1264                         offset * sin_60_,
1265                         -offset * sin_60_,
1266                         -offset * sin_60_,
1267                         0.0,
1268                         offset * sin_60_,
1269                         offset * sin_60_,
1270                         0.0,
1271                         offset / sin_60_,
1272                         offset / tan_60_,
1273                         -offset / tan_60_,
1274                         -offset / sin_60_,
1275                         -offset / tan_60_,
1276                         -offset / sin_60_,
1277                         -offset / tan_60_,
1278                         offset / tan_60_,
1279                         offset / sin_60_,
1280                         offset / tan_60_,
1281                         -offset / tan_60_,
1282                         offset / tan_60_,
1283                         offset / sin_60_,
1284                         offset / tan_60_,
1285                         -offset / tan_60_,
1286                         -offset / sin_60_,
1287                         -offset / tan_60_,
1288                         offset / tan_60_,
1289                         -offset / sin_60_,
1290                         -offset / tan_60_,
1291                         offset / tan_60_,
1292                         offset / sin_60_,
1293                         offset / tan_60_,
1294                         -offset / tan_60_};
1295 
1296   if (part == HGCalTypes::WaferFull) {
1297     int np[7] = {0, 1, 2, 3, 4, 5, 0};
1298     for (int k = 0; k < 7; ++k)
1299       xy.push_back(std::make_pair((xpos + dx[np[k]] + offsetx[np[k]]), (ypos + dy[np[k]] + offsety[np[k]])));
1300   } else if (part == HGCalTypes::WaferFive) {
1301     int np[6][6] = {{0, 2, 3, 4, 5, 0},
1302                     {1, 3, 4, 5, 0, 1},
1303                     {2, 4, 5, 0, 1, 2},
1304                     {3, 5, 0, 1, 2, 3},
1305                     {4, 0, 1, 2, 3, 4},
1306                     {5, 1, 2, 3, 4, 5}};
1307     for (int k = 0; k < 6; ++k) {
1308       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1309                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1310 #ifdef EDM_ML_DEBUG
1311       edm::LogVerbatim("HGCalGeom") << "WaferFull " << k << " np " << np[orient][k] << " dx "
1312                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1313                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1314 #endif
1315     }
1316   } else if (part == HGCalTypes::WaferHalf) {
1317     int np[6][5] = {
1318         {0, 3, 4, 5, 0}, {1, 4, 5, 0, 1}, {2, 5, 0, 1, 2}, {3, 0, 1, 2, 3}, {4, 1, 2, 3, 4}, {5, 2, 3, 4, 5}};
1319     for (int k = 0; k < 5; ++k) {
1320       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1321                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1322 #ifdef EDM_ML_DEBUG
1323       edm::LogVerbatim("HGCalGeom") << "WaferHalf " << k << " np " << np[orient][k] << " dx "
1324                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1325                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1326 #endif
1327     }
1328   } else if (part == HGCalTypes::WaferThree) {
1329     int np[6][4] = {{0, 4, 5, 0}, {1, 5, 0, 1}, {2, 0, 1, 2}, {3, 1, 2, 3}, {4, 2, 3, 4}, {5, 3, 4, 5}};
1330     for (int k = 0; k < 4; ++k) {
1331       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1332                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1333 #ifdef EDM_ML_DEBUG
1334       edm::LogVerbatim("HGCalGeom") << "WaferThree " << k << " np " << np[orient][k] << " dx "
1335                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1336                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1337 #endif
1338     }
1339   } else if (part == HGCalTypes::WaferChopTwo) {
1340     int np[6][7] = {{24, 32, 3, 4, 5, 0, 24},
1341                     {25, 33, 4, 5, 0, 1, 25},
1342                     {26, 34, 5, 0, 1, 2, 26},
1343                     {27, 35, 0, 1, 2, 3, 27},
1344                     {28, 30, 1, 2, 3, 4, 28},
1345                     {29, 31, 2, 3, 4, 5, 29}};
1346     for (int k = 0; k < 7; ++k) {
1347       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1348                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1349 #ifdef EDM_ML_DEBUG
1350       edm::LogVerbatim("HGCalGeom") << "WaferChopTwo " << k << " np " << np[orient][k] << " dx "
1351                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1352                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1353 #endif
1354     }
1355   } else if (part == HGCalTypes::WaferSemi) {
1356     int np[6][6] = {{6, 9, 4, 5, 0, 6},
1357                     {7, 10, 5, 0, 1, 7},
1358                     {8, 11, 0, 1, 2, 8},
1359                     {9, 6, 1, 2, 3, 9},
1360                     {10, 7, 2, 3, 4, 10},
1361                     {11, 8, 3, 4, 5, 11}};
1362     for (int k = 0; k < 6; ++k) {
1363       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1364                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1365 #ifdef EDM_ML_DEBUG
1366       edm::LogVerbatim("HGCalGeom") << "WaferSemi " << k << " np " << np[orient][k] << " dx "
1367                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1368                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1369 #endif
1370     }
1371   } else if (part == HGCalTypes::WaferChopTwoM) {
1372     int np[6][7] = {{36, 42, 3, 4, 5, 0, 36},
1373                     {37, 43, 4, 5, 0, 1, 37},
1374                     {38, 44, 5, 0, 1, 2, 38},
1375                     {39, 45, 0, 1, 2, 3, 39},
1376                     {40, 46, 1, 2, 3, 4, 40},
1377                     {41, 47, 2, 3, 4, 5, 41}};
1378     for (int k = 0; k < 7; ++k) {
1379       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1380                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1381 #ifdef EDM_ML_DEBUG
1382       edm::LogVerbatim("HGCalGeom") << " WaferChopTwoM " << k << " np " << np[orient][k] << " dx "
1383                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1384                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1385 #endif
1386     }
1387   } else if (part == HGCalTypes::WaferSemi2) {
1388     int np[6][6] = {{12, 19, 4, 5, 0, 12},
1389                     {13, 20, 5, 0, 1, 13},
1390                     {14, 21, 0, 1, 2, 14},
1391                     {15, 22, 1, 2, 3, 15},
1392                     {16, 23, 2, 3, 4, 16},
1393                     {17, 18, 3, 4, 5, 17}};
1394     for (int k = 0; k < 6; ++k) {
1395       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1396                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1397 #ifdef EDM_ML_DEBUG
1398       edm::LogVerbatim("HGCalGeom") << "WaferSemi2 " << k << " np " << np[orient][k] << " dx "
1399                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1400                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1401 #endif
1402     }
1403   } else if (part == HGCalTypes::WaferFive2) {
1404     int np[6][6] = {{22, 15, 4, 5, 0, 22},
1405                     {23, 16, 5, 0, 1, 23},
1406                     {18, 17, 0, 1, 2, 18},
1407                     {19, 12, 1, 2, 3, 19},
1408                     {20, 13, 2, 3, 4, 20},
1409                     {21, 14, 3, 4, 5, 21}};
1410     for (int k = 0; k < 6; ++k) {
1411       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1412                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1413 #ifdef EDM_ML_DEBUG
1414       edm::LogVerbatim("HGCalGeom") << "WaferFive2 " << k << " np " << np[orient][k] << " dx "
1415                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1416                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1417 #endif
1418     }
1419   } else if (part == HGCalTypes::WaferHalf2) {
1420     int np[6][5] = {{45, 39, 4, 5, 45},
1421                     {46, 40, 5, 0, 46},
1422                     {47, 41, 0, 1, 47},
1423                     {42, 36, 1, 2, 42},
1424                     {43, 37, 2, 3, 43},
1425                     {44, 38, 3, 4, 44}};
1426     for (int k = 0; k < 5; ++k) {
1427       xy.push_back(std::make_pair((xpos + dx[np[orient][k]] + offsetx[np[orient][k]]),
1428                                   (ypos + dy[np[orient][k]] + offsety[np[orient][k]])));
1429 #ifdef EDM_ML_DEBUG
1430       edm::LogVerbatim("HGCalGeom") << "WaferHalf2 " << k << " np " << np[orient][k] << " dx "
1431                                     << dx[np[orient][k]] + offsetx[np[orient][k]] << " dy "
1432                                     << dy[np[orient][k]] + offsety[np[orient][k]];
1433 #endif
1434     }
1435   }
1436 #ifdef EDM_ML_DEBUG
1437   edm::LogVerbatim("HGCalGeom") << "I/p: part " << part << " ori " << ori << " zside " << zside << " dX " << delX
1438                                 << " dY " << delY << " xpos " << xpos << " ypos " << ypos << " O/p having " << xy.size()
1439                                 << " points:";
1440   std::ostringstream st1;
1441   for (unsigned int i = 0; i < xy.size(); ++i)
1442     st1 << " [" << i << "] " << xy[i].first << ":" << xy[i].second;
1443   edm::LogVerbatim("HGCalGeom") << st1.str();
1444 #endif
1445   return xy;
1446 }
1447 
1448 std::vector<std::pair<double, double> > HGCalWaferMask::waferXY(const int& part,
1449                                                                 const int& place,
1450                                                                 const double& waferSize,
1451                                                                 const double& offset,
1452                                                                 const double& xpos,
1453                                                                 const double& ypos,
1454                                                                 const bool& v17OrLess,
1455                                                                 const bool& air) {
1456   std::vector<std::pair<double, double> > xy;
1457   // Good for V17 version and uses partial wafer type & placement index
1458 #ifdef EDM_ML_DEBUG
1459   edm::LogVerbatim("HGCalGeom") << "Part " << part << " Placement Index " << place;
1460 #endif
1461   double c22(HGCalTypes::c22), c27(HGCalTypes::c27), c61(HGCalTypes::c61);
1462   double c77(HGCalTypes::c77), c88(HGCalTypes::c88);
1463   double c221(HGCalTypes::c221), c271(HGCalTypes::c271), c611(HGCalTypes::c611);
1464   double c771(HGCalTypes::c771), c881(HGCalTypes::c881);
1465   double offsetAir = 0.0;
1466   if ((part == HGCalTypes::WaferHDTop) && air)
1467     offsetAir = -1 * offsetAir_;
1468   else if ((part == HGCalTypes::WaferHDBottom) && air)
1469     offsetAir = offsetAir_;
1470   if (v17OrLess) {
1471     c22 = HGCalTypes::c22O;
1472     c27 = HGCalTypes::c27O;
1473     c61 = HGCalTypes::c61O;
1474     c77 = HGCalTypes::c77O;
1475     c88 = HGCalTypes::c88O;
1476     c221 = c22;
1477     c271 = c27;
1478     c611 = c61;
1479     c771 = c77;
1480     c881 = c88;
1481   }
1482   /*
1483     The exact contour of partial wafers are obtained by joining points on
1484     the circumference of a full wafer.
1485     Numbering the points along the edges of a hexagonal wafer, starting from
1486     the bottom corner:
1487                                    3
1488                                15     18
1489                              9           8
1490                           19               14
1491                         4                     2 
1492                        16                    23
1493                        10                     7
1494                        20                    13
1495                         5                     1
1496                           17               22
1497                             11           6
1498                                21     12
1499                                    0
1500     Depending on the wafer type and placement index, the corners
1501     are chosen in the variable *np*
1502         The points 24-35 are the same as points 12-23 with different offset
1503   */
1504   double delX = 0.5 * waferSize;
1505   double delY = delX / sin_60_;
1506   double dx[60] = {
1507       HGCalTypes::c00 * delX,
1508       HGCalTypes::c10 * delX,
1509       HGCalTypes::c10 * delX,
1510       HGCalTypes::c00 * delX,
1511       -HGCalTypes::c10 * delX,
1512       -HGCalTypes::c10 * delX,
1513       HGCalTypes::c50 * delX,
1514       HGCalTypes::c10 * delX,
1515       HGCalTypes::c50 * delX,
1516       -HGCalTypes::c50 * delX,
1517       -HGCalTypes::c10 * delX,
1518       -HGCalTypes::c50 * delX,
1519       c221 * delX,
1520       HGCalTypes::c10 * delX,
1521       c771 * delX,
1522       -c221 * delX,
1523       -HGCalTypes::c10 * delX,
1524       -c771 * delX,
1525       c221 * delX,
1526       -c771 * delX,
1527       -HGCalTypes::c10 * delX,
1528       -c221 * delX,
1529       c771 * delX,
1530       HGCalTypes::c10 * delX,
1531       c22 * delX,
1532       HGCalTypes::c10 * delX,
1533       c77 * delX,
1534       -c22 * delX,
1535       -HGCalTypes::c10 * delX,
1536       -c77 * delX,
1537       c22 * delX,
1538       -c77 * delX,
1539       -HGCalTypes::c10 * delX,
1540       -c22 * delX,
1541       c77 * delX,
1542       HGCalTypes::c10 * delX,
1543       HGCalTypes::c00 * delX,
1544       HGCalTypes::c10 * delX,
1545       HGCalTypes::c10 * delX,
1546       HGCalTypes::c00 * delX,
1547       -HGCalTypes::c10 * delX,
1548       -HGCalTypes::c10 * delX,
1549       HGCalTypes::c00 * delX,
1550       HGCalTypes::c10 * delX,
1551       HGCalTypes::c10 * delX,
1552       HGCalTypes::c00 * delX,
1553       -HGCalTypes::c10 * delX,
1554       -HGCalTypes::c10 * delX,
1555       HGCalTypes::c00 * delX,
1556       HGCalTypes::c10 * delX,
1557       HGCalTypes::c10 * delX,
1558       HGCalTypes::c00 * delX,
1559       -HGCalTypes::c10 * delX,
1560       -HGCalTypes::c10 * delX,
1561       HGCalTypes::c00 * delX,
1562       HGCalTypes::c10 * delX,
1563       HGCalTypes::c10 * delX,
1564       HGCalTypes::c00 * delX,
1565       -HGCalTypes::c10 * delX,
1566       -HGCalTypes::c10 * delX,
1567   };
1568   double dy[60] = {
1569       -HGCalTypes::c10 * delY,
1570       -HGCalTypes::c50 * delY,
1571       HGCalTypes::c50 * delY,
1572       HGCalTypes::c10 * delY,
1573       HGCalTypes::c50 * delY,
1574       -HGCalTypes::c50 * delY,
1575       -HGCalTypes::c75 * delY,
1576       HGCalTypes::c00 * delY,
1577       HGCalTypes::c75 * delY,
1578       HGCalTypes::c75 * delY,
1579       HGCalTypes::c00 * delY,
1580       -HGCalTypes::c75 * delY,
1581       -c881 * delY,
1582       -c271 * delY,
1583       c611 * delY,
1584       c881 * delY,
1585       c271 * delY,
1586       -c611 * delY,
1587       c881 * delY,
1588       c611 * delY,
1589       -c271 * delY,
1590       -c881 * delY,
1591       -c611 * delY,
1592       c271 * delY,
1593       -c88 * delY,
1594       -c27 * delY,
1595       c61 * delY,
1596       c88 * delY,
1597       c27 * delY,
1598       -c61 * delY,
1599       c88 * delY,
1600       c61 * delY,
1601       -c27 * delY,
1602       -c88 * delY,
1603       -c61 * delY,
1604       c27 * delY,
1605       -HGCalTypes::c10 * delY,
1606       -HGCalTypes::c50 * delY,
1607       HGCalTypes::c50 * delY,
1608       HGCalTypes::c10 * delY,
1609       HGCalTypes::c50 * delY,
1610       -HGCalTypes::c50 * delY,
1611       -HGCalTypes::c10 * delY,
1612       -HGCalTypes::c50 * delY,
1613       HGCalTypes::c50 * delY,
1614       HGCalTypes::c10 * delY,
1615       HGCalTypes::c50 * delY,
1616       -HGCalTypes::c50 * delY,
1617       -HGCalTypes::c10 * delY,
1618       -HGCalTypes::c50 * delY,
1619       HGCalTypes::c50 * delY,
1620       HGCalTypes::c10 * delY,
1621       HGCalTypes::c50 * delY,
1622       -HGCalTypes::c50 * delY,
1623       -HGCalTypes::c10 * delY,
1624       -HGCalTypes::c50 * delY,
1625       HGCalTypes::c50 * delY,
1626       HGCalTypes::c10 * delY,
1627       HGCalTypes::c50 * delY,
1628       -HGCalTypes::c50 * delY,
1629   };
1630 
1631   double offsetx[60] = {0.0,
1632                         -offset,
1633                         -offset,
1634                         0.0,
1635                         offset,
1636                         offset,
1637                         -offset * cos_60_,
1638                         -offset,
1639                         -offset * cos_60_,
1640                         offset * cos_60_,
1641                         offset,
1642                         offset * cos_60_,
1643                         -offset * cos_60_,
1644                         -offset,
1645                         -offset * cos_60_,
1646                         offset * cos_60_,
1647                         offset,
1648                         offset * cos_60_,
1649                         -offset * cos_60_,
1650                         offset * cos_60_,
1651                         offset,
1652                         offset * cos_60_,
1653                         -offset * cos_60_,
1654                         -offset,
1655                         0.0 + (offsetAir * sin_60_),
1656                         -offset,
1657                         -offset - (offsetAir * sin_60_),
1658                         0.0 - (offsetAir * sin_60_),
1659                         offset,
1660                         offset + (offsetAir * sin_60_),
1661                         0.0 + (offsetAir * sin_60_),
1662                         offset + (offsetAir * sin_60_),
1663                         offset,
1664                         0.0 - (offsetAir * sin_60_),
1665                         -offset - (offsetAir * sin_60_),
1666                         -offset,
1667                         -offset,
1668                         -offset / cos_60_,
1669                         -offset,
1670                         offset,
1671                         offset / cos_60_,
1672                         offset,
1673                         offset,
1674                         -offset,
1675                         -offset / cos_60_,
1676                         -offset,
1677                         offset,
1678                         offset / cos_60_,
1679                         -offset * cos_60_,
1680                         -offset,
1681                         -offset * cos_60_,
1682                         offset * cos_60_,
1683                         offset,
1684                         offset * cos_60_,
1685                         offset * cos_60_,
1686                         -offset * cos_60_,
1687                         -offset,
1688                         -offset * cos_60_,
1689                         offset * cos_60_,
1690                         offset};
1691   double offsety[60] = {offset / sin_60_,
1692                         offset / tan_60_,
1693                         -offset / tan_60_,
1694                         -offset / sin_60_,
1695                         -offset / tan_60_,
1696                         offset / tan_60_,
1697                         offset * sin_60_,
1698                         0.0,
1699                         -offset * sin_60_,
1700                         -offset * sin_60_,
1701                         0.0,
1702                         offset * sin_60_,
1703                         offset * sin_60_,
1704                         0.0,
1705                         -offset * sin_60_,
1706                         -offset * sin_60_,
1707                         0.0,
1708                         offset * sin_60_,
1709                         -offset * sin_60_,
1710                         -offset * sin_60_,
1711                         0.0,
1712                         offset * sin_60_,
1713                         offset * sin_60_,
1714                         0.0,
1715                         (offset / sin_60_) + (offsetAir * cos_60_),
1716                         (offset / tan_60_) + offsetAir,
1717                         (-offset / tan_60_) + (offsetAir * cos_60_),
1718                         (-offset / sin_60_) - (offsetAir * cos_60_),
1719                         (-offset / tan_60_) - offsetAir,
1720                         (offset / tan_60_) - (offsetAir * cos_60_),
1721                         (-offset / sin_60_) - (offsetAir * cos_60_),
1722                         (-offset / tan_60_) + (offsetAir * cos_60_),
1723                         (offset / tan_60_) + offsetAir,
1724                         (offset / sin_60_) + (offsetAir * cos_60_),
1725                         (offset / tan_60_) - (offsetAir * cos_60_),
1726                         (-offset / tan_60_) - offsetAir,
1727                         offset * tan_60_,
1728                         0,
1729                         -offset * tan_60_,
1730                         -offset * tan_60_,
1731                         0,
1732                         offset * tan_60_,
1733                         offset * tan_60_,
1734                         offset * tan_60_,
1735                         0,
1736                         -offset * tan_60_,
1737                         -offset * tan_60_,
1738                         0,
1739                         offset * sin_60_,
1740                         0,
1741                         -offset * sin_60_,
1742                         -offset * sin_60_,
1743                         0,
1744                         offset * sin_60_,
1745                         offset * sin_60_,
1746                         offset * sin_60_,
1747                         0,
1748                         -offset * sin_60_,
1749                         -offset * sin_60_,
1750                         0};
1751 
1752   if (part == HGCalTypes::WaferFull) {
1753     int np[7] = {0, 1, 2, 3, 4, 5, 0};
1754     for (int k = 0; k < 7; ++k) {
1755       xy.push_back(std::make_pair((xpos + dx[np[k]] + offsetx[np[k]]), (ypos + dy[np[k]] + offsety[np[k]])));
1756 #ifdef EDM_ML_DEBUG
1757       edm::LogVerbatim("HGCalGeom") << "WaferFull " << k << " np 7 dx " << (dx[np[k]] + offsetx[np[k]]) << " dy "
1758                                     << (dy[np[k]] + offsety[np[k]]);
1759 #endif
1760     }
1761   } else if (part == HGCalTypes::WaferLDTop) {
1762     int np[12][5] = {{0, 1, 4, 5, 0},
1763                      {1, 2, 5, 0, 1},
1764                      {2, 3, 0, 1, 2},
1765                      {3, 4, 1, 2, 3},
1766                      {4, 5, 2, 3, 4},
1767                      {5, 0, 3, 4, 5},
1768                      {0, 1, 2, 5, 0},
1769                      {5, 0, 1, 4, 5},
1770                      {4, 5, 0, 3, 4},
1771                      {3, 4, 5, 2, 3},
1772                      {2, 3, 4, 1, 2},
1773                      {1, 2, 3, 0, 1}};
1774     for (int k = 0; k < 5; ++k) {
1775       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1776                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1777 #ifdef EDM_ML_DEBUG
1778       edm::LogVerbatim("HGCalGeom") << "WaferLDTop " << k << " np " << np[place][k] << " dx "
1779                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1780                                     << dy[np[place][k]] + offsety[np[place][k]];
1781 #endif
1782     }
1783   } else if (part == HGCalTypes::WaferLDBottom) {
1784     int np[12][5] = {{1, 2, 3, 4, 1},
1785                      {2, 3, 4, 5, 2},
1786                      {3, 4, 5, 0, 3},
1787                      {4, 5, 0, 1, 4},
1788                      {5, 0, 1, 2, 5},
1789                      {0, 1, 2, 3, 0},
1790                      {5, 2, 3, 4, 5},
1791                      {4, 1, 2, 3, 4},
1792                      {3, 0, 1, 2, 3},
1793                      {2, 5, 0, 1, 2},
1794                      {1, 4, 5, 0, 1},
1795                      {0, 3, 4, 5, 0}};
1796     for (int k = 0; k < 5; ++k) {
1797       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1798                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1799 #ifdef EDM_ML_DEBUG
1800       edm::LogVerbatim("HGCalGeom") << "WaferLDBottom " << k << " np " << np[place][k] << " dx "
1801                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1802                                     << dy[np[place][k]] + offsety[np[place][k]];
1803 #endif
1804     }
1805   } else if (part == HGCalTypes::WaferLDLeft) {
1806     int np[12][6] = {{0, 1, 2, 8, 11, 0},
1807                      {1, 2, 3, 9, 6, 1},
1808                      {2, 3, 4, 10, 7, 2},
1809                      {3, 4, 5, 11, 8, 3},
1810                      {4, 5, 0, 6, 9, 4},
1811                      {5, 0, 1, 7, 10, 5},
1812                      {0, 6, 9, 4, 5, 0},
1813                      {5, 11, 8, 3, 4, 5},
1814                      {4, 10, 7, 2, 3, 4},
1815                      {3, 9, 6, 1, 2, 3},
1816                      {2, 8, 11, 0, 1, 2},
1817                      {1, 7, 10, 5, 0, 1}};
1818     for (int k = 0; k < 6; ++k) {
1819       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1820                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1821 #ifdef EDM_ML_DEBUG
1822       edm::LogVerbatim("HGCalGeom") << "WaferLDLeft " << k << " np " << np[place][k] << " dx "
1823                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1824                                     << dy[np[place][k]] + offsety[np[place][k]];
1825 #endif
1826     }
1827   } else if (part == HGCalTypes::WaferLDRight) {
1828     int np[12][6] = {{5, 11, 8, 3, 4, 5},
1829                      {0, 6, 9, 4, 5, 0},
1830                      {1, 7, 10, 5, 0, 1},
1831                      {2, 8, 11, 0, 1, 2},
1832                      {3, 9, 6, 1, 2, 3},
1833                      {4, 10, 7, 2, 3, 4},
1834                      {1, 2, 3, 9, 6, 1},
1835                      {0, 1, 2, 8, 11, 0},
1836                      {5, 0, 1, 7, 10, 5},
1837                      {4, 5, 0, 6, 9, 4},
1838                      {3, 4, 5, 11, 8, 3},
1839                      {2, 3, 4, 10, 7, 2}};
1840     for (int k = 0; k < 6; ++k) {
1841       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1842                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1843 #ifdef EDM_ML_DEBUG
1844       edm::LogVerbatim("HGCalGeom") << "WaferLDRight " << k << " np " << np[place][k] << " dx "
1845                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1846                                     << dy[np[place][k]] + offsety[np[place][k]];
1847 #endif
1848     }
1849   } else if (part == HGCalTypes::WaferLDFive) {
1850     int np[12][6] = {{0, 1, 2, 57, 53, 0},
1851                      {1, 2, 3, 58, 48, 1},
1852                      {2, 3, 4, 59, 49, 2},
1853                      {3, 4, 5, 54, 50, 3},
1854                      {4, 5, 0, 55, 51, 4},
1855                      {5, 0, 1, 56, 52, 5},
1856                      {0, 1, 3, 58, 53, 0},
1857                      {5, 0, 2, 57, 52, 5},
1858                      {4, 5, 1, 56, 51, 4},
1859                      {3, 4, 0, 55, 50, 3},
1860                      {2, 3, 5, 54, 49, 2},
1861                      {1, 2, 4, 59, 48, 1}};
1862     for (int k = 0; k < 6; ++k) {
1863       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1864                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1865 #ifdef EDM_ML_DEBUG
1866       edm::LogVerbatim("HGCalGeom") << "WaferLDFive " << k << " np " << np[place][k] << " dx "
1867                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1868                                     << dy[np[place][k]] + offsety[np[place][k]];
1869 #endif
1870     }
1871   } else if (part == HGCalTypes::WaferLDThree) {
1872     int np[12][4] = {{41, 45, 4, 41},
1873                      {36, 46, 5, 36},
1874                      {37, 47, 0, 37},
1875                      {38, 42, 1, 38},
1876                      {39, 43, 2, 39},
1877                      {40, 44, 3, 40},
1878                      {43, 2, 39, 43},
1879                      {42, 1, 38, 42},
1880                      {47, 0, 37, 47},
1881                      {46, 5, 36, 46},
1882                      {45, 4, 41, 45},
1883                      {44, 3, 40, 44}};
1884     for (int k = 0; k < 4; ++k) {
1885       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1886                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1887 #ifdef EDM_ML_DEBUG
1888       edm::LogVerbatim("HGCalGeom") << "WaferLDThree " << k << " np " << np[place][k] << " dx "
1889                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1890                                     << dy[np[place][k]] + offsety[np[place][k]];
1891 #endif
1892     }
1893   } else if (part == HGCalTypes::WaferHDTop) {
1894     int np[12][5] = {{0, 34, 28, 5, 0},
1895                      {1, 35, 29, 0, 1},
1896                      {2, 30, 24, 1, 2},
1897                      {3, 31, 25, 2, 3},
1898                      {4, 32, 26, 3, 4},
1899                      {5, 33, 27, 4, 5},
1900                      {0, 1, 35, 29, 0},
1901                      {5, 0, 34, 28, 5},
1902                      {4, 5, 33, 27, 4},
1903                      {3, 4, 32, 26, 3},
1904                      {2, 3, 31, 25, 2},
1905                      {1, 2, 30, 24, 1}};
1906     for (int k = 0; k < 5; ++k) {
1907       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1908                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1909 #ifdef EDM_ML_DEBUG
1910       edm::LogVerbatim("HGCalGeom") << "WaferHDTop " << k << " np " << np[place][k] << " dx "
1911                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1912                                     << dy[np[place][k]] + offsety[np[place][k]];
1913 #endif
1914     }
1915   } else if (part == HGCalTypes::WaferHDBottom) {
1916     int np[12][7] = {{1, 2, 3, 4, 28, 34, 1},
1917                      {2, 3, 4, 5, 29, 35, 2},
1918                      {3, 4, 5, 0, 24, 30, 3},
1919                      {4, 5, 0, 1, 25, 31, 4},
1920                      {5, 0, 1, 2, 26, 32, 5},
1921                      {0, 1, 2, 3, 27, 33, 0},
1922                      {5, 29, 35, 2, 3, 4, 5},
1923                      {4, 28, 34, 1, 2, 3, 4},
1924                      {3, 27, 33, 0, 1, 2, 3},
1925                      {2, 26, 32, 5, 0, 1, 2},
1926                      {1, 25, 31, 4, 5, 0, 1},
1927                      {0, 24, 30, 3, 4, 5, 0}};
1928     for (int k = 0; k < 7; ++k) {
1929       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1930                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1931 #ifdef EDM_ML_DEBUG
1932       edm::LogVerbatim("HGCalGeom") << "WaferHDBottom " << k << " np " << np[place][k] << " dx "
1933                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1934                                     << dy[np[place][k]] + offsety[np[place][k]];
1935 #endif
1936     }
1937   } else if (part == HGCalTypes::WaferHDLeft) {
1938     int np[12][6] = {{0, 1, 2, 14, 21, 0},
1939                      {1, 2, 3, 15, 22, 1},
1940                      {2, 3, 4, 16, 23, 2},
1941                      {3, 4, 5, 17, 18, 3},
1942                      {4, 5, 0, 12, 19, 4},
1943                      {5, 0, 1, 13, 20, 5},
1944                      {0, 12, 19, 4, 5, 0},
1945                      {5, 17, 18, 3, 4, 5},
1946                      {4, 16, 23, 2, 3, 4},
1947                      {3, 15, 22, 1, 2, 3},
1948                      {2, 14, 21, 0, 1, 2},
1949                      {1, 13, 20, 5, 0, 1}};
1950     for (int k = 0; k < 6; ++k) {
1951       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1952                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1953 #ifdef EDM_ML_DEBUG
1954       edm::LogVerbatim("HGCalGeom") << "WaferHDLeft " << k << " np " << np[place][k] << " dx "
1955                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1956                                     << dy[np[place][k]] + offsety[np[place][k]];
1957 #endif
1958     }
1959   } else if (part == HGCalTypes::WaferHDRight) {
1960     int np[12][6] = {{5, 17, 18, 3, 4, 5},
1961                      {0, 12, 19, 4, 5, 0},
1962                      {1, 13, 20, 5, 0, 1},
1963                      {2, 14, 21, 0, 1, 2},
1964                      {3, 15, 22, 1, 2, 3},
1965                      {4, 16, 23, 2, 3, 4},
1966                      {1, 2, 3, 15, 22, 1},
1967                      {0, 1, 2, 14, 21, 0},
1968                      {5, 0, 1, 13, 20, 5},
1969                      {4, 5, 0, 12, 19, 4},
1970                      {3, 4, 5, 17, 18, 3},
1971                      {2, 3, 4, 16, 23, 2}};
1972     for (int k = 0; k < 6; ++k) {
1973       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1974                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1975 #ifdef EDM_ML_DEBUG
1976       edm::LogVerbatim("HGCalGeom") << "WaferHDRight " << k << " np " << np[place][k] << " dx "
1977                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
1978                                     << dy[np[place][k]] + offsety[np[place][k]];
1979 #endif
1980     }
1981   } else if (part == HGCalTypes::WaferHDFive) {
1982     int np[12][6] = {{0, 1, 2, 18, 17, 0},
1983                      {1, 2, 3, 19, 12, 1},
1984                      {2, 3, 4, 20, 13, 2},
1985                      {3, 4, 5, 21, 14, 3},
1986                      {4, 5, 0, 22, 15, 4},
1987                      {5, 0, 1, 23, 16, 5},
1988                      {0, 22, 15, 4, 5, 0},
1989                      {5, 21, 14, 3, 4, 5},
1990                      {4, 20, 13, 2, 3, 4},
1991                      {3, 19, 12, 1, 2, 3},
1992                      {2, 18, 17, 0, 1, 2},
1993                      {1, 23, 16, 5, 0, 1}};
1994     for (int k = 0; k < 6; ++k) {
1995       xy.push_back(std::make_pair((xpos + dx[np[place][k]] + offsetx[np[place][k]]),
1996                                   (ypos + dy[np[place][k]] + offsety[np[place][k]])));
1997 #ifdef EDM_ML_DEBUG
1998       edm::LogVerbatim("HGCalGeom") << "WaferHDFive " << k << " np " << np[place][k] << " dx "
1999                                     << dx[np[place][k]] + offsetx[np[place][k]] << " dy "
2000                                     << dy[np[place][k]] + offsety[np[place][k]];
2001 #endif
2002     }
2003   }
2004 #ifdef EDM_ML_DEBUG
2005   edm::LogVerbatim("HGCalGeom") << "I/p: part " << part << " place " << place << " dX " << delX << " dY " << delY
2006                                 << " xpos " << xpos << " ypos " << ypos << " O/p having " << xy.size() << " points:";
2007   std::ostringstream st1;
2008   for (unsigned int i = 0; i < xy.size(); ++i)
2009     st1 << " [" << i << "] " << xy[i].first << ":" << xy[i].second;
2010   edm::LogVerbatim("HGCalGeom") << st1.str();
2011 #endif
2012   return xy;
2013 }
2014 
2015 std::array<double, 4> HGCalWaferMask::maskCut(
2016     const int& part, const int& placement, const double& waferSize, const double& offset, const bool& v17OrLess) {
2017   double c22(HGCalTypes::c22), c271(HGCalTypes::c271);
2018   if (v17OrLess) {
2019     c22 = HGCalTypes::c22O;
2020     c271 = HGCalTypes::c27O;
2021   }
2022   double delX = 0.5 * waferSize;
2023   double delY = 2 * delX / sqrt3_;
2024   double tresh = std::abs(offset / cos_1[placement]);
2025   std::array<double, 4> criterion;
2026   switch (part) {
2027     case (HGCalTypes::WaferLDTop): {
2028       criterion[0] = -tan_1[placement] * sign_1[placement];
2029       criterion[1] = 1.0 * sign_1[placement];
2030       criterion[2] = 0.0;
2031       criterion[3] = tresh;
2032       break;
2033     }
2034     case (HGCalTypes::WaferLDBottom): {
2035       criterion[0] = tan_1[placement] * sign_1[placement];
2036       criterion[1] = -1.0 * sign_1[placement];
2037       criterion[2] = 0.0;
2038       criterion[3] = tresh;
2039       break;
2040     }
2041     case (HGCalTypes::WaferLDLeft): {
2042       criterion[0] = 1.0 * sign_2[placement];
2043       criterion[1] = tan_1[placement] * sign_2[placement];
2044       criterion[2] = 0.0;
2045       criterion[3] = tresh;
2046       break;
2047     }
2048     case (HGCalTypes::WaferLDRight): {
2049       criterion[0] = -1.0 * sign_2[placement];
2050       criterion[1] = -tan_1[placement] * sign_2[placement];
2051       criterion[2] = 0.0;
2052       criterion[3] = tresh;
2053       break;
2054     }
2055     case (HGCalTypes::WaferLDFive): {
2056       criterion[0] = 1 * sign_2[placement];
2057       criterion[1] = tan_1[placement] * sign_2[placement];
2058       criterion[2] = -((HGCalTypes::c50 * delY) / cos_1[placement]) * sign_2[placement];
2059       criterion[3] = tresh;
2060       break;
2061     }
2062     case (HGCalTypes::WaferLDThree): {
2063       criterion[0] = -1 * sign_2[placement];
2064       criterion[1] = -tan_1[placement] * sign_2[placement];
2065       criterion[2] = ((HGCalTypes::c50 * delY) / cos_1[placement]) * sign_2[placement];
2066       criterion[3] = tresh;
2067       break;
2068     }
2069     case (HGCalTypes::WaferHDTop): {
2070       criterion[0] = -tan_1[placement] * sign_1[placement];
2071       criterion[1] = 1 * sign_1[placement];
2072       criterion[2] = ((c22 * delX) / cos_1[placement]) * sign_2[placement];
2073       criterion[3] = tresh;
2074       break;
2075     }
2076     case (HGCalTypes::WaferHDBottom): {
2077       criterion[0] = tan_1[placement] * sign_1[placement];
2078       criterion[1] = -1 * sign_1[placement];
2079       criterion[2] = -((c22 * delX) / cos_1[placement]) * sign_2[placement];
2080       criterion[3] = tresh;
2081       break;
2082     }
2083     case (HGCalTypes::WaferHDLeft): {
2084       criterion[0] = 1.0 * sign_2[placement];
2085       criterion[1] = tan_1[placement] * sign_2[placement];
2086       criterion[2] = ((c271 * delY) / cos_1[placement]) * sign_2[placement];
2087       criterion[3] = tresh;
2088       break;
2089     }
2090     case (HGCalTypes::WaferHDRight): {
2091       criterion[0] = -1.0 * sign_2[placement];
2092       criterion[1] = -tan_1[placement] * sign_2[placement];
2093       criterion[2] = ((c271 * delY) / cos_1[placement]) * sign_2[placement];
2094       criterion[3] = tresh;
2095       break;
2096     }
2097     case (HGCalTypes::WaferHDFive): {
2098       criterion[0] = 1.0 * sign_2[placement];
2099       criterion[1] = tan_1[placement] * sign_2[placement];
2100       criterion[2] = -((c271 * delY) / cos_1[placement]) * sign_2[placement];
2101       criterion[3] = tresh;
2102       break;
2103     }
2104   }
2105   return criterion;
2106 }