Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:23

0001 #ifndef MuonDetId_CSCIndexerOldStartup_h
0002 #define MuonDetId_CSCIndexerOldStartup_h
0003 
0004 /** \class CSCIndexerOldStartup
0005  * Creates a linear index for various sublevels of the endcap muon CSC system.
0006  *
0007  * It supplies a linear index for:
0008  * 1. Each chamber of the CSC system: range 1-468 (CSC system as installed 2008)
0009  * 469-540 for ME42 <br>
0010  * 2. Each layer of the CSC system: range 1-2808 (CSCs 2008) 2809-3240 for ME42
0011  * <br>
0012  * 3. Each strip channel of the CSC system: range 1-217728 (CSCs 2008)
0013  * 217729-252288 for ME42 <br>
0014  * 4. Each Buckeye chip (1 for each layer in each CFEB)of the CSC system: range
0015  * 1-13608 (CSCs 2008) 13609-15768 for ME42 <br>
0016  * 5. Each Gas Gain Sector (1 for each [CFEB*HV segment] combination in each
0017  * layer): range 1-45144 (CSCs 2008) 45145-55944 for ME42 <br>
0018  *
0019  * The chamber and layer may be specified by CSCDetId or labels for endcap,
0020  * station, ring, chamber, layer. The strip channel is a value 1-80 (or 64: ME13
0021  * chambers have only 64 channels.) The chip number is a value 1-30 (or 24: ME13
0022  * chambers have only 24 chips.)
0023  *
0024  * The main user interface is the set of functions <br>
0025  *   chamberIndex(.) <br>
0026  *   layerIndex(.) <br>
0027  *   stripChannelIndex(.) <br>
0028  *   chipIndex(.) <br>
0029  * But the other functions are public since they may be useful in contexts other
0030  * than for Conditions Data for which the above functions are intended.
0031  *
0032  * \warning This class is hard-wired for the CSC system at start-up of CMS in
0033  * 2008. with rings ME11, ME12, ME13, ME21, ME22, ME31, ME32, ME41 totalling 234
0034  * chambers per endcap. But ME42 is appended (to permit simulation studies), so
0035  * the chamber order is <br> +z ME11, ME12, ME13, ME21, ME22, ME31, ME32, ME41,
0036  * <br> -z ME11, ME12, ME13, ME21, ME22, ME31, ME32, ME41, <br> +z ME42, -z ME42
0037  * <br>
0038  *
0039  * \warning This uses magic numbers galore!!
0040  *
0041  * \warning EVERY LABEL COUNTS FROM ONE NOT ZERO.
0042  *
0043  */
0044 
0045 #include <DataFormats/MuonDetId/interface/CSCDetId.h>
0046 #include <iosfwd>
0047 #include <utility>  // for pair
0048 #include <vector>
0049 
0050 class CSCIndexerOldStartup {
0051 public:
0052   //  typedef unsigned short int IndexType;
0053   //  typedef unsigned       int LongIndexType;
0054   typedef uint16_t IndexType;
0055   typedef uint32_t LongIndexType;
0056 
0057   CSCIndexerOldStartup(){};
0058   ~CSCIndexerOldStartup(){};
0059 
0060   /**
0061    * Linear index to label each CSC in CSC system.
0062    * Argument is the CSCDetId of some CSCChamber.
0063    *
0064    * Output is 1-468 (CSCs 2008) 469-540 (ME42)
0065    *
0066    * WARNING: Do not input ME1a values (i.e. ring '4'): does not consider ME1a
0067    * and ME1b to be separate, No sanity checking on input value: if you supply
0068    * an ME1a CSCDetId then you'll get nonsense.
0069    */
0070 
0071   IndexType chamberIndex(const CSCDetId &id) const {
0072     return chamberIndex(id.endcap(), id.station(), id.ring(), id.chamber());
0073   }
0074 
0075   /**
0076    * Linear index to label each hardware layer in CSC system.
0077    * Argument is the CSCDetId of some CSCLayer.
0078    *
0079    * Output is 1-2808 (CSCs 2008) 2809-3240 (ME42)
0080    *
0081    * WARNING: Do not input ME1a values (i.e. ring '4'): does not consider ME1a
0082    * and ME1b to be separate, No sanity checking on input value: if you supply
0083    * an ME1a CSCDetId then you'll get nonsense.
0084    */
0085 
0086   IndexType layerIndex(const CSCDetId &id) const {
0087     return layerIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer());
0088   }
0089 
0090   /**
0091    * Starting index for first chamber in ring 'ir' of station 'is' in endcap
0092    * 'ie', in range 1-468 (CSCs 2008) or 469-540 (ME42).
0093    */
0094   IndexType startChamberIndexInEndcap(IndexType ie, IndexType is, IndexType ir) const {
0095     const IndexType nschin[24] = {1,   37,  73,  109, 127, 0, 163, 181, 0, 217, 469, 0,
0096                                   235, 271, 307, 343, 361, 0, 397, 415, 0, 451, 505, 0};
0097     return nschin[(ie - 1) * 12 + (is - 1) * 3 + ir - 1];
0098   }
0099 
0100   /**
0101    * Linear index for chamber 'ic' in ring 'ir' of station 'is' in endcap 'ie',
0102    * in range 1-468 (CSCs 2008) or 469-540 (ME42)
0103    */
0104   IndexType chamberIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic) const {
0105     return startChamberIndexInEndcap(ie, is, ir) + ic - 1;  // -1 so start index _is_ ic=1
0106   }
0107 
0108   /**
0109    * Linear index for layer 'il' of chamber 'ic' in ring 'ir' of station 'is' in
0110    * endcap 'ie', in range 1-2808 (CSCs 2008) or 2809-3240 (ME42).
0111    */
0112   IndexType layerIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il) const {
0113     const IndexType layersInChamber = 6;
0114     return (chamberIndex(ie, is, ir, ic) - 1) * layersInChamber + il;
0115   }
0116 
0117   /**
0118    * How many rings are there in station is=1, 2, 3, 4 ?
0119    *
0120    * BEWARE! Includes ME42 so claims 2 rings in station 4. There is only 1 at
0121    * CSC installation 2008.
0122    */
0123   IndexType ringsInStation(IndexType is) const {
0124     const IndexType nrins[5] = {0, 3, 2, 2, 2};  // rings per station
0125     return nrins[is];
0126   }
0127 
0128   /**
0129    * How many chambers are there in ring ir of station is?
0130    *
0131    * Works for ME1a (ring 4 of ME1) too.
0132    */
0133   IndexType chambersInRingOfStation(IndexType is, IndexType ir) const {
0134     IndexType nc = 36;  // most rings have 36 chambers
0135     if (is > 1 && ir < 2)
0136       nc = 18;  // but 21, 31, 41 have 18
0137     return nc;
0138   }
0139 
0140   /**
0141    * Number of strip channels per layer in a chamber in ring ir of station is.
0142    *
0143    * Station label range 1-4, Ring label range 1-3.
0144    *
0145    * WARNING: ME1a channels are the last 16 of the 80 total in each layer of an
0146    * ME11 chamber, and an input ir=4 is invalid and will give nonsense. <br>
0147    * Considers ME42 as standard 80-strip per layer chambers.
0148    */
0149   IndexType stripChannelsPerLayer(IndexType is, IndexType ir) const {
0150     const IndexType nSCinC[12] = {80, 80, 64, 80, 80, 0, 80, 80, 0, 80, 80, 0};
0151     return nSCinC[(is - 1) * 3 + ir - 1];
0152   }
0153 
0154   /**
0155    * Linear index for 1st strip channel in ring 'ir' of station 'is' in endcap
0156    * 'ie'.
0157    *
0158    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-3.
0159    *
0160    * WARNING: ME1a channels are the last 16 of the 80 total in each layer of an
0161    * ME11 chamber, and an input ir=4 is invalid and will give nonsense.
0162    */
0163   LongIndexType stripChannelStart(IndexType ie, IndexType is, IndexType ir) const {
0164     // These are in the ranges 1-217728 (CSCs 2008) and 217729-252288 (ME42).
0165     // There are 1-108884 channels per endcap (CSCs 2008) and 17280 channels per
0166     // endcap (ME42). Start of -z channels (CSCs 2008) is 108864 + 1 = 108865
0167     // Start of +z (ME42) is 217728 + 1 = 217729
0168     // Start of -z (ME42) is 217728 + 1 + 17280 = 235009
0169     const LongIndexType nStart[24] = {1,      17281,  34561,  48385,  57025,  0, 74305,  82945,  0, 100225, 217729, 0,
0170                                       108865, 126145, 143425, 157249, 165889, 0, 183169, 191809, 0, 209089, 235009, 0};
0171     return nStart[(ie - 1) * 12 + (is - 1) * 3 + ir - 1];
0172   }
0173 
0174   /**
0175    * Linear index for strip channel istrip in layer 'il' of chamber 'ic' of ring
0176    * 'ir' in station 'is' of endcap 'ie'.
0177    *
0178    * Output is 1-217728 (CSCs 2008) or 217729-252288 (ME42).
0179    *
0180    * WARNING: Use at your own risk! You must input labels within hardware
0181    * ranges. No trapping on out-of-range values!
0182    */
0183   LongIndexType stripChannelIndex(
0184       IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il, IndexType istrip) const {
0185     return stripChannelStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * stripChannelsPerLayer(is, ir) + (istrip - 1);
0186   }
0187 
0188   /**
0189    * Linear index for strip channel 'istrip' in layer labelled by CSCDetId 'id'.
0190    *
0191    * Output is 1-217728 (CSCs 2008) or 217729-252288 (ME42).
0192    *
0193    * WARNING: Use at your own risk! The supplied CSCDetId must be a layer id.
0194    * No trapping on out-of-range values!
0195    */
0196 
0197   LongIndexType stripChannelIndex(const CSCDetId &id, IndexType istrip) const {
0198     return stripChannelIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), istrip);
0199   }
0200 
0201   /**
0202    * Number of Buckeye chips per layer in a chamber in ring ir of station is.
0203    *
0204    * Station label range 1-4, Ring label range 1-3.
0205    *
0206    * WARNING: ME1a channels are the last 1 of the 5 total in each layer of an
0207    * ME11 chamber, and an input ir=4 is invalid and will give nonsense. <br>
0208    * Considers ME42 as standard 5 chip per layer chambers.
0209    */
0210   IndexType chipsPerLayer(IndexType is, IndexType ir) const {
0211     const IndexType nCinL[12] = {5, 5, 4, 5, 5, 0, 5, 5, 0, 5, 5, 0};
0212     return nCinL[(is - 1) * 3 + ir - 1];
0213   }
0214 
0215   /**
0216    * Linear index for 1st Buckey chip in ring 'ir' of station 'is' in endcap
0217    * 'ie'.
0218    *
0219    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-3.
0220    *
0221    * WARNING: ME1a channels are the last 1 of the 5 chips total in each layer of
0222    * an ME11 chamber, and an input ir=4 is invalid and will give nonsense.
0223    */
0224   IndexType chipStart(IndexType ie, IndexType is, IndexType ir) const {
0225     // These are in the ranges 1-13608 (CSCs 2008) and 13609-15768 (ME42).
0226     // There are 1-6804 chips per endcap (CSCs 2008) and 1080 channels per
0227     // endcap (ME42). Start of -z channels (CSCs 2008) is 6804 + 1 = 6805 Start
0228     // of +z (ME42) is 13608 + 1 = 13609 Start of -z (ME42) is 13608 + 1 + 1080
0229     // = 14689
0230     const IndexType nStart[24] = {1,    1081, 2161, 3025, 3565,  0, 4645,  5185,  0, 6265,  13609, 0,
0231                                   6805, 7885, 8965, 9829, 10369, 0, 11449, 11989, 0, 13069, 14689, 0};
0232 
0233     return nStart[(ie - 1) * 12 + (is - 1) * 3 + ir - 1];
0234   }
0235 
0236   /**
0237    * Linear index for Buckeye chip 'ichip' in layer 'il' of chamber 'ic' of ring
0238    * 'ir' in station 'is' of endcap 'ie'.
0239    *
0240    * Output is 1-13608 (CSCs 2008) or 13609-15768 (ME42).
0241    *
0242    * WARNING: Use at your own risk! You must input labels within hardware
0243    * ranges. No trapping on out-of-range values!
0244    */
0245   IndexType chipIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il, IndexType ichip) const {
0246     // printf("ME%d/%d/%d/%d layer %d  chip %d chipindex
0247     // %d\n",ie,is,ir,ic,il,ichip,chipStart(ie,is,ir)+( (ic-1)*6 + il - 1
0248     // )*chipsPerLayer(is,ir) + (ichip-1));
0249     return chipStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * chipsPerLayer(is, ir) + (ichip - 1);
0250   }
0251 
0252   /**
0253    * Linear index for Buckeye chip 'ichip' in layer labelled by CSCDetId 'id'.
0254    *
0255    * Output is 1-13608 (CSCs 2008) or 13609-15768 (ME42).
0256    *
0257    * WARNING: Use at your own risk! The supplied CSCDetId must be a layer id.
0258    * No trapping on out-of-range values!
0259    */
0260 
0261   IndexType chipIndex(const CSCDetId &id, IndexType ichip) const {
0262     return chipIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), ichip);
0263   }
0264 
0265   /**
0266    * Linear index for Buckeye chip processing strip 'istrip'.
0267    *
0268    * Output is 1-5.
0269    *
0270    * WARNING: Use at your own risk! The supplied CSCDetId must be a strip id
0271    * 1-80 ME1/1a strips must be 65-80 No trapping on out-of-range values!
0272    */
0273 
0274   IndexType chipIndex(IndexType istrip) const { return (istrip - 1) / 16 + 1; }
0275 
0276   /**
0277    * Number of HV segments per layer in a chamber in ring ir of station is.
0278    *
0279    * Station label range 1-4, Ring label range 1-3.
0280    *
0281    * WARNING: ME1a channels are the last 1 of the 5 total in each layer of an
0282    * ME11 chamber, and an input ir=4 is invalid and will give nonsense. <br>
0283    */
0284   IndexType hvSegmentsPerLayer(IndexType is, IndexType ir) const {
0285     const IndexType nSinL[12] = {1, 3, 3, 3, 5, 0, 3, 5, 0, 3, 5, 0};
0286     return nSinL[(is - 1) * 3 + ir - 1];
0287   }
0288 
0289   /**
0290    * Number of Gas Gain sectors per layer in a chamber in ring ir of station is.
0291    *
0292    * Station label range 1-4, Ring label range 1-3.
0293    *
0294    * WARNING: ME1a channels are the last 1 of the 5 total in each layer of an
0295    * ME11 chamber, and an input ir=4 is invalid and will give nonsense. <br>
0296    */
0297   IndexType sectorsPerLayer(IndexType is, IndexType ir) const {
0298     return chipsPerLayer(is, ir) * hvSegmentsPerLayer(is, ir);
0299   }
0300 
0301   /**
0302    * Linear index for HV segment
0303    *
0304    * Output is 1-5.
0305    *
0306    * WARNING: Use at your own risk! The supplied CSCDetId must be chamber
0307    * station, ring, and wire. No trapping on out-of-range values!
0308    */
0309   IndexType hvSegmentIndex(IndexType is, IndexType ir, IndexType iwire) const {
0310     IndexType hvSegment = 1;  // There is only one HV segment in ME1/1
0311 
0312     if (is > 2 && ir == 1) {  // HV segments are the same in ME3/1 and ME4/1
0313       if (iwire >= 33 && iwire <= 64) {
0314         hvSegment = 2;
0315       } else if (iwire >= 65 && iwire <= 96) {
0316         hvSegment = 3;
0317       }
0318 
0319     } else if (is > 1 && ir == 2) {  // HV segments are the same in ME2/2, ME3/2, and ME4/2
0320       if (iwire >= 17 && iwire <= 28) {
0321         hvSegment = 2;
0322       } else if (iwire >= 29 && iwire <= 40) {
0323         hvSegment = 3;
0324       } else if (iwire >= 41 && iwire <= 52) {
0325         hvSegment = 4;
0326       } else if (iwire >= 53 && iwire <= 64) {
0327         hvSegment = 5;
0328       }
0329 
0330     } else if (is == 1 && ir == 2) {
0331       if (iwire >= 25 && iwire <= 48) {
0332         hvSegment = 2;
0333       } else if (iwire >= 49 && iwire <= 64) {
0334         hvSegment = 3;
0335       }
0336 
0337     } else if (is == 1 && ir == 3) {
0338       if (iwire >= 13 && iwire <= 22) {
0339         hvSegment = 2;
0340       } else if (iwire >= 23 && iwire <= 32) {
0341         hvSegment = 3;
0342       }
0343 
0344     } else if (is == 2 && ir == 1) {
0345       if (iwire >= 45 && iwire <= 80) {
0346         hvSegment = 2;
0347       } else if (iwire >= 81 && iwire <= 112) {
0348         hvSegment = 3;
0349       }
0350     }
0351 
0352     return hvSegment;
0353   }
0354 
0355   /**
0356    * Linear index for 1st Gas gain sector in ring 'ir' of station 'is' in endcap
0357    * 'ie'.
0358    *
0359    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-3.
0360    *
0361    * WARNING: ME1a channels are the last 1 of the 5 chips total in each layer of
0362    * an ME11 chamber, and an input ir=4 is invalid and will give nonsense.
0363    */
0364   IndexType sectorStart(IndexType ie, IndexType is, IndexType ir) const {
0365     // There are 36 chambers * 6 layers * 5 CFEB's * 1 HV segment = 1080
0366     // gas-gain sectors in ME1/1 There are 36*6*5*3 = 3240 gas-gain sectors in
0367     // ME1/2 There are 36*6*4*3 = 2592 gas-gain sectors in ME1/3 There are
0368     // 18*6*5*3 = 1620 gas-gain sectors in ME[2-4]/1 There are 36*6*5*5 = 5400
0369     // gas-gain sectors in ME[2-4]/2 Start of -z channels (CSCs 2008) is 22572 +
0370     // 1 = 22573 Start of +z (ME42) is 45144 + 1 = 45145 Start of -z (ME42) is
0371     // 45144 + 1 + 5400 = 50545
0372     const IndexType nStart[24] = {1,     1081,
0373                                   4321,  // ME+1/1,ME+1/2,ME+1/3
0374                                   6913,  8533,
0375                                   0,  // ME+2/1,ME+2/2,ME+2/3
0376                                   13933, 15553,
0377                                   0,  // ME+3/1,ME+3/2,ME+3/3
0378                                   20953, 45145,
0379                                   0,  // ME+4/1,ME+4/2,ME+4/3 (note, ME+4/2 index follows ME-4/1...)
0380                                   22573, 23653,
0381                                   26893,  // ME-1/1,ME-1/2,ME-1/3
0382                                   29485, 31105,
0383                                   0,  // ME-2/1,ME-2/2,ME-2/3
0384                                   36505, 38125,
0385                                   0,                 // ME-3/1,ME-3/2,ME-3/3
0386                                   43525, 50545, 0};  // ME-4/1,ME-4/2,ME-4/3 (note, ME-4/2 index follows ME+4/2...)
0387     return nStart[(ie - 1) * 12 + (is - 1) * 3 + ir - 1];
0388   }
0389 
0390   /**
0391    * Linear index for Gas gain sector, based on the HV segment# and the chip#
0392    * located in layer 'il' of chamber 'ic' of ring 'ir' in station 'is' of
0393    * endcap 'ie'.
0394    *
0395    * Output is 1-45144 (CSCs 2008) and 45145-55944 (ME42) and 55945-57240 (ME1a)
0396    *
0397    * \warning: You must input labels within hardware ranges. No trapping on
0398    * out-of-range values! E.g., if you provide ir=4 in ganged case, it would
0399    * still be treated the same as ir=1, but ichip must be 5 for it to make
0400    * sense!
0401    */
0402   IndexType gasGainIndex(IndexType ie,
0403                          IndexType is,
0404                          IndexType ir,
0405                          IndexType ic,
0406                          IndexType il,
0407                          IndexType ihvsegment,
0408                          IndexType ichip) const {
0409     return sectorStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * sectorsPerLayer(is, ir) +
0410            (ihvsegment - 1) * chipsPerLayer(is, ir) + (ichip - 1);
0411   }
0412 
0413   /**
0414    * Linear index for Gas gain sector, based on CSCDetId 'id', cathode strip
0415    * 'istrip' and anode wire 'iwire'
0416    *
0417    * \warning: You must input labels within hardware ranges (e.g., 'id' must
0418    * correspond to a specific layer 1-6). No trapping on out-of-range values!
0419    * E.g., if you provide ME1a id in ganged case, it would still be treated the
0420    * same as whole ME11 id, but istrip must be a h/w strip number in 64-80 in
0421    * that case!
0422    */
0423   IndexType gasGainIndex(const CSCDetId &id, IndexType istrip, IndexType iwire) const {
0424     return gasGainIndex(id.endcap(),
0425                         id.station(),
0426                         id.ring(),
0427                         id.chamber(),
0428                         id.layer(),
0429                         hvSegmentIndex(id.station(), id.ring(), iwire),
0430                         chipIndex(istrip));
0431   }
0432 
0433   /**
0434    * Linear index for Gas gain sector, based on CSCDetId 'id', the HV segment#
0435    * and the chip#. Note: to allow method overloading, the parameters order is
0436    * reversed comparing to the (id,strip,wire) method
0437    *
0438    * Output is 1-45144 (CSCs 2008) and 45145-55944 (ME42) and 55945-57240 (ME1a)
0439    *
0440    * \warning: Use at your own risk! You must input labels within hardware
0441    * ranges. No trapping on out-of-range values! The supplied CSCDetId must be a
0442    * layer id, and ichip must be h/w chip number in a chamber. E.g., if you
0443    * provide ME1a id in ganged case, it would still be treated the same as whole
0444    * ME11 id, but ichip must be 5 for it to make sense!
0445    */
0446   IndexType gasGainIndex(IndexType ihvsegment, IndexType ichip, const CSCDetId &id) const {
0447     return gasGainIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), ihvsegment, ichip);
0448   }
0449 
0450   /**
0451    *  Decode CSCDetId from various indexes and labels
0452    */
0453   CSCDetId detIdFromLayerIndex(IndexType ili) const;
0454   CSCDetId detIdFromChamberIndex(IndexType ici) const;
0455   CSCDetId detIdFromChamberIndex_OLD(IndexType ici) const;
0456   CSCDetId detIdFromChamberLabel(IndexType ie, IndexType icl) const;
0457   std::pair<CSCDetId, IndexType> detIdFromStripChannelIndex(LongIndexType ichi) const;
0458   std::pair<CSCDetId, IndexType> detIdFromChipIndex(IndexType ichi) const;
0459 
0460   IndexType chamberLabelFromChamberIndex(IndexType) const;  // just for cross-checks
0461 
0462   /**
0463    * Build index used internally in online CSC conditions databases (the 'Igor
0464    * Index')
0465    *
0466    * This is the decimal integer ie*100000 + is*10000 + ir*1000 + ic*10 + il
0467    * <br> (ie=1-2, is=1-4, ir=1-4, ic=1-36, il=1-6) <br> Channels 1-16 in ME1A
0468    * (is=1, ir=4) are reset to channels 65-80 of ME11.
0469    */
0470   int dbIndex(const CSCDetId &id, int &channel);
0471 
0472 private:
0473   void fillChamberLabel() const;  // const so it can be called in const function
0474                                   // detIdFromChamberIndex
0475 
0476   mutable std::vector<IndexType> chamberLabel;  // mutable so can be filled by fillChamberLabel
0477 };
0478 
0479 #endif