Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:11:25

0001 // -*- C++ -*-
0002 //
0003 // Class:      SiPixelCoordinates
0004 //
0005 // Implementations of the class
0006 //
0007 // Original Author: Janos Karancsi
0008 
0009 #include "DQM/SiPixelPhase1Common/interface/SiPixelCoordinates.h"
0010 
0011 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0012 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0013 #include "DataFormats/TrackerCommon/interface/PixelBarrelName.h"
0014 #include "DataFormats/TrackerCommon/interface/PixelEndcapName.h"
0015 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0016 #include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h"
0017 
0018 #include <boost/range/irange.hpp>
0019 
0020 // _________________________________________________________
0021 //                 Constructors, destructor
0022 SiPixelCoordinates::SiPixelCoordinates() { phase_ = -1; }
0023 
0024 SiPixelCoordinates::SiPixelCoordinates(int phase) : phase_(phase) {}
0025 
0026 SiPixelCoordinates::~SiPixelCoordinates() {}
0027 
0028 // _________________________________________________________
0029 //       init, called in the beginning of each event
0030 void SiPixelCoordinates::init(const TrackerTopology* trackerTopology,
0031                               const TrackerGeometry* trackerGeometry,
0032                               const SiPixelFedCablingMap* siPixelFedCablingMap) {
0033   tTopo_ = trackerTopology;
0034   tGeom_ = trackerGeometry;
0035   cablingMap_ = siPixelFedCablingMap;
0036 
0037   fedid_ = cablingMap_->det2fedMap();
0038 
0039   // If not specified, determine from the geometry
0040   if (phase_ == -1) {
0041     if (tGeom_->isThere(GeomDetEnumerators::PixelBarrel) && tGeom_->isThere(GeomDetEnumerators::PixelEndcap))
0042       phase_ = 0;
0043     else if (tGeom_->isThere(GeomDetEnumerators::P1PXB) && tGeom_->isThere(GeomDetEnumerators::P1PXEC))
0044       phase_ = 1;
0045     else if (tGeom_->isThere(GeomDetEnumerators::P1PXB) && tGeom_->isThere(GeomDetEnumerators::P1PXEC))
0046       phase_ = 2;
0047   }
0048 }
0049 
0050 // _________________________________________________________
0051 //       Offline/Online variables from TrackerTopology
0052 //               and pixel naming classes
0053 
0054 // Taken from pixel naming classes
0055 // BmO (-z-x) = 1, BmI (-z+x) = 2 , BpO (+z-x) = 3 , BpI (+z+x) = 4
0056 int SiPixelCoordinates::quadrant(const DetId& detid) {
0057   if (quadrant_.count(detid.rawId()))
0058     return quadrant_[detid.rawId()];
0059   if (!isPixel_(detid))
0060     return quadrant_[detid.rawId()] = -9999;
0061   if (detid.subdetId() == PixelSubdetector::PixelBarrel)
0062     return quadrant_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).shell();
0063   else
0064     return quadrant_[detid.rawId()] = PixelEndcapName(detid, tTopo_, phase_).halfCylinder();
0065 }
0066 
0067 // Taken from Pixel naming class for barrel
0068 // and TrackerTopology for endcap
0069 // BmO/BmI = 1, BpO/BpI = 2
0070 int SiPixelCoordinates::side(const DetId& detid) {
0071   if (side_.count(detid.rawId()))
0072     return side_[detid.rawId()];
0073   if (!isPixel_(detid))
0074     return side_[detid.rawId()] = -9999;
0075   if (detid.subdetId() == PixelSubdetector::PixelBarrel)
0076     return side_[detid.rawId()] = 1 + (quadrant(detid) > 2);
0077   else
0078     return side_[detid.rawId()] = tTopo_->pxfSide(detid);
0079 }
0080 
0081 // Offline module convention taken from TrackerTopology
0082 int SiPixelCoordinates::module(const DetId& detid) {
0083   if (module_.count(detid.rawId()))
0084     return module_[detid.rawId()];
0085   if (!isPixel_(detid))
0086     return module_[detid.rawId()] = -9999;
0087   if (detid.subdetId() == PixelSubdetector::PixelBarrel)
0088     return module_[detid.rawId()] = tTopo_->pxbModule(detid.rawId());
0089   else
0090     return module_[detid.rawId()] = tTopo_->pxfModule(detid.rawId());
0091 }
0092 
0093 // Taken from TrackerTopology
0094 int SiPixelCoordinates::layer(const DetId& detid) {
0095   if (layer_.count(detid.rawId()))
0096     return layer_[detid.rawId()];
0097   if (!isBPix_(detid))
0098     return layer_[detid.rawId()] = -9999;
0099   return layer_[detid.rawId()] = tTopo_->pxbLayer(detid);
0100 }
0101 
0102 // Taken from pixel naming class for barrel
0103 int SiPixelCoordinates::sector(const DetId& detid) {
0104   if (sector_.count(detid.rawId()))
0105     return sector_[detid.rawId()];
0106   if (!isBPix_(detid))
0107     return sector_[detid.rawId()] = -9999;
0108   return sector_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).sectorName();
0109 }
0110 
0111 // Offline ladder convention taken from TrackerTopology
0112 int SiPixelCoordinates::ladder(const DetId& detid) {
0113   if (ladder_.count(detid.rawId()))
0114     return ladder_[detid.rawId()];
0115   if (!isBPix_(detid))
0116     return ladder_[detid.rawId()] = -9999;
0117   return ladder_[detid.rawId()] = tTopo_->pxbLadder(detid);
0118 }
0119 
0120 // Online ladder convention taken from pixel naming class for barrel
0121 // Apply sign convention (- sign for BmO and BpO)
0122 int SiPixelCoordinates::signed_ladder(const DetId& detid) {
0123   if (signed_ladder_.count(detid.rawId()))
0124     return signed_ladder_[detid.rawId()];
0125   if (!isBPix_(detid))
0126     return signed_ladder_[detid.rawId()] = -9999;
0127   int signed_ladder = PixelBarrelName(detid, tTopo_, phase_).ladderName();
0128   if (quadrant(detid) % 2)
0129     signed_ladder *= -1;
0130   return signed_ladder_[detid.rawId()] = signed_ladder;
0131 }
0132 
0133 // Online mdoule convention taken from pixel naming class for barrel
0134 // Apply sign convention (- sign for BmO and BmI)
0135 int SiPixelCoordinates::signed_module(const DetId& detid) {
0136   if (signed_module_.count(detid.rawId()))
0137     return signed_module_[detid.rawId()];
0138   if (!isBPix_(detid))
0139     return signed_module_[detid.rawId()] = -9999;
0140   int signed_module = PixelBarrelName(detid, tTopo_, phase_).moduleName();
0141   if (quadrant(detid) < 3)
0142     signed_module *= -1;
0143   return signed_module_[detid.rawId()] = signed_module;
0144 }
0145 
0146 // Half ladders taken from pixel naming class
0147 int SiPixelCoordinates::half(const DetId& detid) {
0148   if (half_.count(detid.rawId()))
0149     return half_[detid.rawId()];
0150   if (!isBPix_(detid))
0151     return half_[detid.rawId()] = -9999;
0152   return half_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).isHalfModule();
0153 }
0154 
0155 // Using TrackerTopology
0156 // Ladders have a staggered structure
0157 // Non-flipped ladders are on the outer radius
0158 // Phase 0: Outer ladders are odd for layer 1,3 and even for layer 2
0159 // Phase 1: Outer ladders are odd for layer 4 and even for layer 1,2,3
0160 int SiPixelCoordinates::outer(const DetId& detid) {
0161   if (outer_.count(detid.rawId()))
0162     return outer_[detid.rawId()];
0163   if (!isBPix_(detid))
0164     return outer_[detid.rawId()] = -9999;
0165   int outer = -9999;
0166   int layer = tTopo_->pxbLayer(detid.rawId());
0167   bool odd_ladder = tTopo_->pxbLadder(detid.rawId()) % 2;
0168   if (phase_ == 0) {
0169     if (layer == 2)
0170       outer = !odd_ladder;
0171     else
0172       outer = odd_ladder;
0173   } else if (phase_ == 1) {
0174     if (layer == 4)
0175       outer = odd_ladder;
0176     else
0177       outer = !odd_ladder;
0178   }
0179   return outer_[detid.rawId()] = outer;
0180 }
0181 
0182 // Using outer() method
0183 // We call ladders in the inner radius flipped (see above)
0184 int SiPixelCoordinates::flipped(const DetId& detid) {
0185   if (flipped_.count(detid.rawId()))
0186     return flipped_[detid.rawId()];
0187   if (!isBPix_(detid))
0188     return flipped_[detid.rawId()] = -9999;
0189   int flipped = -9999;
0190   if (phase_ < 2)
0191     flipped = outer(detid) == 0;
0192   return flipped_[detid.rawId()] = flipped;
0193 }
0194 
0195 // Offline disk convention taken from TrackerTopology
0196 int SiPixelCoordinates::disk(const DetId& detid) {
0197   if (disk_.count(detid.rawId()))
0198     return disk_[detid.rawId()];
0199   if (!isFPix_(detid))
0200     return disk_[detid.rawId()] = -9999;
0201   return disk_[detid.rawId()] = tTopo_->pxfDisk(detid);
0202 }
0203 
0204 // Online disk convention
0205 // Apply sign convention (- sign for BmO and BmI)
0206 int SiPixelCoordinates::signed_disk(const DetId& detid) {
0207   if (signed_disk_.count(detid.rawId()))
0208     return signed_disk_[detid.rawId()];
0209   if (!isFPix_(detid))
0210     return signed_disk_[detid.rawId()] = -9999;
0211   int signed_disk = disk(detid);
0212   if (quadrant(detid) < 3)
0213     signed_disk *= -1;
0214   return signed_disk_[detid.rawId()] = signed_disk;
0215 }
0216 
0217 // Taken from TrackerTopology
0218 int SiPixelCoordinates::panel(const DetId& detid) {
0219   if (panel_.count(detid.rawId()))
0220     return panel_[detid.rawId()];
0221   if (!isFPix_(detid))
0222     return panel_[detid.rawId()] = -9999;
0223   return panel_[detid.rawId()] = tTopo_->pxfPanel(detid);
0224 }
0225 
0226 // Phase 0: Ring was not an existing convention
0227 //   but the 7 plaquettes were split by HV group
0228 //   --> Derive Ring 1/2 for them
0229 //   Panel 1 plq 1-2, Panel 2, plq 1   = Ring 1
0230 //   Panel 1 plq 3-4, Panel 2, plq 2-3 = Ring 2
0231 // Phase 1: Using pixel naming class for endcap
0232 int SiPixelCoordinates::ring(const DetId& detid) {
0233   if (ring_.count(detid.rawId()))
0234     return ring_[detid.rawId()];
0235   if (!isFPix_(detid))
0236     return ring_[detid.rawId()] = -9999;
0237   int ring = -9999;
0238   if (phase_ == 0) {
0239     ring = 1 + (panel(detid) + module(detid) > 3);
0240   } else if (phase_ == 1) {
0241     ring = PixelEndcapName(detid, tTopo_, phase_).ringName();
0242   }
0243   return ring_[detid.rawId()] = ring;
0244 }
0245 
0246 // Offline blade convention taken from TrackerTopology
0247 int SiPixelCoordinates::blade(const DetId& detid) {
0248   if (blade_.count(detid.rawId()))
0249     return blade_[detid.rawId()];
0250   if (!isFPix_(detid))
0251     return blade_[detid.rawId()] = -9999;
0252   return blade_[detid.rawId()] = tTopo_->pxfBlade(detid);
0253 }
0254 
0255 // Online blade convention taken from pixel naming class for endcap
0256 // Apply sign convention (- sign for BmO and BpO)
0257 int SiPixelCoordinates::signed_blade(const DetId& detid) {
0258   if (signed_blade_.count(detid.rawId()))
0259     return signed_blade_[detid.rawId()];
0260   if (!isFPix_(detid))
0261     return signed_blade_[detid.rawId()] = -9999;
0262   int signed_blade = PixelEndcapName(detid, tTopo_, phase_).bladeName();
0263   if (quadrant(detid) % 2)
0264     signed_blade *= -1;
0265   return signed_blade_[detid.rawId()] = signed_blade;
0266 }
0267 
0268 // Get the FED number using the cabling map
0269 unsigned int SiPixelCoordinates::fedid(const DetId& detid) {
0270   if (fedid_.count(detid.rawId()))
0271     return fedid_[detid.rawId()];
0272   if (!isPixel_(detid))
0273     return fedid_[detid.rawId()] = 9999;
0274   unsigned int fedid = 9999;
0275   for (auto& fedId : cablingMap_->fedIds()) {
0276     if (SiPixelFrameConverter(cablingMap_, fedId).hasDetUnit(detid.rawId())) {
0277       fedid = fedId;
0278       break;
0279     }
0280   }
0281   return fedid_[detid.rawId()] = fedid;
0282 }
0283 
0284 // _________________________________________________________
0285 //                    Private methods
0286 bool SiPixelCoordinates::isPixel_(const DetId& detid) {
0287   if (detid.det() != DetId::Tracker)
0288     return false;
0289   if (detid.subdetId() == PixelSubdetector::PixelBarrel)
0290     return true;
0291   if (detid.subdetId() == PixelSubdetector::PixelEndcap)
0292     return true;
0293   return false;
0294 }
0295 bool SiPixelCoordinates::isBPix_(const DetId& detid) {
0296   if (detid.det() != DetId::Tracker)
0297     return false;
0298   if (detid.subdetId() == PixelSubdetector::PixelBarrel)
0299     return true;
0300   return false;
0301 }
0302 bool SiPixelCoordinates::isFPix_(const DetId& detid) {
0303   if (detid.det() != DetId::Tracker)
0304     return false;
0305   if (detid.subdetId() == PixelSubdetector::PixelEndcap)
0306     return true;
0307   return false;
0308 }
0309 
0310 std::pair<int, int> SiPixelCoordinates::pixel_(const PixelDigi* digi) {
0311   return std::make_pair(digi->row(), digi->column());
0312 }
0313 std::pair<int, int> SiPixelCoordinates::pixel_(const SiPixelCluster* cluster) {
0314   // Cluster positions are already shifted by 0.5
0315   // We remove this and add back later (for all pixels)
0316   // The aim is to get the offline row/col number of the pixel
0317   int row = cluster->x() - 0.5, col = cluster->y() - 0.5;
0318   return std::make_pair(row, col);
0319 }
0320 std::pair<int, int> SiPixelCoordinates::pixel_(const SiPixelRecHit* rechit) {
0321   // Convert RecHit local position to local pixel using Topology
0322   const PixelGeomDetUnit* detUnit = static_cast<const PixelGeomDetUnit*>(rechit->detUnit());
0323   const PixelTopology* topo = static_cast<const PixelTopology*>(&detUnit->specificTopology());
0324   std::pair<float, float> pixel = topo->pixel(rechit->localPosition());
0325   // We could leave it like this, but it's better to constrain pixel to be on the module
0326   // Also truncate floating point to int (similar to digis)
0327   int row = std::max(0, std::min(topo->nrows() - 1, (int)pixel.first));
0328   int col = std::max(0, std::min(topo->ncolumns() - 1, (int)pixel.second));
0329   return std::make_pair(row, col);
0330 }
0331 
0332 float SiPixelCoordinates::xcoord_on_module_(const DetId& detid, const std::pair<int, int>& pixel) {
0333   int nrows = 160;
0334   // Leave it hard-coded for phase 0/1, read from geometry for phase 2
0335   // no special treatment needed here for phase 0 1x8, 1x5 and 1x2 modules either
0336   // because we do not want to scale coordinates (only shift if needed)
0337   if (phase_ == 2) {
0338     const PixelGeomDetUnit* detUnit = static_cast<const PixelGeomDetUnit*>(tGeom_->idToDetUnit(detid));
0339     const PixelTopology* topo = static_cast<const PixelTopology*>(&detUnit->specificTopology());
0340     nrows = topo->nrows();
0341   }
0342   // Shift to the middle of the pixel, for precision binning
0343   return (pixel.first + 0.5) / nrows;
0344 }
0345 
0346 float SiPixelCoordinates::ycoord_on_module_(const DetId& detid, const std::pair<int, int>& pixel) {
0347   int ncols = 416;
0348   // Leave it hard-coded for phase 0/1, read from geometry for phase 2
0349   if (phase_ == 2) {
0350     const PixelGeomDetUnit* detUnit = static_cast<const PixelGeomDetUnit*>(tGeom_->idToDetUnit(detid));
0351     const PixelTopology* topo = static_cast<const PixelTopology*>(&detUnit->specificTopology());
0352     ncols = topo->ncolumns();
0353   } else if (phase_ == 0 && isFPix_(detid)) {
0354     // Always use largest length for Phase 0 FPix modules (1x5 and 2x5)
0355     // because we do not want to scale coordinates so ROC size remains fixed
0356     // and only shifts are needed
0357     ncols = 260;
0358   }
0359   // Shift to the middle of the pixel, for precision binning
0360   return (pixel.second + 0.5) / ncols;
0361 }
0362 
0363 // _________________________________________________________
0364 //                 Online Link and ROC number
0365 
0366 // Get the FED channel (link) number
0367 // Link may depend on the TBM side of the module
0368 // so pixel location is needed
0369 // Using the cabling map works for all detectors
0370 // Taken from DQM/SiPixelMonitorClient/src/SiPixelInformationExtractor.cc
0371 int SiPixelCoordinates::channel(const DetId& detid, const std::pair<int, int>& pixel) {
0372   if (!isPixel_(detid))
0373     return -9999;
0374   // The method below may be slow when looping on a lot of pixels, so let's try to speed it up
0375   // by quickly chategorizing pixels to ROC coordinates inside det units
0376   int rowsperroc = 80, colsperroc = 52;
0377   if (phase_ == 2) {
0378     // Can get roc info from Geometry for Phase 2, this will need to be specified when it's final
0379     const PixelGeomDetUnit* detUnit = static_cast<const PixelGeomDetUnit*>(tGeom_->idToDetUnit(detid));
0380     const PixelTopology* topo = static_cast<const PixelTopology*>(&detUnit->specificTopology());
0381     rowsperroc = topo->rowsperroc();
0382     colsperroc = topo->colsperroc();
0383   }
0384   // It is unlikely a ROC would have more than 256 chips, so let's use this formula
0385   // If a ROC number was ever found, then binary search in a map will be much quicker
0386   uint64_t pseudo_roc_num =
0387       uint64_t(1 << 16) * detid.rawId() + (1 << 8) * (pixel.first / rowsperroc) + pixel.second / colsperroc;
0388   if (channel_.count(pseudo_roc_num))
0389     return channel_[pseudo_roc_num];
0390   // If not found previously, get the channel number
0391   unsigned int fedId = fedid(detid);
0392   SiPixelFrameConverter converter(cablingMap_, fedId);
0393   sipixelobjects::DetectorIndex detector = {detid.rawId(), pixel.first, pixel.second};
0394   sipixelobjects::ElectronicIndex cabling;
0395   converter.toCabling(cabling, detector);
0396   // Time consuming part is over, so let's save the roc number too
0397   const sipixelobjects::PixelROC* theRoc = converter.toRoc(cabling.link, cabling.roc);
0398   int roc = theRoc->idInDetUnit();
0399   if (detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid) == 1 && half(detid))
0400     roc += 8;
0401   roc_[pseudo_roc_num] = roc;
0402   //printf ("Online FED, LNK, LNKID, ROC: %2d %2d %2d %2d - Offline RAWID, ROW, COL: %9d [%3d,%3d] [%3d,%3d]\n",
0403   //        fedId, cabling.link, cabling.roc, roc, detid.rawId(),
0404   //        (pixel.first /rowsperroc)*rowsperroc, (pixel.first /rowsperroc+1)*rowsperroc-1,
0405   //        (pixel.second/colsperroc)*colsperroc, (pixel.second/colsperroc+1)*colsperroc-1);
0406   return channel_[pseudo_roc_num] = cabling.link;
0407 }
0408 int SiPixelCoordinates::channel(const DetId& detid, const PixelDigi* digi) {
0409   if (!isPixel_(detid))
0410     return -9999;
0411   return channel(detid, pixel_(digi));
0412 }
0413 int SiPixelCoordinates::channel(const DetId& detid, const SiPixelCluster* cluster) {
0414   if (!isPixel_(detid))
0415     return -9999;
0416   return channel(detid, pixel_(cluster));
0417 }
0418 int SiPixelCoordinates::channel(const SiPixelRecHit* rechit) {
0419   if (!isPixel_(rechit->geographicalId()))
0420     return -9999;
0421   return channel(rechit->geographicalId(), pixel_(rechit));
0422 }
0423 int SiPixelCoordinates::channel(const TrackingRecHit* rechit) {
0424   if (!isPixel_(rechit->geographicalId()))
0425     return -9999;
0426   return channel(static_cast<const SiPixelRecHit*>(rechit->hit()));
0427 }
0428 
0429 // Using the cabling map works for all detectors
0430 // Taken from DQM/SiPixelMonitorClient/src/SiPixelInformationExtractor.cc
0431 // Although using coordinates (only available for Phase 0/1) is much faster
0432 // The advantage is very visible when running on smaller statistics
0433 // because the map will speed it up greatly after high enough ROCs were sampled
0434 // The coordinate method is validated to give the same result as the cabling map
0435 // Example for the barrel:
0436 // ROC number is read out in a U shape from ROC 0 to 15 (or maxroc)
0437 // row [80-159] col [0-51] is always ROC 0 on the +Z side of the barrel
0438 // Both coordinates are mirrored on the -Z side (180 deg rotation effectively)
0439 // -Z        8  9 10 11 12 13 14 15   +Z        0  1  2  3  4  5  6  7
0440 //    (0,0)  7  6  5  4  3  2  1  0      (0,0) 15 14 13 12 11 10  9  8
0441 // Half modules on the -Z side should consider the second row of ROCs instead, etc. see below
0442 int SiPixelCoordinates::roc(const DetId& detid, const std::pair<int, int>& pixel) {
0443   if (!isPixel_(detid))
0444     return -9999;
0445   // The method below may be slow when looping on a lot of pixels, so let's try to speed it up
0446   // by quickly chategorizing pixels to ROC coordinates inside det units
0447   int rowsperroc = 80, colsperroc = 52;
0448   if (phase_ == 2) {
0449     // Can get roc info from Geometry for Phase 2, this will need to be specified when it's final
0450     const PixelGeomDetUnit* detUnit = static_cast<const PixelGeomDetUnit*>(tGeom_->idToDetUnit(detid));
0451     const PixelTopology* topo = static_cast<const PixelTopology*>(&detUnit->specificTopology());
0452     rowsperroc = topo->rowsperroc();
0453     colsperroc = topo->colsperroc();
0454   }
0455   // It is unlikely a ROC would have more than 256 chips, so let's use this formula
0456   // If a ROC number was ever found, then binary search in a map will be much quicker
0457   uint64_t pseudo_roc_num =
0458       uint64_t(1 << 16) * detid.rawId() + (1 << 8) * (pixel.first / rowsperroc) + pixel.second / colsperroc;
0459   if (roc_.count(pseudo_roc_num))
0460     return roc_[pseudo_roc_num];
0461   // If not found previously, get the ROC number
0462   int roc = -9999;
0463   // Use the Fed Cabling Map if specified by the bool
0464   // or if using channel number too, or if it's the Phase 2 detector
0465   if (phase_ == 2 || !channel_.empty()) {
0466     unsigned int fedId = fedid(detid);
0467     SiPixelFrameConverter converter(cablingMap_, fedId);
0468     sipixelobjects::DetectorIndex detector = {detid.rawId(), pixel.first, pixel.second};
0469     sipixelobjects::ElectronicIndex cabling;
0470     converter.toCabling(cabling, detector);
0471     // Time consuming part is over, so let's save the channel number too
0472     channel_[pseudo_roc_num] = cabling.link;
0473     const sipixelobjects::PixelROC* theRoc = converter.toRoc(cabling.link, cabling.roc);
0474     roc = theRoc->idInDetUnit();
0475     if (detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid) == 1 && half(detid))
0476       roc += 8;
0477     //printf ("Online FED, LNK, LNKID, ROC: %2d %2d %2d %2d - Offline RAWID, ROW, COL: %9d [%3d,%3d] [%3d,%3d]\n",
0478     //        fedId, cabling.link, cabling.roc, roc, detid.rawId(),
0479     //        (pixel.first /rowsperroc)*rowsperroc, (pixel.first /rowsperroc+1)*rowsperroc-1,
0480     //        (pixel.second/colsperroc)*colsperroc, (pixel.second/colsperroc+1)*colsperroc-1);
0481   } else if (phase_ < 2) {
0482     // This method is faster if only ROC number is needed
0483     int pan = panel(detid), mod = module(detid), rocsY = 8;
0484     if (phase_ == 0 && detid.subdetId() == PixelSubdetector::PixelEndcap)
0485       rocsY = pan + mod;
0486     int rocX = pixel.first / rowsperroc, rocY = pixel.second / colsperroc;
0487     // Consider second row for all 1xN Phase 0 modules
0488     if (phase_ == 0) {
0489       int v1x8 = half(detid) == 1, v1x2 = (pan == 1 && mod == 1), v1x5 = (pan == 1 && mod == 4);
0490       if (v1x8 || v1x2 || v1x5)
0491         ++rocX;
0492     }
0493     // Mirror both coordinates for barrel -Z side
0494     // and for endcap (but only Panel 2 for Phase 0)
0495     if ((detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid) == 1) ||
0496         (detid.subdetId() == PixelSubdetector::PixelEndcap && ((phase_ == 0 && pan == 2) || phase_ == 1))) {
0497       rocX = 1 - rocX;
0498       rocY = rocsY - 1 - rocY;
0499     }
0500     // U-shape readout order
0501     roc = rocX ? rocY : 2 * rocsY - 1 - rocY;
0502   }
0503   return roc_[pseudo_roc_num] = roc;
0504 }
0505 int SiPixelCoordinates::roc(const DetId& detid, const PixelDigi* digi) {
0506   if (!isPixel_(detid))
0507     return -9999;
0508   return roc(detid, pixel_(digi));
0509 }
0510 int SiPixelCoordinates::roc(const DetId& detid, const SiPixelCluster* cluster) {
0511   if (!isPixel_(detid))
0512     return -9999;
0513   return roc(detid, pixel_(cluster));
0514 }
0515 int SiPixelCoordinates::roc(const SiPixelRecHit* rechit) {
0516   if (!isPixel_(rechit->geographicalId()))
0517     return -9999;
0518   return roc(rechit->geographicalId(), pixel_(rechit));
0519 }
0520 int SiPixelCoordinates::roc(const TrackingRecHit* rechit) {
0521   if (!isPixel_(rechit->geographicalId()))
0522     return -9999;
0523   return roc(static_cast<const SiPixelRecHit*>(rechit->hit()));
0524 }
0525 
0526 // _________________________________________________________
0527 //    Floating point Pixel Coordinates similar to those
0528 //       given by TrackerTopology and naming classes
0529 //          but we add a shift within ]-0.5,+0.5[
0530 //    eg. std::round(coord) gives back the original int
0531 float SiPixelCoordinates::module_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0532   if (!isBPix_(detid))
0533     return -9999;
0534   // offline module number is monotonously increasing with global z
0535   // sign is negative because local y is antiparallel to global z
0536   return module(detid) - (ycoord_on_module_(detid, pixel) - 0.5);
0537 }
0538 float SiPixelCoordinates::module_coord(const DetId& detid, const PixelDigi* digi) {
0539   if (!isBPix_(detid))
0540     return -9999;
0541   return module_coord(detid, pixel_(digi));
0542 }
0543 float SiPixelCoordinates::module_coord(const DetId& detid, const SiPixelCluster* cluster) {
0544   if (!isBPix_(detid))
0545     return -9999;
0546   return module_coord(detid, pixel_(cluster));
0547 }
0548 float SiPixelCoordinates::module_coord(const SiPixelRecHit* rechit) {
0549   if (!isBPix_(rechit->geographicalId()))
0550     return -9999;
0551   return module_coord(rechit->geographicalId(), pixel_(rechit));
0552 }
0553 float SiPixelCoordinates::module_coord(const TrackingRecHit* rechit) {
0554   if (!isBPix_(rechit->geographicalId()))
0555     return -9999;
0556   return module_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0557 }
0558 
0559 float SiPixelCoordinates::signed_module_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0560   if (!isBPix_(detid))
0561     return -9999;
0562   // offline module number is monotonously increasing with global z
0563   // sign is negative because local y is antiparallel to global z
0564   return signed_module(detid) - (ycoord_on_module_(detid, pixel) - 0.5);
0565 }
0566 float SiPixelCoordinates::signed_module_coord(const DetId& detid, const PixelDigi* digi) {
0567   if (!isBPix_(detid))
0568     return -9999;
0569   return signed_module_coord(detid, pixel_(digi));
0570 }
0571 float SiPixelCoordinates::signed_module_coord(const DetId& detid, const SiPixelCluster* cluster) {
0572   if (!isBPix_(detid))
0573     return -9999;
0574   return signed_module_coord(detid, pixel_(cluster));
0575 }
0576 float SiPixelCoordinates::signed_module_coord(const SiPixelRecHit* rechit) {
0577   if (!isBPix_(rechit->geographicalId()))
0578     return -9999;
0579   return signed_module_coord(rechit->geographicalId(), pixel_(rechit));
0580 }
0581 float SiPixelCoordinates::signed_module_coord(const TrackingRecHit* rechit) {
0582   if (!isBPix_(rechit->geographicalId()))
0583     return -9999;
0584   return signed_module_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0585 }
0586 
0587 float SiPixelCoordinates::ladder_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0588   if (!isBPix_(detid))
0589     return -9999;
0590   // offline ladder number is monotonously increasing with global phi
0591   // flipped/inner ladders:     lx parallel to global r-phi - positive sign
0592   // non-flipped/outer ladders: lx anti-parallel to global r-phi - negative sign
0593   int sign = flipped(detid) ? 1 : -1;
0594   return ladder(detid) + sign * (xcoord_on_module_(detid, pixel) + half(detid) * 0.5 - 0.5);
0595 }
0596 float SiPixelCoordinates::ladder_coord(const DetId& detid, const PixelDigi* digi) {
0597   if (!isBPix_(detid))
0598     return -9999;
0599   return ladder_coord(detid, pixel_(digi));
0600 }
0601 float SiPixelCoordinates::ladder_coord(const DetId& detid, const SiPixelCluster* cluster) {
0602   if (!isBPix_(detid))
0603     return -9999;
0604   return ladder_coord(detid, pixel_(cluster));
0605 }
0606 float SiPixelCoordinates::ladder_coord(const SiPixelRecHit* rechit) {
0607   if (!isBPix_(rechit->geographicalId()))
0608     return -9999;
0609   return ladder_coord(rechit->geographicalId(), pixel_(rechit));
0610 }
0611 float SiPixelCoordinates::ladder_coord(const TrackingRecHit* rechit) {
0612   if (!isBPix_(rechit->geographicalId()))
0613     return -9999;
0614   return ladder_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0615 }
0616 
0617 float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0618   if (!isBPix_(detid))
0619     return -9999;
0620   // online ladder number is monotonously decreasing with global phi
0621   // flipped/inner ladders:     lx parallel to global r-phi - negative sign
0622   // non-flipped/outer ladders: lx anti-parallel to global r-phi - positive sign
0623   int sign = flipped(detid) ? -1 : 1;
0624   return signed_ladder(detid) + sign * (xcoord_on_module_(detid, pixel) + half(detid) * 0.5 - 0.5);
0625 }
0626 float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const PixelDigi* digi) {
0627   if (!isBPix_(detid))
0628     return -9999;
0629   return signed_ladder_coord(detid, pixel_(digi));
0630 }
0631 float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const SiPixelCluster* cluster) {
0632   if (!isBPix_(detid))
0633     return -9999;
0634   return signed_ladder_coord(detid, pixel_(cluster));
0635 }
0636 float SiPixelCoordinates::signed_ladder_coord(const SiPixelRecHit* rechit) {
0637   if (!isBPix_(rechit->geographicalId()))
0638     return -9999;
0639   return signed_ladder_coord(rechit->geographicalId(), pixel_(rechit));
0640 }
0641 float SiPixelCoordinates::signed_ladder_coord(const TrackingRecHit* rechit) {
0642   if (!isBPix_(rechit->geographicalId()))
0643     return -9999;
0644   return signed_ladder_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0645 }
0646 
0647 // Rings are defined in the radial direction
0648 // which is local x for phase 0 and local y for phase 1
0649 // Rings were not defined for phase 0, but we had a similar
0650 // convention, HV group, the 7 plaquettes were split like this
0651 //   Panel 1 plq 1-2, Panel 2, plq 1   = Ring 1 (HV grp 1)
0652 //   Panel 1 plq 3-4, Panel 2, plq 2-3 = Ring 2 (HV grp 2)
0653 // A subdivision of 8 is suggested for both phase 0 and 1
0654 float SiPixelCoordinates::ring_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0655   if (!isFPix_(detid))
0656     return -9999;
0657   float ring_coord = ring(detid), coord_shift = 0;
0658   if (phase_ == 0) {
0659     // local x on panel 1 is anti-parallel to global radius - sign is negative
0660     // and parallel for panel 2 - sign is positive
0661     int pan = panel(detid), mod = module(detid);
0662     if (pan == 1) {
0663       if (mod == 1)
0664         coord_shift = (-xcoord_on_module_(detid, pixel)) / 4;
0665       else if (mod == 2)
0666         coord_shift = (-xcoord_on_module_(detid, pixel) + 2.0) / 4;
0667       else if (mod == 3)
0668         coord_shift = (-xcoord_on_module_(detid, pixel)) / 4;
0669       else if (mod == 4)
0670         coord_shift = (-xcoord_on_module_(detid, pixel) + 1.5) / 4;
0671     } else {
0672       if (mod == 1)
0673         coord_shift = (xcoord_on_module_(detid, pixel)) / 4;
0674       else if (mod == 2)
0675         coord_shift = (xcoord_on_module_(detid, pixel) - 2.0) / 4;
0676       else if (mod == 3)
0677         coord_shift = (xcoord_on_module_(detid, pixel)) / 4;
0678     }
0679   } else if (phase_ == 1) {
0680     // local y is parallel to global radius, so sign is positive
0681     coord_shift = ycoord_on_module_(detid, pixel) - 0.5;
0682   }
0683   ring_coord += coord_shift;
0684   return ring_coord;
0685 }
0686 float SiPixelCoordinates::ring_coord(const DetId& detid, const PixelDigi* digi) {
0687   if (!isFPix_(detid))
0688     return -9999;
0689   return ring_coord(detid, pixel_(digi));
0690 }
0691 float SiPixelCoordinates::ring_coord(const DetId& detid, const SiPixelCluster* cluster) {
0692   if (!isFPix_(detid))
0693     return -9999;
0694   return ring_coord(detid, pixel_(cluster));
0695 }
0696 float SiPixelCoordinates::ring_coord(const SiPixelRecHit* rechit) {
0697   if (!isFPix_(rechit->geographicalId()))
0698     return -9999;
0699   return ring_coord(rechit->geographicalId(), pixel_(rechit));
0700 }
0701 float SiPixelCoordinates::ring_coord(const TrackingRecHit* rechit) {
0702   if (!isFPix_(rechit->geographicalId()))
0703     return -9999;
0704   return ring_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0705 }
0706 
0707 // Treat disk number as it is (parallel to global z)
0708 // Subdivisions on the forward can be the radial direction
0709 // Which is local x for phase 0 and local y for phase 1
0710 // Closest radius is chosen to be closest to disk = 0
0711 // Rings are not separated, 8 subdivisions are suggested
0712 // Plot suitable for separate ring plots
0713 float SiPixelCoordinates::disk_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0714   if (!isFPix_(detid))
0715     return -9999;
0716   float disk_coord = disk(detid), coord_shift = ring_coord(detid, pixel) - ring(detid);
0717   disk_coord += coord_shift;
0718   return disk_coord;
0719 }
0720 float SiPixelCoordinates::disk_coord(const DetId& detid, const PixelDigi* digi) {
0721   if (!isFPix_(detid))
0722     return -9999;
0723   return disk_coord(detid, pixel_(digi));
0724 }
0725 float SiPixelCoordinates::disk_coord(const DetId& detid, const SiPixelCluster* cluster) {
0726   if (!isFPix_(detid))
0727     return -9999;
0728   return disk_coord(detid, pixel_(cluster));
0729 }
0730 float SiPixelCoordinates::disk_coord(const SiPixelRecHit* rechit) {
0731   if (!isFPix_(rechit->geographicalId()))
0732     return -9999;
0733   return disk_coord(rechit->geographicalId(), pixel_(rechit));
0734 }
0735 float SiPixelCoordinates::disk_coord(const TrackingRecHit* rechit) {
0736   if (!isFPix_(rechit->geographicalId()))
0737     return -9999;
0738   return disk_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0739 }
0740 
0741 // Same as above, but using online convention
0742 // !!! Recommended for Phase 1 !!!
0743 // Can be used for Phase 0 too for comparison purposes
0744 float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0745   if (!isFPix_(detid))
0746     return -9999;
0747   float signed_disk_coord = signed_disk(detid), coord_shift = ring_coord(detid, pixel) - ring(detid);
0748   // Mirror -z side, so plots are symmetric
0749   if (signed_disk_coord < 0)
0750     coord_shift = -coord_shift;
0751   signed_disk_coord += coord_shift;
0752   return signed_disk_coord;
0753 }
0754 float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const PixelDigi* digi) {
0755   if (!isFPix_(detid))
0756     return -9999;
0757   return signed_disk_coord(detid, pixel_(digi));
0758 }
0759 float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const SiPixelCluster* cluster) {
0760   if (!isFPix_(detid))
0761     return -9999;
0762   return signed_disk_coord(detid, pixel_(cluster));
0763 }
0764 float SiPixelCoordinates::signed_disk_coord(const SiPixelRecHit* rechit) {
0765   if (!isFPix_(rechit->geographicalId()))
0766     return -9999;
0767   return signed_disk_coord(rechit->geographicalId(), pixel_(rechit));
0768 }
0769 float SiPixelCoordinates::signed_disk_coord(const TrackingRecHit* rechit) {
0770   if (!isFPix_(rechit->geographicalId()))
0771     return -9999;
0772   return signed_disk_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0773 }
0774 
0775 // Same as the above two, but subdivisions incorporate rings as well
0776 // 16 subdivisions are suggested
0777 float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0778   if (!isFPix_(detid))
0779     return -9999;
0780   float disk_ring_coord = disk(detid), coord_shift = 0;
0781   //if      (phase_==0) coord_shift = (ring_coord(detid,pixel) - 1.625) / 1.5;
0782   //else if (phase_==1) coord_shift = (ring_coord(detid,pixel) - 1.5  ) / 2.0;
0783   coord_shift = (ring_coord(detid, pixel) - 1.5) / 2.0;
0784   disk_ring_coord += coord_shift;
0785   return disk_ring_coord;
0786 }
0787 float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const PixelDigi* digi) {
0788   if (!isFPix_(detid))
0789     return -9999;
0790   return disk_ring_coord(detid, pixel_(digi));
0791 }
0792 float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const SiPixelCluster* cluster) {
0793   if (!isFPix_(detid))
0794     return -9999;
0795   return disk_ring_coord(detid, pixel_(cluster));
0796 }
0797 float SiPixelCoordinates::disk_ring_coord(const SiPixelRecHit* rechit) {
0798   if (!isFPix_(rechit->geographicalId()))
0799     return -9999;
0800   return disk_ring_coord(rechit->geographicalId(), pixel_(rechit));
0801 }
0802 float SiPixelCoordinates::disk_ring_coord(const TrackingRecHit* rechit) {
0803   if (!isFPix_(rechit->geographicalId()))
0804     return -9999;
0805   return disk_ring_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0806 }
0807 
0808 // Same as above, but using online convention
0809 // !!! Recommended for Phase 0 !!!
0810 float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0811   if (!isFPix_(detid))
0812     return -9999;
0813   float signed_disk_ring_coord = signed_disk(detid), coord_shift = 0;
0814   //if      (phase_==0) coord_shift = (ring_coord(detid,pixel) - 1.625) / 1.5;
0815   //else if (phase_==1) coord_shift = (ring_coord(detid,pixel) - 1.5  ) / 2.0;
0816   coord_shift = (ring_coord(detid, pixel) - 1.5) / 2.0;
0817   // Mirror -z side, so plots are symmetric
0818   if (signed_disk_ring_coord < 0)
0819     coord_shift = -coord_shift;
0820   signed_disk_ring_coord += coord_shift;
0821   return signed_disk_ring_coord;
0822 }
0823 float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const PixelDigi* digi) {
0824   if (!isFPix_(detid))
0825     return -9999;
0826   return signed_disk_ring_coord(detid, pixel_(digi));
0827 }
0828 float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const SiPixelCluster* cluster) {
0829   if (!isFPix_(detid))
0830     return -9999;
0831   return signed_disk_ring_coord(detid, pixel_(cluster));
0832 }
0833 float SiPixelCoordinates::signed_disk_ring_coord(const SiPixelRecHit* rechit) {
0834   if (!isFPix_(rechit->geographicalId()))
0835     return -9999;
0836   return signed_disk_ring_coord(rechit->geographicalId(), pixel_(rechit));
0837 }
0838 float SiPixelCoordinates::signed_disk_ring_coord(const TrackingRecHit* rechit) {
0839   if (!isFPix_(rechit->geographicalId()))
0840     return -9999;
0841   return signed_disk_ring_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0842 }
0843 
0844 // Offline blade convention
0845 // Blade number is parallel to global phi
0846 // For Phase 0: local y is parallel with phi
0847 //   On +Z side ly is parallel with phi
0848 //   On -Z side ly is anti-parallel
0849 // Phase 1: local x is parallel with phi
0850 //   +Z Panel 1, -Z Panel 2 is parallel
0851 //   +Z Panel 2, -Z Panel 1 is anti-parallel
0852 // Plot suitable for separate panel 1/2 plots
0853 // 10 subdivisions are recommended for Phase 0 (Half-ROC granularity)
0854 // 2 for Phase 1
0855 float SiPixelCoordinates::blade_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0856   if (!isFPix_(detid))
0857     return -9999;
0858   float blade_coord = blade(detid), coord_shift = 0;
0859   if (phase_ == 0) {
0860     int rocsY = panel(detid) + module(detid);
0861     coord_shift = ycoord_on_module_(detid, pixel) - rocsY / 10.;
0862     if (side(detid) == 1)
0863       coord_shift = -coord_shift;
0864   } else if (phase_ == 1) {
0865     coord_shift = xcoord_on_module_(detid, pixel) - 0.5;
0866     if ((side(detid) + panel(detid)) % 2 == 0)
0867       coord_shift = -coord_shift;
0868   }
0869   blade_coord += coord_shift;
0870   return blade_coord;
0871 }
0872 float SiPixelCoordinates::blade_coord(const DetId& detid, const PixelDigi* digi) {
0873   if (!isFPix_(detid))
0874     return -9999;
0875   return blade_coord(detid, pixel_(digi));
0876 }
0877 float SiPixelCoordinates::blade_coord(const DetId& detid, const SiPixelCluster* cluster) {
0878   if (!isFPix_(detid))
0879     return -9999;
0880   return blade_coord(detid, pixel_(cluster));
0881 }
0882 float SiPixelCoordinates::blade_coord(const SiPixelRecHit* rechit) {
0883   if (!isFPix_(rechit->geographicalId()))
0884     return -9999;
0885   return blade_coord(rechit->geographicalId(), pixel_(rechit));
0886 }
0887 float SiPixelCoordinates::blade_coord(const TrackingRecHit* rechit) {
0888   if (!isFPix_(rechit->geographicalId()))
0889     return -9999;
0890   return blade_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0891 }
0892 
0893 // Online blade convention
0894 // Blade number is anti-parallel to global phi
0895 // so signs are the opposite as above
0896 // Plot suitable for separate panel 1/2 plots
0897 // 10 subdivisions are recommended for Phase 0 (Half-ROC granularity)
0898 // 2 for Phase 1
0899 // !!! Recommended for Phase 0 |||
0900 float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0901   if (!isFPix_(detid))
0902     return -9999;
0903   float signed_blade_coord = signed_blade(detid), coord_shift = 0;
0904   if (phase_ == 0) {
0905     int rocsY = panel(detid) + module(detid);
0906     coord_shift = ycoord_on_module_(detid, pixel) - rocsY / 10.;
0907     if (side(detid) == 2)
0908       coord_shift = -coord_shift;
0909   } else if (phase_ == 1) {
0910     coord_shift = xcoord_on_module_(detid, pixel) - 0.5;
0911     if ((side(detid) + panel(detid)) % 2 == 1)
0912       coord_shift = -coord_shift;
0913   }
0914   signed_blade_coord += coord_shift;
0915   return signed_blade_coord;
0916 }
0917 float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const PixelDigi* digi) {
0918   if (!isFPix_(detid))
0919     return -9999;
0920   return signed_blade_coord(detid, pixel_(digi));
0921 }
0922 float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const SiPixelCluster* cluster) {
0923   if (!isFPix_(detid))
0924     return -9999;
0925   return signed_blade_coord(detid, pixel_(cluster));
0926 }
0927 float SiPixelCoordinates::signed_blade_coord(const SiPixelRecHit* rechit) {
0928   if (!isFPix_(rechit->geographicalId()))
0929     return -9999;
0930   return signed_blade_coord(rechit->geographicalId(), pixel_(rechit));
0931 }
0932 float SiPixelCoordinates::signed_blade_coord(const TrackingRecHit* rechit) {
0933   if (!isFPix_(rechit->geographicalId()))
0934     return -9999;
0935   return signed_blade_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0936 }
0937 
0938 // Offline blade convention + alternating panels
0939 // Same as above two, but subdivisions incorporate panels
0940 // Panel 2 is towards higher phi values for Phase 1 (overlap for phase 0)
0941 // 20 subdivisions are recommended for Phase 0 (Half-ROC granularity)
0942 // 4 for Phase 1
0943 float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0944   if (!isFPix_(detid))
0945     return -9999;
0946   float blade_panel_coord = blade(detid);
0947   float coord_shift = (blade_coord(detid, pixel) - blade_panel_coord + panel(detid) - 1.5) / 2;
0948   blade_panel_coord += coord_shift;
0949   return blade_panel_coord;
0950 }
0951 float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const PixelDigi* digi) {
0952   if (!isFPix_(detid))
0953     return -9999;
0954   return blade_panel_coord(detid, pixel_(digi));
0955 }
0956 float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) {
0957   if (!isFPix_(detid))
0958     return -9999;
0959   return blade_panel_coord(detid, pixel_(cluster));
0960 }
0961 float SiPixelCoordinates::blade_panel_coord(const SiPixelRecHit* rechit) {
0962   if (!isFPix_(rechit->geographicalId()))
0963     return -9999;
0964   return blade_panel_coord(rechit->geographicalId(), pixel_(rechit));
0965 }
0966 float SiPixelCoordinates::blade_panel_coord(const TrackingRecHit* rechit) {
0967   if (!isFPix_(rechit->geographicalId()))
0968     return -9999;
0969   return blade_panel_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
0970 }
0971 
0972 // Online blade convention + alternating panels
0973 // Blade number is anti-parallel to global phi
0974 // so signs are the opposite as above
0975 // 20 subdivisions are recommended for Phase 0 (Half-ROC granularity)
0976 // 4 for Phase 1
0977 // !!! Recommended for Phase 1 !!!
0978 float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const std::pair<int, int>& pixel) {
0979   if (!isFPix_(detid))
0980     return -9999;
0981   float signed_blade_panel_coord = signed_blade(detid);
0982   float coord_shift = (signed_blade_coord(detid, pixel) - signed_blade_panel_coord - panel(detid) + 1.5) / 2;
0983   signed_blade_panel_coord += coord_shift;
0984   return signed_blade_panel_coord;
0985 }
0986 float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const PixelDigi* digi) {
0987   if (!isFPix_(detid))
0988     return -9999;
0989   return signed_blade_panel_coord(detid, pixel_(digi));
0990 }
0991 float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) {
0992   if (!isFPix_(detid))
0993     return -9999;
0994   return signed_blade_panel_coord(detid, pixel_(cluster));
0995 }
0996 float SiPixelCoordinates::signed_blade_panel_coord(const SiPixelRecHit* rechit) {
0997   if (!isFPix_(rechit->geographicalId()))
0998     return -9999;
0999   return signed_blade_panel_coord(rechit->geographicalId(), pixel_(rechit));
1000 }
1001 float SiPixelCoordinates::signed_blade_panel_coord(const TrackingRecHit* rechit) {
1002   if (!isFPix_(rechit->geographicalId()))
1003     return -9999;
1004   return signed_blade_panel_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
1005 }
1006 
1007 // Same as above, but blade numbers are shifted for Phase 1 Ring 1
1008 // so one can plot Ring1+Ring2 while conserving geometrical
1009 // overlaps in phi
1010 // Ring 2: 17 blades x 4 ROC --> 68 bin
1011 // Ring 1: 2 gap, 4 ROC, alternating for 11 blades --> 68 bin
1012 float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const std::pair<int, int>& pixel) {
1013   if (!isFPix_(detid))
1014     return -9999;
1015   float signed_shifted_blade_panel_coord = signed_blade(detid);
1016   float coord_shift = (signed_blade_coord(detid, pixel) - signed_shifted_blade_panel_coord - panel(detid) + 1.5) / 2;
1017   if (phase_ == 1 && ring(detid) == 1)
1018     signed_shifted_blade_panel_coord *= 1.5;
1019   signed_shifted_blade_panel_coord += coord_shift;
1020   return signed_shifted_blade_panel_coord;
1021 }
1022 float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const PixelDigi* digi) {
1023   if (!isFPix_(detid))
1024     return -9999;
1025   return signed_shifted_blade_panel_coord(detid, pixel_(digi));
1026 }
1027 float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) {
1028   if (!isFPix_(detid))
1029     return -9999;
1030   return signed_shifted_blade_panel_coord(detid, pixel_(cluster));
1031 }
1032 float SiPixelCoordinates::signed_shifted_blade_panel_coord(const SiPixelRecHit* rechit) {
1033   if (!isFPix_(rechit->geographicalId()))
1034     return -9999;
1035   return signed_shifted_blade_panel_coord(rechit->geographicalId(), pixel_(rechit));
1036 }
1037 float SiPixelCoordinates::signed_shifted_blade_panel_coord(const TrackingRecHit* rechit) {
1038   if (!isFPix_(rechit->geographicalId()))
1039     return -9999;
1040   return signed_shifted_blade_panel_coord(static_cast<const SiPixelRecHit*>(rechit->hit()));
1041 }