Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:19

0001 #ifndef TRACKERTOPOLOGY_H
0002 #define TRACKERTOPOLOGY_H
0003 
0004 #include "DataFormats/DetId/interface/DetId.h"
0005 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0006 #include "DataFormats/SiStripDetId/interface/SiStripEnums.h"
0007 
0008 #include <vector>
0009 #include <string>
0010 
0011 //knower of all things tracker geometry
0012 //flexible replacement for PXBDetId and friends
0013 //to implement
0014 // endcap pixel
0015 
0016 class TrackerTopology {
0017 public:
0018   struct PixelBarrelValues {
0019     unsigned int layerStartBit_;
0020     unsigned int ladderStartBit_;
0021     unsigned int moduleStartBit_;
0022     unsigned int doubleStartBit_;
0023     unsigned int layerMask_;
0024     unsigned int ladderMask_;
0025     unsigned int moduleMask_;
0026     unsigned int doubleMask_;
0027   };
0028 
0029   struct PixelEndcapValues {
0030     unsigned int sideStartBit_;
0031     unsigned int diskStartBit_;
0032     unsigned int bladeStartBit_;
0033     unsigned int panelStartBit_;
0034     unsigned int moduleStartBit_;
0035     unsigned int sideMask_;
0036     unsigned int diskMask_;
0037     unsigned int bladeMask_;
0038     unsigned int panelMask_;
0039     unsigned int moduleMask_;
0040   };
0041 
0042   struct TECValues {
0043     unsigned int sideStartBit_;
0044     unsigned int wheelStartBit_;
0045     unsigned int petal_fw_bwStartBit_;
0046     unsigned int petalStartBit_;
0047     unsigned int ringStartBit_;
0048     unsigned int moduleStartBit_;
0049     unsigned int sterStartBit_;
0050     unsigned int sideMask_;
0051     unsigned int wheelMask_;
0052     unsigned int petal_fw_bwMask_;
0053     unsigned int petalMask_;
0054     unsigned int ringMask_;
0055     unsigned int moduleMask_;
0056     unsigned int sterMask_;
0057   };
0058 
0059   struct TIBValues {
0060     unsigned int layerStartBit_;
0061     unsigned int str_fw_bwStartBit_;
0062     unsigned int str_int_extStartBit_;
0063     unsigned int strStartBit_;
0064     unsigned int moduleStartBit_;
0065     unsigned int sterStartBit_;
0066 
0067     unsigned int layerMask_;
0068     unsigned int str_fw_bwMask_;
0069     unsigned int str_int_extMask_;
0070     unsigned int strMask_;
0071     unsigned int moduleMask_;
0072     unsigned int sterMask_;
0073   };
0074 
0075   struct TIDValues {
0076     unsigned int sideStartBit_;
0077     unsigned int wheelStartBit_;
0078     unsigned int ringStartBit_;
0079     unsigned int module_fw_bwStartBit_;
0080     unsigned int moduleStartBit_;
0081     unsigned int sterStartBit_;
0082     unsigned int sideMask_;
0083     unsigned int wheelMask_;
0084     unsigned int ringMask_;
0085     unsigned int module_fw_bwMask_;
0086     unsigned int moduleMask_;
0087     unsigned int sterMask_;
0088   };
0089 
0090   struct TOBValues {
0091     unsigned int layerStartBit_;
0092     unsigned int rod_fw_bwStartBit_;
0093     unsigned int rodStartBit_;
0094     unsigned int moduleStartBit_;
0095     unsigned int sterStartBit_;
0096     unsigned int layerMask_;
0097     unsigned int rod_fw_bwMask_;
0098     unsigned int rodMask_;
0099     unsigned int moduleMask_;
0100     unsigned int sterMask_;
0101   };
0102 
0103   enum DetIdFields {
0104     PBModule,
0105     PBLadder,
0106     PBLayer,
0107     PFModule,
0108     PFPanel,
0109     PFBlade,
0110     PFDisk,
0111     PFSide,
0112     /* TODO: this can be extended for all subdetectors */
0113     DETID_FIELDS_MAX
0114   };
0115 
0116   class SameLayerComparator {
0117   public:
0118     explicit SameLayerComparator(const TrackerTopology *topo) : topo_(topo) {}
0119 
0120     bool operator()(DetId i1, DetId i2) const {
0121       if (i1.det() == i2.det() && i1.subdetId() == i2.subdetId() && topo_->side(i1) == topo_->side(i2) &&
0122           topo_->layer(i1) == topo_->layer(i2)) {
0123         return false;
0124       }
0125       return i1 < i2;
0126     }
0127 
0128     bool operator()(uint32_t i1, uint32_t i2) const { return operator()(DetId(i1), DetId(i2)); }
0129 
0130   private:
0131     const TrackerTopology *topo_;
0132   };
0133 
0134   TrackerTopology(const PixelBarrelValues &pxb,
0135                   const PixelEndcapValues &pxf,
0136                   const TECValues &tecv,
0137                   const TIBValues &tibv,
0138                   const TIDValues &tidv,
0139                   const TOBValues &tobv);
0140 
0141   unsigned int side(const DetId &id) const;
0142   unsigned int layer(const DetId &id) const;
0143   unsigned int module(const DetId &id) const;
0144 
0145   // layer numbers
0146   unsigned int pxbLayer(const DetId &id) const {
0147     return int((id.rawId() >> pbVals_.layerStartBit_) & pbVals_.layerMask_);
0148   }
0149   unsigned int tobLayer(const DetId &id) const {
0150     return int((id.rawId() >> tobVals_.layerStartBit_) & tobVals_.layerMask_);
0151   }
0152   unsigned int tibLayer(const DetId &id) const {
0153     return int((id.rawId() >> tibVals_.layerStartBit_) & tibVals_.layerMask_);
0154   }
0155 
0156   //ladder
0157   unsigned int pxbLadder(const DetId &id) const {
0158     return ((id.rawId() >> pbVals_.ladderStartBit_) & pbVals_.ladderMask_);
0159   }
0160 
0161   //module
0162   unsigned int pxbModule(const DetId &id) const {
0163     return ((id.rawId() >> pbVals_.moduleStartBit_) & pbVals_.moduleMask_);
0164   }
0165   unsigned int pxfModule(const DetId &id) const {
0166     return int((id.rawId() >> pfVals_.moduleStartBit_) & pfVals_.moduleMask_);
0167   }
0168   unsigned int tobModule(const DetId &id) const {
0169     return ((id.rawId() >> tobVals_.moduleStartBit_) & tobVals_.moduleMask_);
0170   }
0171   unsigned int tecModule(const DetId &id) const {
0172     return ((id.rawId() >> tecVals_.moduleStartBit_) & tecVals_.moduleMask_);
0173   }
0174   unsigned int tibModule(const DetId &id) const {
0175     return ((id.rawId() >> tibVals_.moduleStartBit_) & tibVals_.moduleMask_);
0176   }
0177   unsigned int tidModule(const DetId &id) const {
0178     return ((id.rawId() >> tidVals_.moduleStartBit_) & tidVals_.moduleMask_);
0179   }
0180 
0181   //side
0182   unsigned int tobSide(const DetId &id) const {
0183     return ((id.rawId() >> tobVals_.rod_fw_bwStartBit_) & tobVals_.rod_fw_bwMask_);
0184   }
0185 
0186   unsigned int tecSide(const DetId &id) const { return ((id.rawId() >> tecVals_.sideStartBit_) & tecVals_.sideMask_); }
0187 
0188   unsigned int tibSide(const DetId &id) const {
0189     return ((id.rawId() >> tibVals_.str_fw_bwStartBit_) & tibVals_.str_fw_bwMask_);
0190   }
0191 
0192   unsigned int tidSide(const DetId &id) const { return ((id.rawId() >> tidVals_.sideStartBit_) & tidVals_.sideMask_); }
0193 
0194   unsigned int pxfSide(const DetId &id) const { return ((id.rawId() >> pfVals_.sideStartBit_) & pfVals_.sideMask_); }
0195 
0196   //rod
0197   unsigned int tobRod(const DetId &id) const { return ((id.rawId() >> tobVals_.rodStartBit_) & tobVals_.rodMask_); }
0198 
0199   //wheel
0200   unsigned int tecWheel(const DetId &id) const {
0201     return ((id.rawId() >> tecVals_.wheelStartBit_) & tecVals_.wheelMask_);
0202   }
0203   unsigned int tidWheel(const DetId &id) const {
0204     return ((id.rawId() >> tidVals_.wheelStartBit_) & tidVals_.wheelMask_);
0205   }
0206 
0207   //order
0208   unsigned int tecOrder(const DetId &id) const {
0209     return ((id.rawId() >> tecVals_.petal_fw_bwStartBit_) & tecVals_.petal_fw_bwMask_);
0210   }
0211   unsigned int tibOrder(const DetId &id) const {
0212     return ((id.rawId() >> tibVals_.str_int_extStartBit_) & tibVals_.str_int_extMask_);
0213   }
0214   unsigned int tidOrder(const DetId &id) const {
0215     return ((id.rawId() >> tidVals_.module_fw_bwStartBit_) & tidVals_.module_fw_bwMask_);
0216   }
0217 
0218   /// ring id
0219   unsigned int tecRing(const DetId &id) const { return ((id.rawId() >> tecVals_.ringStartBit_) & tecVals_.ringMask_); }
0220   unsigned int tidRing(const DetId &id) const { return ((id.rawId() >> tidVals_.ringStartBit_) & tidVals_.ringMask_); }
0221 
0222   //petal
0223   unsigned int tecPetalNumber(const DetId &id) const {
0224     return ((id.rawId() >> tecVals_.petalStartBit_) & tecVals_.petalMask_);
0225   }
0226 
0227   //misc tob
0228   std::vector<unsigned int> tobRodInfo(const DetId &id) const {
0229     std::vector<unsigned int> num;
0230     num.push_back(tobSide(id));
0231     num.push_back(tobRod(id));
0232     return num;
0233   }
0234 
0235   //generic function to return DetIds and boolean factors
0236   uint32_t glued(const DetId &id) const;
0237   uint32_t stack(const DetId &id) const;
0238   uint32_t doubleSensor(const DetId &id) const;
0239   uint32_t lower(const DetId &id) const;
0240   uint32_t upper(const DetId &id) const;
0241   uint32_t first(const DetId &id) const;
0242   uint32_t second(const DetId &id) const;
0243 
0244   bool isStereo(const DetId &id) const;
0245   bool isRPhi(const DetId &id) const;
0246   bool isDoubleSens(const DetId &id) const;
0247   bool isLower(const DetId &id) const;
0248   bool isUpper(const DetId &id) const;
0249   bool isFirst(const DetId &id) const;
0250   bool isSecond(const DetId &id) const;
0251 
0252   //specific function to return boolean factors
0253   bool tobIsDoubleSide(const DetId &id) const { return tobGlued(id) == 0 && (tobLayer(id) == 1 || tobLayer(id) == 2); }
0254   bool tecIsDoubleSide(const DetId &id) const {
0255     return tecGlued(id) == 0 && (tecRing(id) == 1 || tecRing(id) == 2 || tecRing(id) == 5);
0256   }
0257   bool tibIsDoubleSide(const DetId &id) const { return tibGlued(id) == 0 && (tibLayer(id) == 1 || tibLayer(id) == 2); }
0258   bool tidIsDoubleSide(const DetId &id) const { return tidGlued(id) == 0 && (tidRing(id) == 1 || tidRing(id) == 2); }
0259 
0260   bool tobIsZPlusSide(const DetId &id) const { return !tobIsZMinusSide(id); }
0261   bool tobIsZMinusSide(const DetId &id) const { return tobSide(id) == 1; }
0262 
0263   bool tibIsZPlusSide(const DetId &id) const { return !tibIsZMinusSide(id); }
0264   bool tibIsZMinusSide(const DetId &id) const { return tibSide(id) == 1; }
0265 
0266   bool tidIsZPlusSide(const DetId &id) const { return !tidIsZMinusSide(id); }
0267   bool tidIsZMinusSide(const DetId &id) const { return tidSide(id) == 1; }
0268 
0269   bool tecIsZPlusSide(const DetId &id) const { return !tecIsZMinusSide(id); }
0270   bool tecIsZMinusSide(const DetId &id) const { return tecSide(id) == 1; }
0271 
0272   bool tobIsStereo(const DetId &id) const { return tobStereo(id) != 0 && !tobIsDoubleSide(id); }
0273   bool tecIsStereo(const DetId &id) const { return tecStereo(id) != 0 && !tecIsDoubleSide(id); }
0274   bool tibIsStereo(const DetId &id) const { return tibStereo(id) != 0 && !tibIsDoubleSide(id); }
0275   bool tidIsStereo(const DetId &id) const { return tidStereo(id) != 0 && !tidIsDoubleSide(id); }
0276 
0277   bool tobIsRPhi(const DetId &id) const { return tobRPhi(id) != 0 && !tobIsDoubleSide(id); }
0278   bool tecIsRPhi(const DetId &id) const { return tecRPhi(id) != 0 && !tecIsDoubleSide(id); }
0279   bool tibIsRPhi(const DetId &id) const { return tibRPhi(id) != 0 && !tibIsDoubleSide(id); }
0280   bool tidIsRPhi(const DetId &id) const { return tidRPhi(id) != 0 && !tidIsDoubleSide(id); }
0281 
0282   //phase0 stereo
0283   uint32_t tobStereo(const DetId &id) const {
0284     return (((id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_) == 1) ? 1 : 0;
0285   }
0286 
0287   uint32_t tibStereo(const DetId &id) const {
0288     return (((id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_) == 1) ? 1 : 0;
0289   }
0290 
0291   uint32_t tidStereo(const DetId &id) const {
0292     return (((id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_) == 1) ? 1 : 0;
0293   }
0294 
0295   uint32_t tecStereo(const DetId &id) const {
0296     return (((id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_) == 1) ? 1 : 0;
0297   }
0298 
0299   //phase 2 split sensor
0300   uint32_t pixFirst(const DetId &id) const {
0301     return (((id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_) == 1) ? 1 : 0;
0302   }
0303 
0304   //phase0 stereo == phase2 lower
0305   uint32_t tibLower(const DetId &id) const { return tibStereo(id); }
0306   uint32_t tidLower(const DetId &id) const { return tidStereo(id); }
0307   uint32_t tobLower(const DetId &id) const { return tobStereo(id); }
0308   uint32_t tecLower(const DetId &id) const { return tecStereo(id); }
0309 
0310   //phase0 rphi
0311   uint32_t tobRPhi(const DetId &id) const {
0312     if (((id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_) == 2) {
0313       return ((id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_);
0314     } else {
0315       return 0;
0316     }
0317   }
0318 
0319   uint32_t tibRPhi(const DetId &id) const {
0320     if (((id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_) == 2) {
0321       return ((id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_);
0322     } else {
0323       return 0;
0324     }
0325   }
0326 
0327   uint32_t tidRPhi(const DetId &id) const {
0328     if (((id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_) == 2) {
0329       return ((id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_);
0330     } else {
0331       return 0;
0332     }
0333   }
0334 
0335   uint32_t tecRPhi(const DetId &id) const {
0336     if (((id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_) == 2) {
0337       return ((id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_);
0338     } else {
0339       return 0;
0340     }
0341   }
0342 
0343   uint32_t pixSecond(const DetId &id) const {
0344     if (((id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_) == 2) {
0345       return ((id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_);
0346     } else {
0347       return 0;
0348     }
0349   }
0350 
0351   //phase0 rphi == phase2 upper
0352   uint32_t tibUpper(const DetId &id) const { return tibRPhi(id); }
0353   uint32_t tidUpper(const DetId &id) const { return tidRPhi(id); }
0354   uint32_t tobUpper(const DetId &id) const { return tobRPhi(id); }
0355   uint32_t tecUpper(const DetId &id) const { return tecRPhi(id); }
0356 
0357   //phase0 glued
0358   uint32_t tibGlued(const DetId &id) const {
0359     uint32_t testId = (id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_;
0360     return (testId == 0) ? 0 : (id.rawId() - testId);
0361   }
0362 
0363   uint32_t tecGlued(const DetId &id) const {
0364     uint32_t testId = (id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_;
0365     return (testId == 0) ? 0 : (id.rawId() - testId);
0366   }
0367 
0368   uint32_t tobGlued(const DetId &id) const {
0369     uint32_t testId = (id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_;
0370     return (testId == 0) ? 0 : (id.rawId() - testId);
0371   }
0372 
0373   uint32_t tidGlued(const DetId &id) const {
0374     uint32_t testId = (id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_;
0375     return (testId == 0) ? 0 : (id.rawId() - testId);
0376   }
0377 
0378   uint32_t pixDouble(const DetId &id) const {
0379     uint32_t testId = (id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_;
0380     return (testId == 0) ? 0 : (id.rawId() - testId);
0381   }
0382 
0383   //phase0 glued == phase2 stack
0384   uint32_t tibStack(const DetId &id) const { return tibGlued(id); }
0385   uint32_t tidStack(const DetId &id) const { return tidGlued(id); }
0386   uint32_t tobStack(const DetId &id) const { return tobGlued(id); }
0387   uint32_t tecStack(const DetId &id) const { return tecGlued(id); }
0388 
0389   //these should be used now!!
0390   DetId partnerDetId(const DetId &id) const;
0391 
0392   DetId pixPartnerDetId(const DetId &id) const {
0393     if (((id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_) == 1) {
0394       return DetId(id.rawId() + 1);
0395     } else if (((id.rawId() >> pbVals_.doubleStartBit_) & pbVals_.doubleMask_) == 2) {
0396       return DetId(id.rawId() - 1);
0397     } else {
0398       return DetId();
0399     }
0400   }
0401 
0402   DetId tibPartnerDetId(const DetId &id) const {
0403     if (((id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_) == 1) {
0404       return DetId(id.rawId() + 1);
0405     } else if (((id.rawId() >> tibVals_.sterStartBit_) & tibVals_.sterMask_) == 2) {
0406       return DetId(id.rawId() - 1);
0407     } else {
0408       return DetId();
0409     }
0410   }
0411 
0412   DetId tobPartnerDetId(const DetId &id) const {
0413     if (((id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_) == 1) {
0414       return DetId(id.rawId() + 1);
0415     } else if (((id.rawId() >> tobVals_.sterStartBit_) & tobVals_.sterMask_) == 2) {
0416       return DetId(id.rawId() - 1);
0417     } else {
0418       return DetId();
0419     }
0420   }
0421 
0422   DetId tidPartnerDetId(const DetId &id) const {
0423     if (((id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_) == 1) {
0424       return DetId(id.rawId() + 1);
0425     } else if (((id.rawId() >> tidVals_.sterStartBit_) & tidVals_.sterMask_) == 2) {
0426       return DetId(id.rawId() - 1);
0427     } else {
0428       return DetId();
0429     }
0430   }
0431 
0432   uint32_t tecPartnerDetId(const DetId &id) const {
0433     if (((id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_) == 1) {
0434       return DetId(id.rawId() + 1);
0435     } else if (((id.rawId() >> tecVals_.sterStartBit_) & tecVals_.sterMask_) == 2) {
0436       return DetId(id.rawId() - 1);
0437     } else {
0438       return DetId();
0439     }
0440   }
0441 
0442   //misc tec
0443   std::vector<unsigned int> tecPetalInfo(const DetId &id) const {
0444     std::vector<unsigned int> num;
0445     num.push_back(tecOrder(id));
0446     num.push_back(tecPetalNumber(id));
0447     return num;
0448   }
0449 
0450   bool tecIsBackPetal(const DetId &id) const { return (tecOrder(id) == 1); }
0451 
0452   bool tecIsFrontPetal(const DetId &id) const { return !tecIsBackPetal(id); }
0453 
0454   //misc tib
0455   unsigned int tibString(const DetId &id) const { return (id.rawId() >> tibVals_.strStartBit_) & tibVals_.strMask_; }
0456 
0457   std::vector<unsigned int> tibStringInfo(const DetId &id) const {
0458     std::vector<unsigned int> num;
0459     num.push_back(tibSide(id));
0460     num.push_back(tibOrder(id));
0461     num.push_back(tibString(id));
0462     return num;
0463   }
0464 
0465   bool tibIsInternalString(const DetId &id) const { return (tibOrder(id) == 1); }
0466 
0467   bool tibIsExternalString(const DetId &id) const { return !tibIsInternalString(id); }
0468 
0469   //misc tid
0470   std::vector<unsigned int> tidModuleInfo(const DetId &id) const {
0471     std::vector<unsigned int> num;
0472     num.push_back(tidOrder(id));
0473     num.push_back(tidModule(id));
0474     return num;
0475   }
0476 
0477   bool tidIsBackRing(const DetId &id) const { return (tidOrder(id) == 1); }
0478 
0479   bool tidIsFrontRing(const DetId &id) const { return !tidIsBackRing(id); }
0480 
0481   //misc pf
0482   unsigned int pxfDisk(const DetId &id) const { return int((id.rawId() >> pfVals_.diskStartBit_) & pfVals_.diskMask_); }
0483   unsigned int pxfBlade(const DetId &id) const {
0484     return int((id.rawId() >> pfVals_.bladeStartBit_) & pfVals_.bladeMask_);
0485   }
0486   unsigned int pxfPanel(const DetId &id) const {
0487     return int((id.rawId() >> pfVals_.panelStartBit_) & pfVals_.panelMask_);
0488   }
0489 
0490   //old constructors, now return DetId
0491   DetId pxbDetId(uint32_t layer, uint32_t ladder, uint32_t module) const {
0492     //uply
0493     DetId id(DetId::Tracker, PixelSubdetector::PixelBarrel);
0494     uint32_t rawid = id.rawId();
0495     rawid |= (layer & pbVals_.layerMask_) << pbVals_.layerStartBit_ |
0496              (ladder & pbVals_.ladderMask_) << pbVals_.ladderStartBit_ |
0497              (module & pbVals_.moduleMask_) << pbVals_.moduleStartBit_;
0498     return DetId(rawid);
0499   }
0500 
0501   DetId pxfDetId(uint32_t side, uint32_t disk, uint32_t blade, uint32_t panel, uint32_t module) const {
0502     DetId id(DetId::Tracker, PixelSubdetector::PixelEndcap);
0503     uint32_t rawid = id.rawId();
0504     rawid |= (side & pfVals_.sideMask_) << pfVals_.sideStartBit_ | (disk & pfVals_.diskMask_) << pfVals_.diskStartBit_ |
0505              (blade & pfVals_.bladeMask_) << pfVals_.bladeStartBit_ |
0506              (panel & pfVals_.panelMask_) << pfVals_.panelStartBit_ |
0507              (module & pfVals_.moduleMask_) << pfVals_.moduleStartBit_;
0508     return DetId(rawid);
0509   }
0510 
0511   DetId tecDetId(uint32_t side,
0512                  uint32_t wheel,
0513                  uint32_t petal_fw_bw,
0514                  uint32_t petal,
0515                  uint32_t ring,
0516                  uint32_t module,
0517                  uint32_t ster) const {
0518     DetId id = DetId(DetId::Tracker, SiStripSubdetector::TEC);
0519     uint32_t rawid = id.rawId();
0520 
0521     rawid |= (side & tecVals_.sideMask_) << tecVals_.sideStartBit_ |
0522              (wheel & tecVals_.wheelMask_) << tecVals_.wheelStartBit_ |
0523              (petal_fw_bw & tecVals_.petal_fw_bwMask_) << tecVals_.petal_fw_bwStartBit_ |
0524              (petal & tecVals_.petalMask_) << tecVals_.petalStartBit_ |
0525              (ring & tecVals_.ringMask_) << tecVals_.ringStartBit_ |
0526              (module & tecVals_.moduleMask_) << tecVals_.moduleStartBit_ |
0527              (ster & tecVals_.sterMask_) << tecVals_.sterStartBit_;
0528     return DetId(rawid);
0529   }
0530 
0531   DetId tibDetId(
0532       uint32_t layer, uint32_t str_fw_bw, uint32_t str_int_ext, uint32_t str, uint32_t module, uint32_t ster) const {
0533     DetId id = DetId(DetId::Tracker, SiStripSubdetector::TIB);
0534     uint32_t rawid = id.rawId();
0535     rawid |= (layer & tibVals_.layerMask_) << tibVals_.layerStartBit_ |
0536              (str_fw_bw & tibVals_.str_fw_bwMask_) << tibVals_.str_fw_bwStartBit_ |
0537              (str_int_ext & tibVals_.str_int_extMask_) << tibVals_.str_int_extStartBit_ |
0538              (str & tibVals_.strMask_) << tibVals_.strStartBit_ |
0539              (module & tibVals_.moduleMask_) << tibVals_.moduleStartBit_ |
0540              (ster & tibVals_.sterMask_) << tibVals_.sterStartBit_;
0541     return DetId(rawid);
0542   }
0543 
0544   DetId tidDetId(
0545       uint32_t side, uint32_t wheel, uint32_t ring, uint32_t module_fw_bw, uint32_t module, uint32_t ster) const {
0546     DetId id = DetId(DetId::Tracker, SiStripSubdetector::TID);
0547     uint32_t rawid = id.rawId();
0548     rawid |= (side & tidVals_.sideMask_) << tidVals_.sideStartBit_ |
0549              (wheel & tidVals_.wheelMask_) << tidVals_.wheelStartBit_ |
0550              (ring & tidVals_.ringMask_) << tidVals_.ringStartBit_ |
0551              (module_fw_bw & tidVals_.module_fw_bwMask_) << tidVals_.module_fw_bwStartBit_ |
0552              (module & tidVals_.moduleMask_) << tidVals_.moduleStartBit_ |
0553              (ster & tidVals_.sterMask_) << tidVals_.sterStartBit_;
0554     return DetId(rawid);
0555   }
0556 
0557   DetId tobDetId(uint32_t layer, uint32_t rod_fw_bw, uint32_t rod, uint32_t module, uint32_t ster) const {
0558     DetId id = DetId(DetId::Tracker, SiStripSubdetector::TOB);
0559     uint32_t rawid = id.rawId();
0560     rawid |= (layer & tobVals_.layerMask_) << tobVals_.layerStartBit_ |
0561              (rod_fw_bw & tobVals_.rod_fw_bwMask_) << tobVals_.rod_fw_bwStartBit_ |
0562              (rod & tobVals_.rodMask_) << tobVals_.rodStartBit_ |
0563              (module & tobVals_.moduleMask_) << tobVals_.moduleStartBit_ |
0564              (ster & tobVals_.sterMask_) << tobVals_.sterStartBit_;
0565     return DetId(rawid);
0566   }
0567 
0568   std::pair<DetId, SameLayerComparator> pxbDetIdLayerComparator(uint32_t layer) const {
0569     return std::make_pair(pxbDetId(layer, 1, 1), SameLayerComparator(this));
0570   }
0571 
0572   std::pair<DetId, SameLayerComparator> pxfDetIdDiskComparator(uint32_t side, uint32_t disk) const {
0573     return std::make_pair(pxfDetId(side, disk, 1, 1, 1), SameLayerComparator(this));
0574   }
0575 
0576   std::pair<DetId, SameLayerComparator> tecDetIdWheelComparator(uint32_t side, uint32_t wheel) const {
0577     return std::make_pair(tecDetId(side, wheel, 1, 1, 1, 1, 1), SameLayerComparator(this));
0578   }
0579 
0580   std::pair<DetId, SameLayerComparator> tibDetIdLayerComparator(uint32_t layer) const {
0581     return std::make_pair(tibDetId(layer, 1, 1, 1, 1, 1), SameLayerComparator(this));
0582   }
0583 
0584   std::pair<DetId, SameLayerComparator> tidDetIdWheelComparator(uint32_t side, uint32_t wheel) const {
0585     return std::make_pair(tidDetId(side, wheel, 1, 1, 1, 1), SameLayerComparator(this));
0586   }
0587 
0588   std::pair<DetId, SameLayerComparator> tobDetIdLayerComparator(uint32_t layer) const {
0589     return std::make_pair(tobDetId(layer, 1, 1, 1, 1), SameLayerComparator(this));
0590   }
0591 
0592   std::string print(DetId detid) const;
0593 
0594   SiStripModuleGeometry moduleGeometry(const DetId &id) const;
0595 
0596   int getOTLayerNumber(const DetId &id) const;
0597   int getITPixelLayerNumber(const DetId &id) const;
0598 
0599   // Those is only implemented for Pixel right now, but can be extended to all
0600   // subdetectors.
0601 
0602   // Extract the raw bit value for a given field type.
0603   // E.g. getField(id, PBLadder) == pxbLadder(id)
0604   unsigned int getField(const DetId &id, DetIdFields idx) const {
0605     return ((id.rawId() >> bits_per_field[idx].startBit) & bits_per_field[idx].mask);
0606   }
0607   // checks whether a given field can be extracted from a given DetId.
0608   // This boils down to checking whether it is the correct subdetector.
0609   bool hasField(const DetId &id, DetIdFields idx) const { return id.subdetId() == bits_per_field[idx].subdet; }
0610 
0611 private:
0612   const PixelBarrelValues pbVals_;
0613   const PixelEndcapValues pfVals_;
0614 
0615   const TOBValues tobVals_;
0616   const TIBValues tibVals_;
0617   const TIDValues tidVals_;
0618   const TECValues tecVals_;
0619 
0620   struct BitmaskAndSubdet {
0621     unsigned int startBit;
0622     unsigned int mask;
0623     int subdet;
0624   };
0625   const BitmaskAndSubdet bits_per_field[DETID_FIELDS_MAX];
0626 };
0627 
0628 #endif