Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-19 23:19:55

0001 #ifndef DataFormats_SiStripDetId_SiStripDetId_h
0002 #define DataFormats_SiStripDetId_SiStripDetId_h
0003 
0004 #include "DataFormats/DetId/interface/DetId.h"
0005 #include "DataFormats/SiStripDetId/interface/SiStripEnums.h"
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 #include <ostream>
0008 
0009 class SiStripDetId;
0010 
0011 /** Debug info for SiStripDetId class. */
0012 std::ostream &operator<<(std::ostream &, const SiStripDetId &);
0013 
0014 /**
0015     @class SiStripDetId
0016     @author R.Bainbridge
0017     @brief Detector identifier class for the strip tracker.
0018 */
0019 class SiStripDetId : public DetId {
0020 public:
0021   // ---------- Constructors, enumerated types ----------
0022 
0023   /** Construct a null id */
0024   SiStripDetId() : DetId() { ; }
0025 
0026   /** Construct from a raw value */
0027   SiStripDetId(const uint32_t &raw_id) : DetId(raw_id) { ; }
0028 
0029   /** Construct from generic DetId */
0030   SiStripDetId(const DetId &det_id) : DetId(det_id.rawId()) { ; }
0031 
0032   /** Construct and fill only the det and sub-det fields. */
0033   SiStripDetId(Detector det, int subdet) : DetId(det, subdet) { ; }
0034 
0035   /** Enumerated type for tracker sub-deteector systems. */
0036   using SubDetector = SiStripSubdetector::Subdetector;
0037   static constexpr auto UNKNOWN = SiStripSubdetector::UNKNOWN;
0038   static constexpr auto TIB = SiStripSubdetector::TIB;
0039   static constexpr auto TID = SiStripSubdetector::TID;
0040   static constexpr auto TOB = SiStripSubdetector::TOB;
0041   static constexpr auto TEC = SiStripSubdetector::TEC;
0042 
0043   // ---------- Common methods ----------
0044 
0045   /** Returns enumerated type specifying sub-detector. */
0046   inline SubDetector subDetector() const;
0047 
0048   /** Returns enumerated type specifying sub-detector. */
0049   inline SiStripModuleGeometry moduleGeometry() const;
0050 
0051   /** A non-zero value means a glued module, null means not glued. */
0052   inline uint32_t glued() const;
0053 
0054   /** A non-zero value means a stereo module, null means not stereo. */
0055   inline uint32_t stereo() const;
0056 
0057   /** Returns DetId of the partner module if glued, otherwise null. */
0058   inline uint32_t partnerDetId() const;
0059 
0060   /** Returns strip length of strip tracker sensor, otherwise null. */
0061   inline double stripLength() const;
0062 
0063   /** Returns number of APVs connected to each strip tracker module */
0064   inline unsigned int numberOfAPVs() const;
0065 
0066   // ---------- Constructors that set "reserved" field ----------
0067 
0068   /** Construct from a raw value and set "reserved" field. */
0069   SiStripDetId(const uint32_t &raw_id, const uint16_t &reserved) : DetId(raw_id) {
0070     id_ &= (~static_cast<uint32_t>(reservedMask_ << reservedStartBit_));
0071     id_ |= ((reserved & reservedMask_) << reservedStartBit_);
0072   }
0073 
0074   // -----------------------------------------------------------------------------
0075   //
0076 
0077   /** Construct from generic DetId and set "reserved" field. */
0078   SiStripDetId(const DetId &det_id, const uint16_t &reserved) : DetId(det_id.rawId()) {
0079     id_ &= (~static_cast<uint32_t>(reservedMask_ << reservedStartBit_));
0080     id_ |= ((reserved & reservedMask_) << reservedStartBit_);
0081   }
0082 
0083   /** Returns value of "reserved" field. */
0084   inline uint16_t reserved() const;
0085 
0086 private:
0087   /** Position of "reserved" bit field. */
0088   static const uint16_t reservedStartBit_ = 20;
0089 
0090   /** */
0091   static const uint32_t sterStartBit_ = 0;
0092 
0093   /** Mask for "reserved" bit field (3-bits wide). */
0094   static const uint16_t reservedMask_ = 0x7;
0095 
0096   /** */
0097   static const uint32_t sterMask_ = 0x3;
0098 
0099   static const unsigned layerStartBit_ = 14;
0100   static const unsigned layerMask_ = 0x7;
0101   static const unsigned ringStartBitTID_ = 9;
0102   static const unsigned ringMaskTID_ = 0x3;
0103   static const unsigned ringStartBitTEC_ = 5;
0104   static const unsigned ringMaskTEC_ = 0x7;
0105 };
0106 
0107 // ---------- inline methods ----------
0108 
0109 SiStripDetId::SubDetector SiStripDetId::subDetector() const {
0110   return static_cast<SiStripDetId::SubDetector>(subdetId());
0111 }
0112 
0113 SiStripModuleGeometry SiStripDetId::moduleGeometry() const {
0114   auto geometry = SiStripModuleGeometry::UNKNOWNGEOMETRY;
0115   switch (subDetector()) {
0116     case TIB:
0117       geometry =
0118           int((id_ >> layerStartBit_) & layerMask_) < 3 ? SiStripModuleGeometry::IB1 : SiStripModuleGeometry::IB2;
0119       break;
0120     case TOB:
0121       geometry =
0122           int((id_ >> layerStartBit_) & layerMask_) < 5 ? SiStripModuleGeometry::OB2 : SiStripModuleGeometry::OB1;
0123       break;
0124     case TID:
0125       switch ((id_ >> ringStartBitTID_) & ringMaskTID_) {
0126         case 1:
0127           geometry = SiStripModuleGeometry::W1A;
0128           break;
0129         case 2:
0130           geometry = SiStripModuleGeometry::W2A;
0131           break;
0132         case 3:
0133           geometry = SiStripModuleGeometry::W3A;
0134           break;
0135       }
0136       break;
0137     case TEC:
0138       switch ((id_ >> ringStartBitTEC_) & ringMaskTEC_) {
0139         case 1:
0140           geometry = SiStripModuleGeometry::W1B;
0141           break;
0142         case 2:
0143           geometry = SiStripModuleGeometry::W2B;
0144           break;
0145         case 3:
0146           geometry = SiStripModuleGeometry::W3B;
0147           break;
0148         case 4:
0149           geometry = SiStripModuleGeometry::W4;
0150           break;
0151         case 5:
0152           geometry = SiStripModuleGeometry::W5;
0153           break;
0154         case 6:
0155           geometry = SiStripModuleGeometry::W6;
0156           break;
0157         case 7:
0158           geometry = SiStripModuleGeometry::W7;
0159           break;
0160       }
0161     case UNKNOWN:
0162     default:;
0163   }
0164   return geometry;
0165 }
0166 
0167 uint32_t SiStripDetId::glued() const {
0168   uint32_t testId = (id_ >> sterStartBit_) & sterMask_;
0169   return (testId == 0) ? 0 : (id_ - testId);
0170 }
0171 
0172 uint32_t SiStripDetId::stereo() const { return (((id_ >> sterStartBit_) & sterMask_) == 1) ? 1 : 0; }
0173 
0174 uint32_t SiStripDetId::partnerDetId() const {
0175   uint32_t testId = (id_ >> sterStartBit_) & sterMask_;
0176   if (testId == 1) {
0177     testId = id_ + 1;
0178   } else if (testId == 2) {
0179     testId = id_ - 1;
0180   } else {
0181     testId = 0;
0182   }
0183   return testId;
0184 }
0185 
0186 double SiStripDetId::stripLength() const { return 0.; }
0187 
0188 uint16_t SiStripDetId::reserved() const { return static_cast<uint16_t>((id_ >> reservedStartBit_) & reservedMask_); }
0189 
0190 unsigned int SiStripDetId::numberOfAPVs() const {
0191   const auto &moduleGeometry = this->moduleGeometry();
0192 
0193   // Check for unknown geometry and throw a meaningful exception
0194   if (moduleGeometry == SiStripModuleGeometry::UNKNOWNGEOMETRY) {
0195     throw cms::Exception("InvalidModuleGeometry")
0196         << "Error in SiStripDetId::numberOfAPVs(): Module geometry is UNKNOWNGEOMETRY. "
0197         << "This indicates an invalid or unsupported module geometry for the current DetId: " << this->rawId();
0198   }
0199 
0200   // Determine the number of APVs based on the module geometry
0201   if (moduleGeometry == SiStripModuleGeometry::IB1 || moduleGeometry == SiStripModuleGeometry::OB1 ||
0202       moduleGeometry == SiStripModuleGeometry::W1A || moduleGeometry == SiStripModuleGeometry::W1B ||
0203       moduleGeometry == SiStripModuleGeometry::W2A || moduleGeometry == SiStripModuleGeometry::W2B ||
0204       moduleGeometry == SiStripModuleGeometry::W5) {
0205     return 6;
0206   } else {
0207     return 4;
0208   }
0209 }
0210 
0211 #endif  // DataFormats_SiStripDetId_SiStripDetId_h