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 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
#include "CondFormats/PPSObjects/interface/PPSPixelTopology.h"

// Constructors

PPSPixelTopology::PPSPixelTopology()
    : runType_(""),
      pitch_simY_(0.),
      pitch_simX_(0.),
      thickness_(0.),
      no_of_pixels_simX_(0.),
      no_of_pixels_simY_(0.),
      no_of_pixels_(0.),
      simX_width_(0.),
      simY_width_(0.),
      dead_edge_width_(0.),
      active_edge_sigma_(0.),
      phys_active_edge_dist_(0.),
      active_edge_x_(0.),
      active_edge_y_(0.) {}

// Destructor
PPSPixelTopology::~PPSPixelTopology() {}

unsigned short PPSPixelTopology::pixelIndex(PixelInfo pI) const {
  return no_of_pixels_simX_ * pI.pixelColNo() + pI.pixelRowNo();
}

bool PPSPixelTopology::isPixelHit(float xLocalCoordinate, float yLocalCoordinate, bool is3x2 = true) const {
  // check hit fiducial boundaries
  const double xModuleSize = 2 * ((no_of_pixels_simX_ / 2. + 1) * pitch_simX_ + dead_edge_width_);
  if (xLocalCoordinate < -xModuleSize / 2. || xLocalCoordinate > xModuleSize / 2.)
    return false;

  const double yModuleSize = (no_of_pixels_simY_ + 4.) * pitch_simY_ + 2. * dead_edge_width_;
  const double y2x2top = no_of_pixels_simY_ / 6. * pitch_simY_ + dead_edge_width_;
  if (is3x2 && (yLocalCoordinate < -yModuleSize / 2. || yLocalCoordinate > yModuleSize / 2.))
    return false;
  if (!is3x2 && (runType_ == "Run2") && (yLocalCoordinate < -yModuleSize / 2. || yLocalCoordinate > y2x2top))
    return false;
  if (!is3x2 && (runType_ == "Run3") && (yLocalCoordinate < -yModuleSize / 2. || yLocalCoordinate > yModuleSize / 2.))
    return false;

  return true;
}

PPSPixelTopology::PixelInfo PPSPixelTopology::getPixelsInvolved(
    double x, double y, double sigma, double& hit_pos_x, double& hit_pos_y) const {
  //hit position wrt the bottom left corner of the sensor (-8.3, -12.2) in sensor view, rocs behind
  hit_pos_x = x + simX_width_ / 2.;
  hit_pos_y = y + simY_width_ / 2.;
  if (!(hit_pos_x * hit_pos_y > 0))
    throw cms::Exception("PPSPixelTopology") << "pixel out of reference frame";

  double hit_factor = activeEdgeFactor(x, y);

  unsigned int interested_row = row(x);
  unsigned int interested_col = col(y);
  double low_pixel_range_x, high_pixel_range_x, low_pixel_range_y, high_pixel_range_y;
  pixelRange(
      interested_row, interested_col, low_pixel_range_x, high_pixel_range_x, low_pixel_range_y, high_pixel_range_y);

  return PPSPixelTopology::PixelInfo(low_pixel_range_x,
                                     high_pixel_range_x,
                                     low_pixel_range_y,
                                     high_pixel_range_y,
                                     hit_factor,
                                     interested_row,
                                     interested_col);
}

