Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef TP_PIXELINDICES_H
0002 #define TP_PIXELINDICES_H
0003 
0004 #include <iostream>
0005 
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  * The defaults are specific to 100*150 micron pixels.
0014  * 
0015  * Some methods are declared as static and can be used without class 
0016  * instantiation. Others need the construstor to setup the Module size
0017  * parameters. These parameters are only used for error checking.
0018  * d.k. 10/2005
0019  */
0020 
0021 namespace {
0022   // A few constants just for error checking
0023   // The maximum number of ROCs in the X (row) direction per sensor.
0024   const int maxROCsInX = 2;  //
0025   // The maximum number of ROCs in the Y (column) direction per sensor.
0026   const int maxROCsInY = 8;  //
0027   // The nominal number of double columns per ROC is 26.
0028   const int DColsPerROC = 26;
0029   // Default ROC size
0030   const int ROCSizeInX = 80;  // ROC row size in pixels
0031   const int ROCSizeInY = 52;  // ROC col size in pixels
0032   // Default DET barrel size
0033   const int defaultDetSizeInX = 160;  // Det barrel row size in pixels
0034   const int defaultDetSizeInY = 416;  // Det barrel col size in pixels
0035 
0036   // Check the limits
0037   const bool TP_CHECK_LIMITS = true;
0038 }  // namespace
0039 
0040 class PixelIndices {
0041 public:
0042   //*********************************************************************
0043   // Constructor with the ROC size fixed to the default.
0044   PixelIndices(const int colsInDet, const int rowsInDet) : theColsInDet(colsInDet), theRowsInDet(rowsInDet) {
0045     theChipsInX = theRowsInDet / ROCSizeInX;  // number of ROCs in X
0046     theChipsInY = theColsInDet / ROCSizeInY;  // number of ROCs in Y
0047 
0048     if (TP_CHECK_LIMITS) {
0049       if (theChipsInX < 1 || theChipsInX > maxROCsInX)
0050         std::cout << " PixelIndices: Error in ROCsInX " << theChipsInX << " " << theRowsInDet << " " << ROCSizeInX
0051                   << std::endl;
0052       if (theChipsInY < 1 || theChipsInY > maxROCsInY)
0053         std::cout << " PixelIndices: Error in ROCsInY " << theChipsInY << " " << theColsInDet << " " << ROCSizeInY
0054                   << std::endl;
0055     }
0056   }
0057   //************************************************************************
0058   ~PixelIndices() {}
0059   //***********************************************************************
0060 
0061   inline int numberOfROCsInX(void) { return theChipsInX; }
0062   inline int numberOfROCsInY(void) { return theChipsInY; }
0063 
0064   //***********************************************************************
0065 
0066   void print(void) const {
0067     std::cout << " Pixel det with " << theChipsInX << " chips in x and " << theChipsInY << " in y " << std::endl;
0068     std::cout << " Pixel rows " << theRowsInDet << " and columns " << theColsInDet << std::endl;
0069     std::cout << " Rows in one chip " << ROCSizeInX << " and columns " << ROCSizeInY << std::endl;
0070     std::cout << " Double columns per ROC " << DColsPerROC << std::endl;
0071   }
0072 
0073   //********************************************************************
0074   // Convert dcol & pix indices to ROC col and row
0075   // Decoding from "Weber" pixel addresses to rows for PSI46
0076   // dcol = 0 - 25
0077   // pix = 2 - 161, zigzag pattern.
0078   // colAdd = 0-51   ! col&row start from 0
0079   // rowAdd = 0-79
0080   inline static int convertDcolToCol(const int dcol, const int pix, int& colROC, int& rowROC) {
0081     if (TP_CHECK_LIMITS) {
0082       if (dcol < 0 || dcol >= DColsPerROC || pix < 2 || pix > 161) {
0083         std::cout << "PixelIndices: wrong dcol or pix " << dcol << " " << pix << std::endl;
0084         rowROC = -1;  // dummy row Address
0085         colROC = -1;  // dummy col Address
0086         return -1;    // Signal error
0087       }
0088     }
0089 
0090     // First find if we are in the first or 2nd col of a dcol.
0091     int colEvenOdd = pix % 2;  // module(2), 0-1st sol, 1-2nd col.
0092     // Transform
0093     colROC = dcol * 2 + colEvenOdd;   // col address, starts from 0
0094     rowROC = abs(int(pix / 2) - 80);  // row addres, starts from 0
0095 
0096     if (TP_CHECK_LIMITS) {
0097       if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
0098         std::cout << "PixelIndices: wrong col or row " << colROC << " " << rowROC << " " << dcol << " " << pix
0099                   << std::endl;
0100         rowROC = -1;  // dummy row Address
0101         colROC = -1;  // dummy col Address
0102         return -1;
0103       }
0104     }
0105     return 0;
0106   }
0107 
0108   //********************************************************************
0109   // colROC, rowROC are coordinates in the ROC frame, for ROC=rocId
0110   // (Start from 0).
0111   // cols, row are coordinates in the module frame, start from 0.
0112   // row is X, col is Y.
0113   // At the moment this works only for modules read with a single TBM.
0114   int transformToModule(const int colROC, const int rowROC, const int rocId, int& col, int& row) const {
0115     if (TP_CHECK_LIMITS) {
0116       if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
0117         std::cout << "PixelIndices: wrong index " << colROC << " " << rowROC << std::endl;
0118         return -1;
0119       }
0120     }
0121 
0122     // The transformation depends on the ROC-ID
0123     if (rocId >= 0 && rocId < 8) {
0124       row = 159 - rowROC;
0125       //col = rocId*52 + colROC;
0126       col = (8 - rocId) * ROCSizeInY - colROC - 1;
0127     } else if (rocId >= 8 && rocId < 16) {
0128       row = rowROC;
0129       //col = (16-rocId)*52 - colROC - 1;
0130       col = (rocId - 8) * ROCSizeInY + colROC;
0131     } else {
0132       std::cout << "PixelIndices: wrong ROC ID " << rocId << std::endl;
0133       return -1;
0134     }
0135     if (TP_CHECK_LIMITS) {
0136       if (col < 0 || col >= (ROCSizeInY * theChipsInY) || row < 0 || row >= (ROCSizeInX * theChipsInX)) {
0137         std::cout << "PixelIndices: wrong index " << col << " " << row << std::endl;
0138         return -1;
0139       }
0140     }
0141 
0142     return 0;
0143   }
0144   //**************************************************************************
0145   // Transform from the module indixes to the ROC indices.
0146   // col, row - indices in the Module
0147   // rocId - roc index
0148   // colROC, rowROC - indices in the ROC frame.
0149   int transformToROC(const int col, const int row, int& rocId, int& colROC, int& rowROC) const {
0150     if (TP_CHECK_LIMITS) {
0151       if (col < 0 || col >= (ROCSizeInY * theChipsInY) || row < 0 || row >= (ROCSizeInX * theChipsInX)) {
0152         std::cout << "PixelIndices: wrong index 3 " << std::endl;
0153         return -1;
0154       }
0155     }
0156 
0157     // Get the 2d ROC coordinate
0158     int chipX = row / ROCSizeInX;  // row index of the chip 0-1
0159     int chipY = col / ROCSizeInY;  // col index of the chip 0-7
0160 
0161     // Get the ROC id from the 2D index
0162     rocId = rocIndex(chipX, chipY);
0163     if (TP_CHECK_LIMITS && (rocId < 0 || rocId >= 16)) {
0164       std::cout << "PixelIndices: wrong roc index " << rocId << std::endl;
0165       return -1;
0166     }
0167     // get the local ROC coordinates
0168     rowROC = (row % ROCSizeInX);  // row in chip
0169     colROC = (col % ROCSizeInY);  // col in chip
0170 
0171     if (rocId < 8) {  // For lower 8 ROCs the coordinates are reversed
0172       colROC = 51 - colROC;
0173       rowROC = 79 - rowROC;
0174     }
0175 
0176     if (TP_CHECK_LIMITS) {
0177       if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
0178         std::cout << "PixelIndices: wrong index " << colROC << " " << rowROC << std::endl;
0179         return -1;
0180       }
0181     }
0182 
0183     return 0;
0184   }
0185   //***********************************************************************
0186   // Calculate a single number ROC index from the 2 ROC indices (coordinates)
0187   // chipX and chipY.
0188   // Goes from 0 to 15.
0189   inline static int rocIndex(const int chipX, const int chipY) {
0190     int rocId = -1;
0191     if (TP_CHECK_LIMITS) {
0192       if (chipX < 0 || chipX >= 2 || chipY < 0 || chipY >= 8) {
0193         std::cout << "PixelChipIndices: wrong index " << chipX << " " << chipY << std::endl;
0194         return -1;
0195       }
0196     }
0197     if (chipX == 0)
0198       rocId = chipY + 8;  // should be 8-15
0199     else if (chipX == 1)
0200       rocId = 7 - chipY;  // should be 0-7
0201 
0202     if (TP_CHECK_LIMITS) {
0203       if (rocId < 0 || rocId >= (maxROCsInX * maxROCsInY)) {
0204         std::cout << "PixelIndices: Error in ROC index " << rocId << std::endl;
0205         return -1;
0206       }
0207     }
0208     return rocId;
0209   }
0210   //**************************************************************************
0211   // Calculate the dcol in ROC from the col in ROC frame.
0212   // dcols go from 0 to 25.
0213   inline static int DColumn(const int colROC) {
0214     int dColumnId = (colROC) / 2;  // double column 0-25
0215     if (TP_CHECK_LIMITS) {
0216       if (dColumnId < 0 || dColumnId >= 26) {
0217         std::cout << "PixelIndices: wrong dcol index  " << dColumnId << " " << colROC << std::endl;
0218         return -1;
0219       }
0220     }
0221     return dColumnId;
0222   }
0223   //*************************************************************************
0224   // Calcuulate the global dcol index within a module
0225   // Usefull only forin efficiency calculations.
0226   inline static int DColumnInModule(const int dcol, const int chipIndex) {
0227     int dcolInMod = dcol + chipIndex * 26;
0228     return dcolInMod;
0229   }
0230 
0231   // This is routines to generate ROC channel number
0232   // Only limited use to store ROC pixel indices for calibration
0233   inline static int pixelToChannelROC(const int rowROC, const int colROC) {
0234     return (rowROC << 6) | colROC;  // reserve 6 bit for col ROC index 0-52
0235   }
0236   inline static std::pair<int, int> channelToPixelROC(const int chan) {
0237     int rowROC = (chan >> 6) & 0x7F;  // reserve 7 bits for row ROC index 0-79
0238     int colROC = chan & 0x3F;
0239     return std::pair<int, int>(rowROC, colROC);
0240   }
0241 
0242   //***********************************************************************
0243 private:
0244   int theColsInDet;  // Columns per Det
0245   int theRowsInDet;  // Rows per Det
0246   int theChipsInX;   // Chips in det in X (column direction)
0247   int theChipsInY;   // Chips in det in Y (row direction)
0248 };
0249 
0250 #endif