Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:02:28

0001 #ifndef CTPPS_PIXELINDICES_H
0002 #define CTPPS_PIXELINDICES_H
0003 
0004 #include <iostream>
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 /**
0007  * Numbering of the pixels inside the readout chip (ROC).
0008  * There is a column index and a row index.
0009  * In the barrel the row index is in the global rfi direction (local X) and
0010  * the column index is in the global z (local Y) direction.
0011  * In the endcaps the row index is in the global r direction (local X) and
0012  * the column index in the gloabl rfi (local Y) direction.
0013  *
0014  * In CTPPS  the row index is in the global y direction (local X) and
0015  * the column index is in the global x (local Y) direction.
0016  * The defaults are specific to 100*150 micron pixels.
0017  * 
0018  * Some methods are declared as static and can be used without class 
0019  * instantiation. Others need the construstor to setup the Module size
0020  * parameters. These parameters are only used for error checking.
0021  * d.k. 10/2005
0022  */
0023 
0024 /*
0025 
0026   sensor side = bump bonding side = wire bonding side
0027 
0028 
0029   ^   sim y
0030   |
0031   |
0032   |
0033   0-----------------------------------
0034   |                |                  |
0035   |        2      |       3         |
0036   |                |                  0
0037   --------------------------------------
0038   0-----------------------------------
0039   |                |                  |
0040   |       1       |-------4---------|--------------> sim x        
0041   |                |                  0
0042   --------------------------------------
0043   0-----------------------------------   ^
0044   |                |                  |    | det cols 
0045   |      0        |        5        |    |
0046   |                |                  0   |
0047   --------------------------------------   |
0048   |
0049   <------------------------------------------ 0,0
0050   det rows x
0051   0  beam
0052 
0053 */
0054 
0055 namespace rpixValues {
0056 
0057   // The maximum number of ROCs in the X (row) direction per sensor.
0058   constexpr int maxROCsInX = 2;  //
0059   // The maximum number of ROCs in the Y (column) direction per sensor.
0060   constexpr int maxROCsInY = 3;  //
0061   // The nominal number of double columns per ROC is 26.
0062   constexpr int DColsPerROC = 26;
0063   // Default ROC size
0064   constexpr int ROCSizeInX = 80;  // ROC row size in pixels
0065   constexpr int ROCSizeInY = 52;  // ROC col size in pixels
0066   // Default DET barrel size
0067   constexpr int defaultDetSizeInX = 160;  // Det row size in pixels (2 ROCs)
0068   constexpr int defaultDetSizeInY = 156;  //  Det col size in pixels (3 ROCs)
0069 
0070   // Check the limits
0071   constexpr bool CTPPS_CHECK_LIMITS = true;
0072 }  // namespace rpixValues
0073 
0074 class CTPPSPixelIndices {
0075 public:
0076   //*********************************************************************
0077   // Constructor with the ROC size fixed to the default.
0078 
0079   CTPPSPixelIndices() : theColsInDet(rpixValues::defaultDetSizeInY), theRowsInDet(rpixValues::defaultDetSizeInX) {
0080     theChipsInX = theRowsInDet / rpixValues::ROCSizeInX;  // number of ROCs in X
0081     theChipsInY = theColsInDet / rpixValues::ROCSizeInY;  // number of ROCs in Y
0082 
0083     if (rpixValues::CTPPS_CHECK_LIMITS) {
0084       if (theChipsInX < 1 || theChipsInX > rpixValues::maxROCsInX)
0085         edm::LogError("RPix") << " CTPPSPixelIndices: Error in ROCsInX " << theChipsInX << " " << theRowsInDet << " "
0086                               << rpixValues::ROCSizeInX;
0087       if (theChipsInY < 1 || theChipsInY > rpixValues::maxROCsInY)
0088         edm::LogError("RPix") << " CTPPSPixelIndices: Error in ROCsInY " << theChipsInY << " " << theColsInDet << " "
0089                               << rpixValues::ROCSizeInY;
0090     }
0091   }
0092 
0093   CTPPSPixelIndices(const int colsInDet, const int rowsInDet) : theColsInDet(colsInDet), theRowsInDet(rowsInDet) {
0094     theChipsInX = theRowsInDet / rpixValues::ROCSizeInX;  // number of ROCs in X
0095     theChipsInY = theColsInDet / rpixValues::ROCSizeInY;  // number of ROCs in Y
0096 
0097     if (rpixValues::CTPPS_CHECK_LIMITS) {
0098       if (theChipsInX < 1 || theChipsInX > rpixValues::maxROCsInX)
0099         edm::LogError("RPix") << " CTPPSPixelIndices: Error in ROCsInX " << theChipsInX << " " << theRowsInDet << " "
0100                               << rpixValues::ROCSizeInX;
0101       if (theChipsInY < 1 || theChipsInY > rpixValues::maxROCsInY)
0102         edm::LogError("RPix") << " CTPPSPixelIndices: Error in ROCsInY " << theChipsInY << " " << theColsInDet << " "
0103                               << rpixValues::ROCSizeInY;
0104     }
0105   }
0106 
0107   ~CTPPSPixelIndices() {}
0108 
0109   inline int numberOfROCsInX(void) { return theChipsInX; }
0110   inline int numberOfROCsInY(void) { return theChipsInY; }
0111 
0112   void print(void) const {
0113     edm::LogInfo("RPix") << " Pixel det with " << theChipsInX << " chips in x and " << theChipsInY << " in y ";
0114     edm::LogInfo("RPix") << " Pixel rows " << theRowsInDet << " and columns " << theColsInDet;
0115     edm::LogInfo("RPix") << " Rows in one chip " << rpixValues::ROCSizeInX << " and columns " << rpixValues::ROCSizeInY;
0116     edm::LogInfo("RPix") << " Double columns per ROC " << rpixValues::DColsPerROC;
0117   }
0118 
0119   //********************************************************************
0120   // Convert dcol & pix indices to ROC col and row
0121   // Decoding from "Weber" pixel addresses to rows for PSI46
0122   // dcol = 0 - 25
0123   // pix = 2 - 161, zigzag pattern.
0124   // colAdd = 0-51   ! col&row start from 0
0125   // rowAdd = 0-79
0126   inline static int convertDcolToCol(const int dcol, const int pix, int& colROC, int& rowROC) {
0127     if (rpixValues::CTPPS_CHECK_LIMITS) {
0128       if (dcol < 0 || dcol >= rpixValues::DColsPerROC || pix < 2 || pix > 161) {
0129         edm::LogError("RPix") << "CTPPSPixelIndices: wrong dcol or pix " << dcol << " " << pix;
0130         rowROC = -1;  // dummy row Address
0131         colROC = -1;  // dummy col Address
0132         return -1;    // Signal error
0133       }
0134     }
0135 
0136     // First find if we are in the first or 2nd col of a dcol.
0137     int colEvenOdd = pix % 2;  // module(2), 0-1st sol, 1-2nd col.
0138     // Transform
0139     colROC = dcol * 2 + colEvenOdd;   // col address, starts from 0
0140     rowROC = abs(int(pix / 2) - 80);  // row addres, starts from 0
0141 
0142     if (rpixValues::CTPPS_CHECK_LIMITS) {
0143       if (colROC < 0 || colROC >= rpixValues::ROCSizeInY || rowROC < 0 || rowROC >= rpixValues::ROCSizeInX) {
0144         edm::LogError("RPix") << "CTPPSPixelIndices: wrong col or row " << colROC << " " << rowROC << " " << dcol << " "
0145                               << pix;
0146         rowROC = -1;  // dummy row Address
0147         colROC = -1;  // dummy col Address
0148         return -1;
0149       }
0150     }
0151     return 0;
0152   }
0153 
0154   //********************************************************************
0155   // colROC, rowROC are coordinates in the ROC frame, for ROC=rocId
0156   // (Start from 0).
0157   // cols, row are coordinates in the module frame, start from 0.
0158   // row is X, col is Y.
0159   // At the moment this works only for modules read with a single TBM.
0160   int transformToModule(const int colROC, const int rowROC, const int rocId, int& col, int& row) const {
0161     if (rpixValues::CTPPS_CHECK_LIMITS) {
0162       if (colROC < 0 || colROC >= rpixValues::ROCSizeInY || rowROC < 0 || rowROC >= rpixValues::ROCSizeInX) {
0163         edm::LogError("RPix") << "CTPPSPixelIndices: wrong index " << colROC << " " << rowROC;
0164         return -1;
0165       }
0166     }
0167 
0168     // The transformation depends on the ROC-ID
0169     if (rocId >= 0 && rocId < 3) {
0170       row = 159 - rowROC;
0171 
0172       col = (rocId + 1) * rpixValues::ROCSizeInY - colROC - 1;
0173     } else if (rocId >= 3 && rocId < 6) {
0174       row = rowROC;
0175 
0176       col = (5 - rocId) * rpixValues::ROCSizeInY + colROC;
0177     } else {
0178       edm::LogError("RPix") << "CTPPSPixelIndices: wrong ROC ID " << rocId;
0179       return -1;
0180     }
0181     if (rpixValues::CTPPS_CHECK_LIMITS) {
0182       if (col < 0 || col >= (rpixValues::ROCSizeInY * theChipsInY) || row < 0 ||
0183           row >= (rpixValues::ROCSizeInX * theChipsInX)) {
0184         edm::LogError("RPix") << "CTPPSPixelIndices: wrong index " << col << " " << row;
0185         return -1;
0186       }
0187     }
0188 
0189     return 0;
0190   }
0191   //**************************************************************************
0192   // Transform from the module indixes to the ROC indices.
0193   // col, row - indices in the Module
0194   // rocId - roc index
0195   // colROC, rowROC - indices in the ROC frame.
0196   int transformToROC(const int col, const int row, int& rocId, int& colROC, int& rowROC) const {
0197     if (rpixValues::CTPPS_CHECK_LIMITS) {
0198       if (col < 0 || col >= (rpixValues::ROCSizeInY * theChipsInY) || row < 0 ||
0199           row >= (rpixValues::ROCSizeInX * theChipsInX)) {
0200         edm::LogError("RPix") << "CTPPSPixelIndices: wrong index 3 ";
0201         return -1;
0202       }
0203     }
0204 
0205     // Get the 2d ROC coordinate
0206     int chipX = row / rpixValues::ROCSizeInX;  // row index of the chip 0-1
0207     int chipY = col / rpixValues::ROCSizeInY;  // col index of the chip 0-2
0208 
0209     // Get the ROC id from the 2D index
0210     rocId = rocIndex(chipX, chipY);
0211     if (rpixValues::CTPPS_CHECK_LIMITS && (rocId < 0 || rocId >= 6)) {
0212       edm::LogError("RPix") << "CTPPSPixelIndices: wrong roc index " << rocId;
0213       return -1;
0214     }
0215     // get the local ROC coordinates
0216     rowROC = (row % rpixValues::ROCSizeInX);  // row in chip
0217     colROC = (col % rpixValues::ROCSizeInY);  // col in chip
0218 
0219     if (rocId < 3) {
0220       colROC = 51 - colROC;
0221       rowROC = 79 - rowROC;
0222     }
0223 
0224     if (rpixValues::CTPPS_CHECK_LIMITS) {
0225       if (colROC < 0 || colROC >= rpixValues::ROCSizeInY || rowROC < 0 || rowROC >= rpixValues::ROCSizeInX) {
0226         edm::LogError("RPix") << "CTPPSPixelIndices: wrong index " << colROC << " " << rowROC;
0227         return -1;
0228       }
0229     }
0230 
0231     return 0;
0232   }
0233 
0234   // get ROC ID from module row and column
0235 
0236   int getROCId(const int col, const int row) const {
0237     int rocId = -1;
0238 
0239     if (rpixValues::CTPPS_CHECK_LIMITS) {
0240       if (col < 0 || col >= (rpixValues::ROCSizeInY * theChipsInY) || row < 0 ||
0241           row >= (rpixValues::ROCSizeInX * theChipsInX)) {
0242         edm::LogError("RPix") << "CTPPSPixelIndices: wrong index ";
0243         return -1;
0244       }
0245     }
0246 
0247     // Get the 2d ROC coordinate
0248     int chipX = row / rpixValues::ROCSizeInX;  // row index of the chip 0-1
0249     int chipY = col / rpixValues::ROCSizeInY;  // col index of the chip 0-2
0250 
0251     // Get the ROC id from the 2D index
0252     rocId = rocIndex(chipX, chipY);
0253     if (rpixValues::CTPPS_CHECK_LIMITS && (rocId < 0 || rocId >= 6)) {
0254       edm::LogError("RPix") << "CTPPSPixelIndices: wrong roc index " << rocId;
0255       return -1;
0256     }
0257 
0258     return rocId;
0259   }
0260 
0261   // is pixel on the edge?
0262   bool isOnEdge(const int col, const int row) const {
0263     if (col == 0 || row == 0 || col == (rpixValues::defaultDetSizeInY - 1) ||
0264         row == (rpixValues::defaultDetSizeInX - 1))
0265       return true;
0266     return false;
0267   }
0268 
0269   //***********************************************************************
0270   // Calculate a single number ROC index from the 2 ROC indices (coordinates)
0271   // chipX and chipY.
0272   // Goes from 0 to 5.
0273   inline static int rocIndex(const int chipX, const int chipY) {
0274     int rocId = -1;
0275     if (rpixValues::CTPPS_CHECK_LIMITS) {
0276       if (chipX < 0 || chipX >= 2 || chipY < 0 || chipY >= 3) {
0277         edm::LogError("RPix") << "PixelChipIndices: wrong index " << chipX << " " << chipY;
0278         return -1;
0279       }
0280     }
0281     if (chipX == 0)
0282       rocId = 5 - chipY;  // should be 3-5
0283     else if (chipX == 1)
0284       rocId = chipY;  // should be 0-2
0285 
0286     if (rpixValues::CTPPS_CHECK_LIMITS) {
0287       if (rocId < 0 || rocId >= (rpixValues::maxROCsInX * rpixValues::maxROCsInY)) {
0288         edm::LogError("RPix") << "CTPPSPixelIndices: Error in ROC index " << rocId;
0289         return -1;
0290       }
0291     }
0292     return rocId;
0293   }
0294   //**************************************************************************
0295   // Calculate the dcol in ROC from the col in ROC frame.
0296   // dcols go from 0 to 25.
0297   inline static int DColumn(const int colROC) {
0298     int dColumnId = (colROC) / 2;  // double column 0-25
0299     if (rpixValues::CTPPS_CHECK_LIMITS) {
0300       if (dColumnId < 0 || dColumnId >= 26) {
0301         edm::LogError("RPix") << "CTPPSPixelIndices: wrong dcol index  " << dColumnId << " " << colROC;
0302         return -1;
0303       }
0304     }
0305     return dColumnId;
0306   }
0307   //*************************************************************************
0308   // Calcuulate the global dcol index within a module
0309   // Usefull only forin efficiency calculations.
0310   inline static int DColumnInModule(const int dcol, const int chipIndex) {
0311     int dcolInMod = dcol + chipIndex * 26;
0312     return dcolInMod;
0313   }
0314 
0315   // This is routines to generate ROC channel number
0316   // Only limited use to store ROC pixel indices for calibration
0317   inline static int pixelToChannelROC(const int rowROC, const int colROC) {
0318     return (rowROC << 6) | colROC;  // reserve 6 bit for col ROC index 0-52
0319   }
0320   inline static std::pair<int, int> channelToPixelROC(const int chan) {
0321     int rowROC = (chan >> 6) & 0x7F;  // reserve 7 bits for row ROC index 0-79
0322     int colROC = chan & 0x3F;
0323     return std::pair<int, int>(rowROC, colROC);
0324   }
0325 
0326   inline int getDefaultRowDetSize() const { return rpixValues::defaultDetSizeInX; }
0327   inline int getDefaultColDetSize() const { return rpixValues::defaultDetSizeInY; }
0328 
0329   //***********************************************************************
0330 private:
0331   int theColsInDet;  // Columns per Det
0332   int theRowsInDet;  // Rows per Det
0333   int theChipsInX;   // Chips in det in X (column direction)
0334   int theChipsInY;   // Chips in det in Y (row direction)
0335 };
0336 
0337 #endif