void PPSPixelTopology::pixelRange(
    unsigned int arow, unsigned int acol, double& lower_x, double& higher_x, double& lower_y, double& higher_y) const {
  // x and y in the system  of Geant4 SIMULATION
  arow = (2 * rpixValues::ROCSizeInX - 1) - arow;
  if (arow > (2 * rpixValues::ROCSizeInX - 1) || acol > (3 * rpixValues::ROCSizeInY - 1))
    throw cms::Exception("PPSPixelTopology") << "pixel rows or columns exceeding limits";

  // rows (x segmentation)
  if (arow == 0) {
    lower_x = dead_edge_width_ - phys_active_edge_dist_;  // 50 um
    higher_x = dead_edge_width_ + pitch_simX_;            // 300 um
  } else if (arow <= (rpixValues::ROCSizeInX - 2)) {
    lower_x = dead_edge_width_ + arow * pitch_simX_;
    higher_x = dead_edge_width_ + (arow + 1) * pitch_simX_;
  } else if (arow == (rpixValues::ROCSizeInX - 1)) {
    lower_x = dead_edge_width_ + arow * pitch_simX_;
    higher_x = dead_edge_width_ + (arow + 2) * pitch_simX_;
  } else if (arow == rpixValues::ROCSizeInX) {
    lower_x = dead_edge_width_ + (arow + 1) * pitch_simX_;
    higher_x = dead_edge_width_ + (arow + 3) * pitch_simX_;
  } else if (arow <= (2 * rpixValues::ROCSizeInX - 2)) {
    lower_x = dead_edge_width_ + (arow + 2) * pitch_simX_;
    higher_x = dead_edge_width_ + (arow + 3) * pitch_simX_;
  } else if (arow == (2 * rpixValues::ROCSizeInX - 1)) {
    lower_x = dead_edge_width_ + (arow + 2) * pitch_simX_;
    higher_x = dead_edge_width_ + (arow + 3) * pitch_simX_ + phys_active_edge_dist_;
  }
  // columns (y segmentation)
  if (acol == 0) {
    lower_y = dead_edge_width_ - phys_active_edge_dist_;  // 50 um
    higher_y = dead_edge_width_ + pitch_simY_;            // 350 um
  } else if (acol <= (rpixValues::ROCSizeInY - 2)) {
    lower_y = dead_edge_width_ + acol * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 1) * pitch_simY_;
  } else if (acol == (rpixValues::ROCSizeInY - 1)) {
    lower_y = dead_edge_width_ + acol * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 2) * pitch_simY_;
  } else if (acol == rpixValues::ROCSizeInY) {
    lower_y = dead_edge_width_ + (acol + 1) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 3) * pitch_simY_;
  } else if (acol <= (2 * rpixValues::ROCSizeInY - 2)) {
    lower_y = dead_edge_width_ + (acol + 2) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 3) * pitch_simY_;
  } else if (acol == (2 * rpixValues::ROCSizeInY - 1)) {
    lower_y = dead_edge_width_ + (acol + 2) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 4) * pitch_simY_;
  } else if (acol == (2 * rpixValues::ROCSizeInY)) {
    lower_y = dead_edge_width_ + (acol + 3) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 5) * pitch_simY_;
  } else if (acol <= (3 * rpixValues::ROCSizeInY - 2)) {
    lower_y = dead_edge_width_ + (acol + 4) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 5) * pitch_simY_;
  } else if (acol == (3 * rpixValues::ROCSizeInY - 1)) {
    lower_y = dead_edge_width_ + (acol + 4) * pitch_simY_;
    higher_y = dead_edge_width_ + (acol + 5) * pitch_simY_ + phys_active_edge_dist_;
  }

  lower_x = lower_x - simX_width_ / 2.;
  lower_y = lower_y - simY_width_ / 2.;
  higher_x = higher_x - simX_width_ / 2.;
  higher_y = higher_y - simY_width_ / 2.;
}

double PPSPixelTopology::activeEdgeFactor(double x, double y) const {
  const double inv_sigma = 1. / active_edge_sigma_;  // precaching
  const double topEdgeFactor = std::erf(-distanceFromTopActiveEdge(x, y) * inv_sigma) * 0.5 + 0.5;
  const double bottomEdgeFactor = std::erf(-distanceFromBottomActiveEdge(x, y) * inv_sigma) * 0.5 + 0.5;
  const double rightEdgeFactor = std::erf(-distanceFromRightActiveEdge(x, y) * inv_sigma) * 0.5 + 0.5;
  const double leftEdgeFactor = std::erf(-distanceFromLeftActiveEdge(x, y) * inv_sigma) * 0.5 + 0.5;

  const double aEF = topEdgeFactor * bottomEdgeFactor * rightEdgeFactor * leftEdgeFactor;

  if (aEF > 1.)
    throw cms::Exception("PPSPixelTopology") << " pixel active edge factor > 1";

  return aEF;
}

