Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-22 04:03:05

0001 #include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h"
0002 
0003 /**
0004    * Topology for rectangular pixel detector with BIG pixels.
0005    */
0006 // Modified for the large pixles.
0007 // Danek Kotlinski & Michele Pioppi, 3/06.
0008 // See documentation in the include file.
0009 
0010 //--------------------------------------------------------------------
0011 // PixelTopology interface.
0012 // Transform LocalPoint in cm to measurement in pitch units.
0013 std::pair<float, float> RectangularPixelTopology::pixel(const LocalPoint& p) const {
0014   // check limits
0015   float py = p.y();
0016   float px = p.x();
0017 
0018 #ifdef EDM_ML_DEBUG
0019 #define EPSCM 0
0020 #define EPS 0
0021   // This will catch points which are outside the active sensor area.
0022   // In the digitizer during the early induce_signal phase non valid
0023   // location are passed here. They are cleaned later.
0024 
0025   std::ostringstream debugstr;
0026   debugstr << "py = " << py << ", m_yoffset = " << m_yoffset << "px = " << px << ", m_xoffset = " << m_xoffset << "\n";
0027 
0028   if (py < m_yoffset)  // m_yoffset is negative
0029   {
0030     debugstr << " wrong lp y " << py << " " << m_yoffset << "\n";
0031     py = m_yoffset + EPSCM;  // make sure it is in, add an EPS in cm
0032   }
0033   if (py > -m_yoffset) {
0034     debugstr << " wrong lp y " << py << " " << -m_yoffset << "\n";
0035     py = -m_yoffset - EPSCM;
0036   }
0037   if (px < m_xoffset)  // m_xoffset is negative
0038   {
0039     debugstr << " wrong lp x " << px << " " << m_xoffset << "\n";
0040     px = m_xoffset + EPSCM;
0041   }
0042   if (px > -m_xoffset) {
0043     debugstr << " wrong lp x " << px << " " << -m_xoffset << "\n";
0044     px = -m_xoffset - EPSCM;
0045   }
0046 
0047   if (!debugstr.str().empty())
0048     LogDebug("RectangularPixelTopology") << debugstr.str();
0049 #endif  // EDM_ML_DEBUG
0050 
0051   float newybin = (py - m_yoffset) / m_pitchy;
0052   int iybin = int(newybin);
0053   float fractionY = newybin - iybin;
0054 
0055   // Normalize it all to 1 ROC
0056   int iybin0 = 0;
0057   int numROC = 0;
0058   float mpY = 0.;
0059 
0060   iybin0 = (iybin % 54);  // 0-53
0061   numROC = iybin / 54;    // 0-7
0062 
0063   if (iybin0 == 53) {  // inside big pixel
0064     iybin0 = 51;
0065     fractionY = (fractionY + 1.) / 2.;
0066   } else if (iybin0 == 52) {  // inside big pixel
0067     iybin0 = 51;
0068     fractionY = fractionY / 2.;
0069   } else if (iybin0 > 1) {  // inside normal pixel
0070     iybin0 = iybin0 - 1;
0071   } else if (iybin0 == 1) {  // inside big pixel
0072     iybin0 = 0;
0073     fractionY = (fractionY + 1.) / 2.;
0074   } else if (iybin0 == 0) {  // inside big pixel
0075     iybin0 = 0;
0076     fractionY = fractionY / 2.;
0077   }
0078 
0079   mpY = float(numROC * 52. + iybin0) + fractionY;
0080 
0081 #ifdef EDM_ML_DEBUG
0082 
0083   if (mpY < 0. || mpY >= 416.) {
0084     LogDebug("RectangularPixelTopology") << " bad pix y " << mpY << "\n"
0085                                          << py << " " << m_yoffset << " " << m_pitchy << " " << newybin << " " << iybin
0086                                          << " " << fractionY << " " << iybin0 << " " << numROC;
0087   }
0088 #endif  // EDM_ML_DEBUG
0089 
0090   // In X
0091   float newxbin = (px - m_xoffset) / m_pitchx;
0092   int ixbin = int(newxbin);
0093   float fractionX = newxbin - ixbin;
0094 
0095 #ifdef EDM_ML_DEBUG
0096 
0097   if (ixbin > 161 || ixbin < 0)  //  ixbin < 0 outside range
0098   {
0099     LogDebug("RectangularPixelTopology") << " very bad, newbinx " << ixbin << "\n"
0100                                          << px << " " << m_xoffset << " " << m_pitchx << " " << newxbin << " " << ixbin
0101                                          << " " << fractionX;
0102   }
0103 #endif  // EDM_ML_DEBUG
0104 
0105   if (ixbin > 82) {  // inside normal pixel, ROC 1
0106     ixbin = ixbin - 2;
0107   } else if (ixbin == 82) {  // inside bin pixel
0108     ixbin = 80;
0109     fractionX = (fractionX + 1.) / 2.;
0110   } else if (ixbin == 81) {  // inside big pixel
0111     ixbin = 80;
0112     fractionX = fractionX / 2.;
0113   } else if (ixbin == 80) {  // inside bin pixel, ROC 0
0114     ixbin = 79;
0115     fractionX = (fractionX + 1.) / 2.;
0116   } else if (ixbin == 79) {  // inside big pixel
0117     ixbin = 79;
0118     fractionX = fractionX / 2.;
0119   }
0120 
0121   float mpX = float(ixbin) + fractionX;
0122 
0123 #ifdef EDM_ML_DEBUG
0124 
0125   if (mpX < 0. || mpX >= 160.) {
0126     LogDebug("RectangularPixelTopology") << " bad pix x " << mpX << "\n"
0127                                          << px << " " << m_xoffset << " " << m_pitchx << " " << newxbin << " " << ixbin
0128                                          << " " << fractionX;
0129   }
0130 #endif  // EDM_ML_DEBUG
0131 
0132   return std::pair<float, float>(mpX, mpY);
0133 }
0134 
0135 //----------------------------------------------------------------------
0136 // Topology interface, go from Masurement to Local corrdinates
0137 // pixel coordinates (mp) -> cm (LocalPoint)
0138 LocalPoint RectangularPixelTopology::localPosition(const MeasurementPoint& mp) const {
0139   float mpy = mp.y();  // measurements
0140   float mpx = mp.x();
0141 
0142 #ifdef EDM_ML_DEBUG
0143 #define EPS 0
0144   // check limits
0145   std::ostringstream debugstr;
0146 
0147   if (mpy < 0.) {
0148     debugstr << " wrong mp y, fix " << mpy << " " << 0 << "\n";
0149     mpy = 0.;
0150   }
0151   if (mpy >= m_ncols) {
0152     debugstr << " wrong mp y, fix " << mpy << " " << m_ncols << "\n";
0153     mpy = float(m_ncols) - EPS;  // EPS is a small number
0154   }
0155   if (mpx < 0.) {
0156     debugstr << " wrong mp x, fix " << mpx << " " << 0 << "\n";
0157     mpx = 0.;
0158   }
0159   if (mpx >= m_nrows) {
0160     debugstr << " wrong mp x, fix " << mpx << " " << m_nrows << "\n";
0161     mpx = float(m_nrows) - EPS;  // EPS is a small number
0162   }
0163   if (!debugstr.str().empty())
0164     LogDebug("RectangularPixelTopology") << debugstr.str();
0165 #endif  // EDM_ML_DEBUG
0166 
0167   float lpY = localY(mpy);
0168   float lpX = localX(mpx);
0169 
0170   // Return it as a LocalPoint
0171   return LocalPoint(lpX, lpY);
0172 }
0173 
0174 //--------------------------------------------------------------------
0175 //
0176 // measuremet to local transformation for X coordinate
0177 // X coordinate is in the ROC row number direction
0178 float RectangularPixelTopology::localX(const float mpx) const {
0179   int binoffx = int(mpx);                  // truncate to int
0180   float fractionX = mpx - float(binoffx);  // find the fraction
0181   float local_pitchx = m_pitchx;           // defaultpitch
0182 
0183   if (binoffx > 80) {  // ROC 1 - handles x on edge cluster
0184     binoffx = binoffx + 2;
0185   } else if (binoffx == 80) {  // ROC 1
0186     binoffx = binoffx + 1;
0187     local_pitchx *= 2;
0188   } else if (binoffx == 79) {  // ROC 0
0189     binoffx = binoffx + 0;
0190     local_pitchx *= 2;
0191   }
0192   // else if (binoffx>=0) {       // ROC 0
0193   //  binoffx=binoffx+0;
0194   // }
0195 
0196 #ifdef EDM_ML_DEBUG
0197   if (binoffx < 0)  // too small
0198     LogDebug("RectangularPixelTopology") << " very bad, binx " << binoffx << "\n"
0199                                          << mpx << " " << binoffx << " " << fractionX << " " << local_pitchx << " "
0200                                          << m_xoffset;
0201 #endif
0202 
0203   // The final position in local coordinates
0204   float lpX = float(binoffx * m_pitchx) + fractionX * local_pitchx + m_xoffset;
0205 
0206 #ifdef EDM_ML_DEBUG
0207 
0208   if (lpX < m_xoffset || lpX > (-m_xoffset)) {
0209     LogDebug("RectangularPixelTopology") << " bad lp x " << lpX << "\n"
0210                                          << mpx << " " << binoffx << " " << fractionX << " " << local_pitchx << " "
0211                                          << m_xoffset;
0212   }
0213 #endif  // EDM_ML_DEBUG
0214 
0215   return lpX;
0216 }
0217 
0218 // measuremet to local transformation for Y coordinate
0219 // Y is in the ROC column number direction
0220 float RectangularPixelTopology::localY(const float mpy) const {
0221   int binoffy = int(mpy);                  // truncate to int
0222   float fractionY = mpy - float(binoffy);  // find the fraction
0223   float local_pitchy = m_pitchy;           // defaultpitch
0224 
0225   constexpr int bigYIndeces[]{0, 51, 52, 103, 104, 155, 156, 207, 208, 259, 260, 311, 312, 363, 364, 415, 416, 511};
0226   auto const j = std::lower_bound(std::begin(bigYIndeces), std::end(bigYIndeces), binoffy);
0227   if (*j == binoffy)
0228     local_pitchy *= 2;
0229   binoffy += (j - bigYIndeces);
0230 
0231   // The final position in local coordinates
0232   float lpY = float(binoffy * m_pitchy) + fractionY * local_pitchy + m_yoffset;
0233 
0234 #ifdef EDM_ML_DEBUG
0235 
0236   if (lpY < m_yoffset || lpY > (-m_yoffset)) {
0237     LogDebug("RectangularPixelTopology") << " bad lp y " << lpY << "\n"
0238                                          << mpy << " " << binoffy << " " << fractionY << " " << local_pitchy << " "
0239                                          << m_yoffset;
0240   }
0241 #endif  // EDM_ML_DEBUG
0242 
0243   return lpY;
0244 }
0245 
0246 ///////////////////////////////////////////////////////////////////
0247 // Get hit errors in LocalPoint coordinates (cm)
0248 LocalError RectangularPixelTopology::localError(const MeasurementPoint& mp, const MeasurementError& me) const {
0249   float pitchy = m_pitchy;
0250   int binoffy = int(mp.y());
0251   if (isItBigPixelInY(binoffy))
0252     pitchy = 2. * m_pitchy;
0253 
0254   float pitchx = m_pitchx;
0255   int binoffx = int(mp.x());
0256   if (isItBigPixelInX(binoffx))
0257     pitchx = 2. * m_pitchx;
0258 
0259   return LocalError(me.uu() * float(pitchx * pitchx), 0, me.vv() * float(pitchy * pitchy));
0260 }
0261 
0262 /////////////////////////////////////////////////////////////////////
0263 // Get errors in pixel pitch units.
0264 MeasurementError RectangularPixelTopology::measurementError(const LocalPoint& lp, const LocalError& le) const {
0265   float pitchy = m_pitchy;
0266   float pitchx = m_pitchx;
0267 
0268   int iybin = int((lp.y() - m_yoffset) / m_pitchy);  //get bin for equal picth
0269   int iybin0 = iybin % 54;                           //This is just to avoid many ifs by using the periodicy
0270   //quasi bins 0,1,52,53 fall into larger pixels
0271   if ((iybin0 <= 1) | (iybin0 >= 52))
0272     pitchy = 2.f * m_pitchy;
0273 
0274   int ixbin = int((lp.x() - m_xoffset) / m_pitchx);  //get bin for equal pitch
0275   //quasi bins 79,80,81,82 fall into the 2 larger pixels
0276   if ((ixbin >= 79) & (ixbin <= 82))
0277     pitchx = 2.f * m_pitchx;
0278 
0279   return MeasurementError(le.xx() / float(pitchx * pitchx), 0, le.yy() / float(pitchy * pitchy));
0280 }