PixelIndices

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
#ifndef TP_PIXELINDICES_H
#define TP_PIXELINDICES_H

#include <iostream>

/**
 * Numbering of the pixels inside the readout chip (ROC).
 * There is a column index and a row index.
 * In the barrel the row index is in the global rfi direction (local X) and
 * the column index is in the global z (local Y) direction.
 * In the endcaps the row index is in the global r direction (local X) and
 * the column index in the gloabl rfi (local Y) direction.
 * The defaults are specific to 100*150 micron pixels.
 * 
 * Some methods are declared as static and can be used without class 
 * instantiation. Others need the construstor to setup the Module size
 * parameters. These parameters are only used for error checking.
 * d.k. 10/2005
 */

namespace {
  // A few constants just for error checking
  // The maximum number of ROCs in the X (row) direction per sensor.
  const int maxROCsInX = 2;  //
  // The maximum number of ROCs in the Y (column) direction per sensor.
  const int maxROCsInY = 8;  //
  // The nominal number of double columns per ROC is 26.
  const int DColsPerROC = 26;
  // Default ROC size
  const int ROCSizeInX = 80;  // ROC row size in pixels
  const int ROCSizeInY = 52;  // ROC col size in pixels
  // Default DET barrel size
  const int defaultDetSizeInX = 160;  // Det barrel row size in pixels
  const int defaultDetSizeInY = 416;  // Det barrel col size in pixels

  // Check the limits
  const bool TP_CHECK_LIMITS = true;
}  // namespace

class PixelIndices {
public:
  //*********************************************************************
  // Constructor with the ROC size fixed to the default.
  PixelIndices(const int colsInDet, const int rowsInDet) : theColsInDet(colsInDet), theRowsInDet(rowsInDet) {
    theChipsInX = theRowsInDet / ROCSizeInX;  // number of ROCs in X
    theChipsInY = theColsInDet / ROCSizeInY;  // number of ROCs in Y

    if (TP_CHECK_LIMITS) {
      if (theChipsInX < 1 || theChipsInX > maxROCsInX)
        std::cout << " PixelIndices: Error in ROCsInX " << theChipsInX << " " << theRowsInDet << " " << ROCSizeInX
                  << std::endl;
      if (theChipsInY < 1 || theChipsInY > maxROCsInY)
        std::cout << " PixelIndices: Error in ROCsInY " << theChipsInY << " " << theColsInDet << " " << ROCSizeInY
                  << std::endl;
    }
  }
  //************************************************************************
  ~PixelIndices() {}
  //***********************************************************************

  inline int numberOfROCsInX(void) { return theChipsInX; }
  inline int numberOfROCsInY(void) { return theChipsInY; }

  //***********************************************************************

  void print(void) const {
    std::cout << " Pixel det with " << theChipsInX << " chips in x and " << theChipsInY << " in y " << std::endl;
    std::cout << " Pixel rows " << theRowsInDet << " and columns " << theColsInDet << std::endl;
    std::cout << " Rows in one chip " << ROCSizeInX << " and columns " << ROCSizeInY << std::endl;
    std::cout << " Double columns per ROC " << DColsPerROC << std::endl;
  }

