Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:46

0001 #ifndef MuonDetId_CSCDetId_h
0002 #define MuonDetId_CSCDetId_h
0003 
0004 /** \class CSCDetId
0005  * Identifier class for hierarchy of Endcap Muon detector components.
0006  *
0007  * Ported from MuEndDetectorId but now derived from DetId and updated accordingly.
0008  *
0009  * Allows access to hardware integer labels of the subcomponents
0010  * of the Muon Endcap CSC detector system.
0011  *
0012  * The STATIC member functions can be used to translate back and
0013  * forth between a layer/chamber 'rawId' and the %set of subdetector labels.
0014  *
0015  * \warning EVERY LABEL COUNTS FROM ONE NOT ZERO.
0016  *
0017  */
0018 
0019 #include "DataFormats/DetId/interface/DetId.h"
0020 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0021 
0022 class CSCDetId;
0023 
0024 std::ostream& operator<<(std::ostream& os, const CSCDetId& id);
0025 
0026 class CSCDetId : public DetId {
0027 public:
0028   /// Default constructor; fills the common part in the base
0029   /// and leaves 0 in all other fields
0030   CSCDetId() : DetId(DetId::Muon, MuonSubdetId::CSC) {}
0031 
0032   /// Construct from a packed id. It is required that the Detector part of
0033   /// id is Muon and the SubDet part is CSC, otherwise an exception is thrown.
0034   CSCDetId(uint32_t id) : DetId(id) {}
0035   CSCDetId(DetId id) : DetId(id) {}
0036 
0037   /// Construct from fully qualified identifier.
0038   /// Input values are required to be within legal ranges, otherwise an
0039   /// exception is thrown.<br>
0040   /// iendcap: 1=forward (+Z), 2=backward(-Z)
0041   CSCDetId(int iendcap, int istation, int iring, int ichamber, int ilayer = 0) : DetId(DetId::Muon, MuonSubdetId::CSC) {
0042     id_ |= init(iendcap, istation, iring, ichamber, ilayer);
0043   }
0044 
0045   /** Chamber CSCDetId from a Layer CSCDetId
0046    */
0047   CSCDetId chamberId() const {
0048     // build chamber id by removing layer bits
0049     return CSCDetId(id_ - layer());
0050   }
0051 
0052   /**
0053    * Return Layer label.
0054    *
0055    */
0056   int layer() const { return (id_ & MASK_LAYER); }
0057 
0058   /**
0059    * Return Chamber label.
0060    *
0061    */
0062   int chamber() const { return ((id_ >> START_CHAMBER) & MASK_CHAMBER); }
0063 
0064   /**
0065    * Return Ring label.
0066    *
0067    */
0068   int ring() const {
0069     if (((id_ >> START_STATION) & MASK_STATION) == 1)
0070       return (detIdToInt((id_ >> START_RING) & MASK_RING));
0071     else
0072       return (((id_ >> START_RING) & MASK_RING));
0073   }
0074 
0075   /**
0076    * Return Station label.
0077    *
0078    */
0079   int station() const { return ((id_ >> START_STATION) & MASK_STATION); }
0080 
0081   /**
0082    * Return Endcap label. 1=forward (+Z); 2=backward (-Z)
0083    *
0084    */
0085   int endcap() const { return ((id_ >> START_ENDCAP) & MASK_ENDCAP); }
0086 
0087   /**
0088     * What is the sign of global z?
0089     *
0090     */
0091   short int zendcap() const { return (endcap() != 1 ? -1 : +1); }
0092 
0093   /**
0094     * Chamber type (integer 1-10)
0095     */
0096   unsigned short iChamberType() const { return iChamberType(station(), ring()); }
0097 
0098   /**
0099     * Geometric channel no. from geometric strip no. - identical except for ME1a ganged strips
0100     *
0101     * Note that 'Geometric' means increasing number corresponds to increasing local x coordinate.
0102     * \warning There is no attempt here to handle cabling or readout questions.
0103     * If you need that look at CondFormats/CSCObjects/CSCChannelTranslator.
0104     */
0105   int channel(int istrip) {
0106     if (ring() == 4)
0107       // strips 1-48 mapped to channels 1-16:
0108       // 1+17+33->1, 2+18+34->2, .... 16+32+48->16
0109       return 1 + (istrip - 1) % 16;
0110     else
0111       return istrip;
0112   }
0113 
0114   /**
0115    * Simple accessors
0116    */
0117   bool isME1a() const;
0118   bool isME1b() const;
0119   bool isME11() const;
0120   bool isME12() const;
0121   bool isME13() const;
0122   bool isME21() const;
0123   bool isME22() const;
0124   bool isME31() const;
0125   bool isME32() const;
0126   bool isME41() const;
0127   bool isME42() const;
0128 
0129   // static methods
0130   // Used when we need information about subdetector labels.
0131 
0132   /**
0133    * Returns the unique integer 'rawId' which labels each CSC layer.
0134    *
0135    * The arguments are the integer labels for, respectively,  <br>
0136    * endcap, station, ring, chamber, layer.
0137    *
0138    * \warning The input int args are expected to be .ge. 1 and there
0139    * is no sanity-checking for their upper limits.
0140    *
0141    * \warning The returned integers are not necessarily consecutive, i.e.
0142    * there are gaps. This is to permit computational efficiency
0143    * starting from the component ids.
0144    *
0145    */
0146   static int rawIdMaker(int iendcap, int istation, int iring, int ichamber, int ilayer) {
0147     return ((DetId::Muon & 0xF) << (DetId::kDetOffset)) |           // set Muon flag
0148            ((MuonSubdetId::CSC & 0x7) << (DetId::kSubdetOffset)) |  // set CSC flag
0149            init(iendcap, istation, iring, ichamber, ilayer);
0150   }  // set CSC id
0151 
0152   /**
0153     * Return Layer label for supplied CSCDetId index.
0154     *
0155     */
0156   static int layer(int index) { return (index & MASK_LAYER); }
0157 
0158   /**
0159     * Return Chamber label for supplied CSCDetId index.
0160     *
0161     */
0162   static int chamber(int index) { return ((index >> START_CHAMBER) & MASK_CHAMBER); }
0163 
0164   /**
0165     * Return Ring label for supplied CSCDetId index.
0166     *
0167     */
0168   static int ring(int index) {
0169     if (((index >> START_STATION) & MASK_STATION) == 1)
0170       return (detIdToInt((index >> START_RING) & MASK_RING));
0171     else
0172       return ((index >> START_RING) & MASK_RING);
0173   }
0174 
0175   /**
0176     * Return Station label for supplied CSCDetId index.
0177     *
0178     */
0179   static int station(int index) { return ((index >> START_STATION) & MASK_STATION); }
0180 
0181   /**
0182     * Return Endcap label for supplied CSCDetId index.
0183     *
0184     */
0185   static int endcap(int index) { return ((index >> START_ENDCAP) & MASK_ENDCAP); }
0186 
0187   /**
0188     * Return a unique integer 1-10 for a station, ring pair:
0189     *        1           for S = 1  and R=4 inner strip part of ME11 (ME1a)
0190     *      2,3,4 =  R+1  for S = 1  and R = 1,2,3 (ME11 means ME1b)
0191     *      5-10  = 2*S+R for S = 2,3,4 and R = 1,2
0192     */
0193   static unsigned short iChamberType(unsigned short istation, unsigned short iring);
0194 
0195   /**
0196     * Return trigger-level sector id for an Endcap Muon chamber.
0197     *
0198     * This method encapsulates the information about which chambers
0199     * are in which sectors, and may need updating according to
0200     * hardware changes, or software chamber indexing.
0201     *
0202     * Station 1 has 3 rings of 10-degree chambers. <br>
0203     * Stations 2, 3, 4 have an inner ring of 20-degree chambers
0204     * and an outer ring of 10-degree chambers. <br>
0205     *
0206     * Sectors are 60 degree slices of a station, covering both rings. <br>
0207     * For Station 1, there are subsectors of 30 degrees: 9 10-degree
0208     * chambers (3 each from ME1/1, ME1/2, ME1/3.) <br>
0209     *
0210     * The first sector starts at phi = 15 degrees so it matches Barrel Muon sectors.
0211     * We count from one not zero.
0212     *
0213     */
0214   int triggerSector() const;
0215 
0216   /**
0217     * Return trigger-level CSC id  within a sector for an Endcap Muon chamber.
0218     *
0219     * This id is an index within a sector such that the 3 inner ring chambers
0220     * (20 degrees each) are 1, 2, 3 (increasing counterclockwise) and the 6 outer ring
0221     * chambers (10 degrees each) are 4, 5, 6, 7, 8, 9 (again increasing counter-clockwise.)
0222     *
0223     * This method knows which chambers are part of which sector and returns
0224     * the chamber label/index/identifier accordingly.
0225     * Beware that this information is liable to change according to hardware
0226     * and software changes.
0227     *
0228     */
0229   int triggerCscId() const;
0230 
0231   /**
0232     * Lower and upper counts for the subdetector hierarchy
0233     */
0234   static int minEndcapId() { return MIN_ENDCAP; }
0235   static int maxEndcapId() { return MAX_ENDCAP; }
0236   static int minStationId() { return MIN_STATION; }
0237   static int maxStationId() { return MAX_STATION; }
0238   static int minRingId() { return MIN_RING; }
0239   static int maxRingId() { return MAX_RING; }
0240   static int minChamberId() { return MIN_CHAMBER; }
0241   static int maxChamberId() { return MAX_CHAMBER; }
0242   static int minLayerId() { return MIN_LAYER; }
0243   static int maxLayerId() { return MAX_LAYER; }
0244 
0245   /**
0246     * Returns the chamber name in the format
0247     * ME$sign$station/$ring/$chamber. Example: ME+1/1/9
0248     */
0249   static std::string chamberName(int endcap, int station, int ring, int chamber);
0250   static std::string chamberName(int iChamberType);
0251   std::string chamberName() const;
0252   /**
0253     * Returns the layer name in the format
0254     * ME$sign$station/$ring/$chamber/$layer. Example: ME+1/1/9/1
0255     */
0256   static std::string layerName(int endcap, int station, int ring, int chamber, int layer);
0257   std::string layerName() const;
0258 
0259 private:
0260   /**
0261    * Method for initialization within ctors.
0262    *
0263    */
0264   static uint32_t init(int iendcap, int istation, int iring, int ichamber, int ilayer) {
0265     if (istation == 1)
0266       iring = intToDetId(iring);
0267 
0268     return (ilayer & MASK_LAYER) | ((ichamber & MASK_CHAMBER) << START_CHAMBER) | ((iring & MASK_RING) << START_RING) |
0269            ((istation & MASK_STATION) << START_STATION) | ((iendcap & MASK_ENDCAP) << START_ENDCAP);
0270   }
0271 
0272   /**
0273    *
0274    * Methods for reordering CSCDetId for ME1 detectors.
0275    *
0276    * Internally the chambers are ordered (Station/Ring) as: ME1/a (1/1), ME1/b (1/2), ME1/2 (1/3), ME1/3 (1/4)
0277    * i.e. they are labelled within the DetId as if ME1a, ME1b, ME12, ME13 are rings 1, 2, 3, 4.
0278    * The offline software always considers rings 1, 2, 3, 4 as ME1b, ME12, ME13, ME1a so that at
0279    * least ME12 and ME13 have ring numbers which match in hardware and software!
0280    *
0281    */
0282   static int intToDetId(int iring) {
0283     // change iring = 1, 2, 3, 4 input to 2, 3, 4, 1 for use inside the DetId
0284     // i.e. ME1b, ME12, ME13, ME1a externally become stored internally in order ME1a, ME1b, ME12, ME13
0285     int i = (iring + 1) % 4;
0286     if (i == 0)
0287       i = 4;
0288     return i;
0289   }
0290 
0291   static int detIdToInt(int iring) {
0292     // reverse intToDetId: change 1, 2, 3, 4 inside the DetId to 4, 1, 2, 3 for external use
0293     // i.e. output ring # 1, 2, 3, 4 in ME1 means ME1b, ME12, ME13, ME1a as usual in the offline software.
0294     int i = (iring - 1);
0295     if (i == 0)
0296       i = 4;
0297     return i;
0298   }
0299 
0300   // The following define the bit-packing implementation...
0301 
0302   // The maximum numbers of various parts
0303   enum eMaxNum { MAX_ENDCAP = 2, MAX_STATION = 4, MAX_RING = 4, MAX_CHAMBER = 36, MAX_LAYER = 6 };
0304   // We count from 1
0305   enum eMinNum { MIN_ENDCAP = 1, MIN_STATION = 1, MIN_RING = 1, MIN_CHAMBER = 1, MIN_LAYER = 1 };
0306 
0307   // BITS_det is no. of binary bits required to label 'det' but allow 0 as a wild-card character
0308   // Keep as multiples of 3 so that number can be easily decodable from octal
0309   enum eNumBitDet { BITS_ENDCAP = 3, BITS_STATION = 3, BITS_RING = 3, BITS_CHAMBER = 6, BITS_LAYER = 3 };
0310 
0311   // MASK_det is binary bits set to pick off the bits for 'det' (defined as octal)
0312   enum eMaskBitDet { MASK_ENDCAP = 07, MASK_STATION = 07, MASK_RING = 07, MASK_CHAMBER = 077, MASK_LAYER = 07 };
0313 
0314   // START_det is bit position (counting from zero) at which bits for 'det' start in 'rawId' word
0315   enum eStartBitDet {
0316     START_CHAMBER = BITS_LAYER,
0317     START_RING = START_CHAMBER + BITS_CHAMBER,
0318     START_STATION = START_RING + BITS_RING,
0319     START_ENDCAP = START_STATION + BITS_STATION
0320   };
0321 };
0322 
0323 #endif