double PPSPixelTopology::distanceFromTopActiveEdge(double x, double y) const { return (y - active_edge_y_); }
double PPSPixelTopology::distanceFromBottomActiveEdge(double x, double y) const { return (-y - active_edge_y_); }
double PPSPixelTopology::distanceFromRightActiveEdge(double x, double y) const { return (x - active_edge_x_); }
double PPSPixelTopology::distanceFromLeftActiveEdge(double x, double y) const { return (-x - active_edge_x_); }

unsigned int PPSPixelTopology::row(double x) const {
  // x in the G4 simulation system
  x = x + simX_width_ / 2.;

  // now x in the system centered in the bottom left corner of the sensor (sensor view, rocs behind)
  if (x < 0. || x > simX_width_)
    throw cms::Exception("PPSPixelTopology") << " pixel out of reference frame";

  // rows (x segmentation)
  unsigned int arow;
  if (x <= (dead_edge_width_ + pitch_simX_))
    arow = 0;
  else if (x <= (dead_edge_width_ + (rpixValues::ROCSizeInX - 1) * pitch_simX_))
    arow = int((x - dead_edge_width_ - pitch_simX_) / pitch_simX_) + 1;
  else if (x <= (dead_edge_width_ + (rpixValues::ROCSizeInX + 1) * pitch_simX_))
    arow = (rpixValues::ROCSizeInX - 1);
  else if (x <= (dead_edge_width_ + (rpixValues::ROCSizeInX + 3) * pitch_simX_))
    arow = rpixValues::ROCSizeInX;
  else if (x <= (dead_edge_width_ + (2 * rpixValues::ROCSizeInX + 2) * pitch_simX_))
    arow = int((x - dead_edge_width_ - pitch_simX_) / pitch_simX_) - 1;
  else
    arow = (2 * rpixValues::ROCSizeInX - 1);

  arow = (2 * rpixValues::ROCSizeInX - 1) - arow;
  if (arow > (2 * rpixValues::ROCSizeInX - 1))
    throw cms::Exception("PPSPixelTopology") << " pixel row number exceeding limit";

  return arow;
}

unsigned int PPSPixelTopology::col(double y) const {
  // y in the G4 simulation system
  unsigned int column;

  // columns (y segmentation)
  // now y in the system centered in the bottom left corner of the sensor (sensor view, rocs behind)
  y = y + simY_width_ / 2.;
  if (y < 0. || y > simY_width_)
    throw cms::Exception("PPSPixelTopology") << "pixel out of reference frame";

  if (y <= (dead_edge_width_ + pitch_simY_))
    column = 0;
  else if (y <= (dead_edge_width_ + (rpixValues::ROCSizeInY - 1) * pitch_simY_))
    column = int((y - dead_edge_width_ - pitch_simY_) / pitch_simY_) + 1;
  else if (y <= (dead_edge_width_ + (rpixValues::ROCSizeInY + 1) * pitch_simY_))
    column = rpixValues::ROCSizeInY - 1;
  else if (y <= (dead_edge_width_ + (rpixValues::ROCSizeInY + 3) * pitch_simY_))
    column = rpixValues::ROCSizeInY;
  else if (y <= (dead_edge_width_ + (2 * rpixValues::ROCSizeInY + 1) * pitch_simY_))
    column = int((y - dead_edge_width_ - pitch_simY_) / pitch_simY_) - 1;
  else if (y <= (dead_edge_width_ + (2 * rpixValues::ROCSizeInY + 3) * pitch_simY_))
    column = 2 * rpixValues::ROCSizeInY - 1;
  else if (y <= (dead_edge_width_ + (2 * rpixValues::ROCSizeInY + 5) * pitch_simY_))
    column = 2 * rpixValues::ROCSizeInY;
  else if (y <= (dead_edge_width_ + (3 * rpixValues::ROCSizeInY + 3) * pitch_simY_))
    column = int((y - dead_edge_width_ - pitch_simY_) / pitch_simY_) - 3;
  else
    column = (3 * rpixValues::ROCSizeInY - 1);

  return column;
}

void PPSPixelTopology::rowCol2Index(unsigned int arow, unsigned int acol, unsigned int& index) const {
  index = acol * no_of_pixels_simX_ + arow;
}