  //********************************************************************
  // Convert dcol & pix indices to ROC col and row
  // Decoding from "Weber" pixel addresses to rows for PSI46
  // dcol = 0 - 25
  // pix = 2 - 161, zigzag pattern.
  // colAdd = 0-51   ! col&row start from 0
  // rowAdd = 0-79
  inline static int convertDcolToCol(const int dcol, const int pix, int& colROC, int& rowROC) {
    if (TP_CHECK_LIMITS) {
      if (dcol < 0 || dcol >= DColsPerROC || pix < 2 || pix > 161) {
        std::cout << "PixelIndices: wrong dcol or pix " << dcol << " " << pix << std::endl;
        rowROC = -1;  // dummy row Address
        colROC = -1;  // dummy col Address
        return -1;    // Signal error
      }
    }

    // First find if we are in the first or 2nd col of a dcol.
    int colEvenOdd = pix % 2;  // module(2), 0-1st sol, 1-2nd col.
    // Transform
    colROC = dcol * 2 + colEvenOdd;   // col address, starts from 0
    rowROC = abs(int(pix / 2) - 80);  // row addres, starts from 0

    if (TP_CHECK_LIMITS) {
      if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
        std::cout << "PixelIndices: wrong col or row " << colROC << " " << rowROC << " " << dcol << " " << pix
                  << std::endl;
        rowROC = -1;  // dummy row Address
        colROC = -1;  // dummy col Address
        return -1;
      }
    }
    return 0;
  }

  //********************************************************************
  // colROC, rowROC are coordinates in the ROC frame, for ROC=rocId
  // (Start from 0).
  // cols, row are coordinates in the module frame, start from 0.
  // row is X, col is Y.
  // At the moment this works only for modules read with a single TBM.
  int transformToModule(const int colROC, const int rowROC, const int rocId, int& col, int& row) const {
    if (TP_CHECK_LIMITS) {
      if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
        std::cout << "PixelIndices: wrong index " << colROC << " " << rowROC << std::endl;
        return -1;
      }
    }

    // The transformation depends on the ROC-ID
    if (rocId >= 0 && rocId < 8) {
      row = 159 - rowROC;
      //col = rocId*52 + colROC;
      col = (8 - rocId) * ROCSizeInY - colROC - 1;
    } else if (rocId >= 8 && rocId < 16) {
      row = rowROC;
      //col = (16-rocId)*52 - colROC - 1;
      col = (rocId - 8) * ROCSizeInY + colROC;
    } else {
      std::cout << "PixelIndices: wrong ROC ID " << rocId << std::endl;
      return -1;
    }
    if (TP_CHECK_LIMITS) {
      if (col < 0 || col >= (ROCSizeInY * theChipsInY) || row < 0 || row >= (ROCSizeInX * theChipsInX)) {
        std::cout << "PixelIndices: wrong index " << col << " " << row << std::endl;
        return -1;
      }
    }

    return 0;
  }
  //**************************************************************************
  // Transform from the module indixes to the ROC indices.
  // col, row - indices in the Module
  // rocId - roc index
  // colROC, rowROC - indices in the ROC frame.
  int transformToROC(const int col, const int row, int& rocId, int& colROC, int& rowROC) const {
    if (TP_CHECK_LIMITS) {
      if (col < 0 || col >= (ROCSizeInY * theChipsInY) || row < 0 || row >= (ROCSizeInX * theChipsInX)) {
        std::cout << "PixelIndices: wrong index 3 " << std::endl;
        return -1;
      }
    }

    // Get the 2d ROC coordinate
    int chipX = row / ROCSizeInX;  // row index of the chip 0-1
    int chipY = col / ROCSizeInY;  // col index of the chip 0-7

    // Get the ROC id from the 2D index
    rocId = rocIndex(chipX, chipY);
    if (TP_CHECK_LIMITS && (rocId < 0 || rocId >= 16)) {
      std::cout << "PixelIndices: wrong roc index " << rocId << std::endl;
      return -1;
    }
    // get the local ROC coordinates
    rowROC = (row % ROCSizeInX);  // row in chip
    colROC = (col % ROCSizeInY);  // col in chip

    if (rocId < 8) {  // For lower 8 ROCs the coordinates are reversed
      colROC = 51 - colROC;
      rowROC = 79 - rowROC;
    }

    if (TP_CHECK_LIMITS) {
      if (colROC < 0 || colROC >= ROCSizeInY || rowROC < 0 || rowROC >= ROCSizeInX) {
        std::cout << "PixelIndices: wrong index " << colROC << " " << rowROC << std::endl;
        return -1;
      }
    }

    return 0;
  }
  //***********************************************************************
  // Calculate a single number ROC index from the 2 ROC indices (coordinates)
  // chipX and chipY.
  // Goes from 0 to 15.
  inline static int rocIndex(const int chipX, const int chipY) {
    int rocId = -1;
    if (TP_CHECK_LIMITS) {
      if (chipX < 0 || chipX >= 2 || chipY < 0 || chipY >= 8) {
        std::cout << "PixelChipIndices: wrong index " << chipX << " " << chipY << std::endl;
        return -1;
      }
    }
    if (chipX == 0)
      rocId = chipY + 8;  // should be 8-15
    else if (chipX == 1)
      rocId = 7 - chipY;  // should be 0-7

    if (TP_CHECK_LIMITS) {
      if (rocId < 0 || rocId >= (maxROCsInX * maxROCsInY)) {
        std::cout << "PixelIndices: Error in ROC index " << rocId << std::endl;
        return -1;
      }
    }
    return rocId;
  }
  //**************************************************************************
  // Calculate the dcol in ROC from the col in ROC frame.
  // dcols go from 0 to 25.
  inline static int DColumn(const int colROC) {
    int dColumnId = (colROC) / 2;  // double column 0-25
    if (TP_CHECK_LIMITS) {
      if (dColumnId < 0 || dColumnId >= 26) {
        std::cout << "PixelIndices: wrong dcol index  " << dColumnId << " " << colROC << std::endl;
        return -1;
      }
    }
    return dColumnId;
  }
  //*************************************************************************
  // Calcuulate the global dcol index within a module
  // Usefull only forin efficiency calculations.
  inline static int DColumnInModule(const int dcol, const int chipIndex) {
    int dcolInMod = dcol + chipIndex * 26;
    return dcolInMod;
  }

  // This is routines to generate ROC channel number
  // Only limited use to store ROC pixel indices for calibration
  inline static int pixelToChannelROC(const int rowROC, const int colROC) {
    return (rowROC << 6) | colROC;  // reserve 6 bit for col ROC index 0-52
  }
  inline static std::pair<int, int> channelToPixelROC(const int chan) {
    int rowROC = (chan >> 6) & 0x7F;  // reserve 7 bits for row ROC index 0-79
    int colROC = chan & 0x3F;
    return std::pair<int, int>(rowROC, colROC);
  }

  //***********************************************************************
private:
  int theColsInDet;  // Columns per Det
  int theRowsInDet;  // Rows per Det
  int theChipsInX;   // Chips in det in X (column direction)
  int theChipsInY;   // Chips in det in Y (row direction)
};

#endif