void PPSPixelTopology::index2RowCol(unsigned int& arow, unsigned int& acol, unsigned int index) const {
  acol = index / no_of_pixels_simX_;
  arow = index % no_of_pixels_simX_;
}

// Getters

std::string PPSPixelTopology::getRunType() const { return runType_; }
double PPSPixelTopology::getPitchSimY() const { return pitch_simY_; }
double PPSPixelTopology::getPitchSimX() const { return pitch_simX_; }
double PPSPixelTopology::getThickness() const { return thickness_; }
unsigned short PPSPixelTopology::getNoPixelsSimX() const { return no_of_pixels_simX_; }
unsigned short PPSPixelTopology::getNoPixelsSimY() const { return no_of_pixels_simY_; }
unsigned short PPSPixelTopology::getNoPixels() const { return no_of_pixels_; }
double PPSPixelTopology::getSimXWidth() const { return simX_width_; }
double PPSPixelTopology::getSimYWidth() const { return simY_width_; }
double PPSPixelTopology::getDeadEdgeWidth() const { return dead_edge_width_; }
double PPSPixelTopology::getActiveEdgeSigma() const { return active_edge_sigma_; }
double PPSPixelTopology::getPhysActiveEdgeDist() const { return phys_active_edge_dist_; }
double PPSPixelTopology::getActiveEdgeX() const { return active_edge_x_; }
double PPSPixelTopology::getActiveEdgeY() const { return active_edge_y_; }

// Setters

void PPSPixelTopology::setRunType(std::string rt) { runType_ = rt; }
void PPSPixelTopology::setPitchSimY(double psy) { pitch_simY_ = psy; }
void PPSPixelTopology::setPitchSimX(double psx) { pitch_simX_ = psx; }
void PPSPixelTopology::setThickness(double tss) { thickness_ = tss; }
void PPSPixelTopology::setNoPixelsSimX(unsigned short npx) { no_of_pixels_simX_ = npx; }
void PPSPixelTopology::setNoPixelsSimY(unsigned short npy) { no_of_pixels_simY_ = npy; }
void PPSPixelTopology::setNoPixels(unsigned short np) { no_of_pixels_ = np; }
void PPSPixelTopology::setSimXWidth(double sxw) { simX_width_ = sxw; }
void PPSPixelTopology::setSimYWidth(double syw) { simY_width_ = syw; }
void PPSPixelTopology::setDeadEdgeWidth(double dew) { dead_edge_width_ = dew; }
void PPSPixelTopology::setActiveEdgeSigma(double aes) { active_edge_sigma_ = aes; }
void PPSPixelTopology::setPhysActiveEdgeDist(double pae) { phys_active_edge_dist_ = pae; }
void PPSPixelTopology::setActiveEdgeX(double aex) { active_edge_x_ = aex; }
void PPSPixelTopology::setActiveEdgeY(double aey) { active_edge_y_ = aey; }

void PPSPixelTopology::printInfo(std::stringstream& s) {
  s << "\n PPS Topology parameters : \n"
    << "\n  runType_  = " << runType_ << "\n  pitch_simY_  = " << pitch_simY_ << "\n   pitch_simX_ = " << pitch_simX_
    << "\n   thickness_ = " << thickness_ << "\n   no_of_pixels_simX_ " << no_of_pixels_simX_
    << "\n   no_of_pixels_simY_ " << no_of_pixels_simY_ << "\n   no_of_pixels_ " << no_of_pixels_ << "\n   simX_width_ "
    << simX_width_ << "\n   simY_width_ " << simY_width_ << "\n   dead_edge_width_ " << dead_edge_width_
    << "\n   active_edge_sigma_ " << active_edge_sigma_ << "\n   phys_active_edge_dist_ " << phys_active_edge_dist_

    << "\n   active_edge_x_ " << active_edge_x_ << "\n   active_edge_y_ " << active_edge_y_

    << std::endl;
}

std::ostream& operator<<(std::ostream& os, PPSPixelTopology info) {
  std::stringstream ss;
  info.printInfo(ss);
  os << ss.str();
  return os;
}