Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef CSCIndexerBase_H
0002 #define CSCIndexerBase_H
0003 
0004 /** \class CSCIndexerBase
0005  * ABC for CSCIndexer classes.
0006  *
0007  * A CSCIndexer class provides a linear index for various sublevels of the
0008  * endcap muon CSC system for use in access to information stored in the
0009  * Conditions Database. Only concrete derived classes can be instantiated.
0010  *
0011  * It supplies a linear index for:
0012  * 1. Each chamber of the CSC system: range 1-468 (CSC system as installed 2008)
0013  * 469-540 for ME42 <br>
0014  * 2. Each layer of the CSC system: range 1-2808 (CSCs 2008) 2809-3240 for ME42
0015  * <br>
0016  * 3. Each strip channel of the CSC system: range 1-217728 (CSCs 2008)
0017  * 217729-252288 for ME42 <br>
0018  * 4. Each Buckeye chip (1 for each layer in each CFEB) of the CSC system: range
0019  * 1-13608 (CSCs 2008) 13609-15768 for ME42 <br>
0020  * 5. Each Gas Gain Sector (1 for each [CFEB*HV segment] combination in each
0021  * layer): range 1-45144 (CSCs 2008) 45145-55944 for ME42 <br>
0022  *
0023  * The chamber and layer may be specified by CSCDetId or labels for endcap,
0024  * station, ring, chamber, layer.
0025  *
0026  * The strip channel is a value 1-80 for most chambers. <br>
0027  * ME1/3 and ME1/1B have 64 channels. <br>
0028  * ME1/1A has 16 channels at CMS startup (2008-2013) and 48 channels after Long
0029  * Shutdown 1 ('LS1' 2013-2014) <br> The chip number is a value 1-30 (or 24:
0030  * ME13 chambers have only 24 chips.)
0031  *
0032  * The main user interface is the set of functions <br>
0033  *   chamberIndex(.) <br>
0034  *   layerIndex(.) <br>
0035  *   stripChannelIndex(.) <br>
0036  *   chipIndex(.) <br>
0037  * But the other functions are public since they may be useful in contexts other
0038  * than for Conditions Data for which the above functions are intended.
0039  *
0040  * The terminology "label" can be confusing. <br>
0041  * The CSC project typically refers to an element of the CSC detector by
0042  * hardware labels endcap (+z, -z), station (1-4), ring (1-3), chamber (1-18 or
0043  * 1-36 depending on ring), layer (1-6). Strips (and wiregroups) are number 1-N
0044  * where N is the total number of strips in a given layer. <br> Offline, we turn
0045  * +z, -z into integers 1, 2 and extend the ring index to 4 to mean ME1/1A
0046  * (leaving ring 1 in station 1 to mean ME1/1B when dealing with strip planes.
0047  * Since there is only one common wire plane sometimes ring 1, station 1 means
0048  * the entire ME1/1 and sometimes just ME1/1B.)
0049  * So in offline code, when we talk about "labels" for an element, we typically
0050  * mean these integer values. <br> For example, strip 71 of layer 4 of chamber
0051  * 17 of ME-3/1 is labelled {ie=2, is=3, ir=1, ic=17, il=4, istrip=71}. However,
0052  * in CSCIndexer classes, "label" may be generalized to mean more than this. For
0053  * example, the "chamberLabel_" vector encodes these integer labels for a
0054  * chamber, and does not just mean the value ic=1-18 or 36.
0055  *
0056  * \warning EVERY LABEL COUNTS FROM ONE NOT ZERO.
0057  *
0058  * \warning Contains a number of non-virtual method that derived classes are not
0059  * expected to override!
0060  * TODO: add 'final' attribute to those non-virtual methods after full migration
0061  * to gcc4.7
0062  */
0063 
0064 #include <DataFormats/MuonDetId/interface/CSCDetId.h>
0065 #include <tuple>
0066 #include <utility>  // for pair
0067 #include <vector>
0068 
0069 class CSCIndexerBase {
0070 public:
0071   typedef uint16_t IndexType;
0072   typedef uint32_t LongIndexType;
0073   typedef std::tuple<CSCDetId,   // id
0074                      IndexType,  // HV segment
0075                      IndexType   // chip
0076                      >
0077       GasGainIndexType;
0078 
0079   CSCIndexerBase();
0080   virtual ~CSCIndexerBase();
0081 
0082   virtual std::string name() const { return "CSCIndexerBase"; }
0083 
0084   /** \name maxIndexMethods
0085    * The following methods are expected to define maximum values for various
0086    * index types.
0087    *
0088    * \warning The abstract methods need to be implemented by concrete
0089    * CSCIndexers! \warning the minimum index value is 1.
0090    */
0091   //@{
0092   IndexType maxChamberIndex() const { return 540; }
0093   IndexType maxLayerIndex() const { return 3240; }
0094   virtual LongIndexType maxStripChannelIndex() const = 0;
0095   virtual IndexType maxChipIndex() const = 0;
0096   virtual IndexType maxGasGainIndex() const = 0;
0097   //@}
0098 
0099   /// \name nonIndexCountingMethods
0100   //@{
0101   /**
0102    * How many physical rings are there in station 'is'=1, 2, 3, 4 ?
0103    */
0104   IndexType ringsInStation(IndexType is) const {
0105     const IndexType nrins[5] = {0, 3, 2, 2, 2};  // physical rings per station
0106     return nrins[is];
0107   }
0108 
0109   /**
0110    * How many online rings are there in station 'is'=1, 2, 3, 4 ?
0111    */
0112   virtual IndexType onlineRingsInStation(IndexType is) const = 0;
0113 
0114   /**
0115    * How many offline rings are there in station 'is'=1, 2, 3, 4 ?
0116    *
0117    * \warning:
0118    * - ME1 has 4 rings in the offline notation (virtual ring 4 is used for
0119    * ME1a).
0120    */
0121   IndexType offlineRingsInStation(IndexType is) const {
0122     const IndexType nrings[5] = {0, 4, 2, 2, 2};  // offline rings per station
0123     return nrings[is];
0124   }
0125 
0126   /**
0127    * How many chambers are there in an "offline" ring ir of station is?
0128    * Works for ME1a (ring 4 of ME1) too.
0129    */
0130   IndexType chambersInRingOfStation(IndexType is, IndexType ir) const {
0131     const IndexType nCinR[16] = {36, 36, 36, 36, 18, 36, 0, 0, 18, 36, 0, 0, 18, 36, 0, 0};  // chambers in ring
0132     return nCinR[(is - 1) * 4 + ir - 1];
0133   }
0134 
0135   /**
0136    * Number of strip readout channels per layer in an offline chamber
0137    * with ring 'ir' and station 'is'.
0138    * Works for ME1a (ring 4 of ME1) too.
0139    */
0140   virtual IndexType stripChannelsPerOfflineLayer(IndexType is, IndexType ir) const = 0;
0141 
0142   /**
0143    * Number of strip readout channels per layer in an online chamber
0144    * with ring 'ir' and station 'is'.
0145    * Works for ME1a (ring 4 of ME1) too.
0146    */
0147   virtual IndexType stripChannelsPerOnlineLayer(IndexType is, IndexType ir) const = 0;
0148 
0149   /**
0150    * Number of Buckeye chips per layer in an online chamber
0151    * in ring 'ir' of station 'is'.
0152    * Works for ME1a (ring 4 of ME1) too.
0153    */
0154   virtual IndexType chipsPerOnlineLayer(IndexType is, IndexType ir) const = 0;
0155 
0156   /**
0157    * Number of Gas Gain sectors per layer in an online chamber
0158    * in ring 'ir' of station 'is'.
0159    * Works for ME1a (ring 4 of ME1) too.
0160    *
0161    * The difference between this and sectorsPerLayer completely depends on
0162    * the difference between chipsPerOnlineLayer and chipsPerLayer
0163    */
0164   IndexType sectorsPerOnlineLayer(IndexType is, IndexType ir) const {
0165     return chipsPerOnlineLayer(is, ir) * hvSegmentsPerLayer(is, ir);
0166   }
0167 
0168   //@}
0169 
0170   /// \name chamberIndexMethods
0171   //@{
0172   /**
0173    * Starting index for first chamber in ring 'ir' of station 'is' in endcap
0174    * 'ie', in range 1-468 (CSCs 2008) or 469-540 (ME42).
0175    *
0176    * \warning: Considers both ME1a and ME1b to be part of one whole ME11 chamber
0177    *          (result would be the same for is=1 and ir=1 or 4).
0178    */
0179   IndexType startChamberIndexInEndcap(IndexType ie, IndexType is, IndexType ir) const {
0180     const IndexType nschin[32] = {1,   37,  73,  1,   109, 127, 0, 0, 163, 181, 0, 0, 217, 469, 0, 0,
0181                                   235, 271, 307, 235, 343, 361, 0, 0, 397, 415, 0, 0, 451, 505, 0, 0};
0182     return nschin[(ie - 1) * 16 + (is - 1) * 4 + ir - 1];
0183   }
0184 
0185   /**
0186    * Linear index for chamber 'ic' in ring 'ir' of station 'is' in endcap 'ie',
0187    * in range 1-468 (CSCs 2008) or 469-540 (ME42)
0188    *
0189    * \warning: Since both ME1a and ME1b are part of one ME11 chamber
0190    * the output is the same for input {is=1, ir=1} and {is=1, ir=4}, i.e.
0191    * chamberIndex for ME1/1a is the same as for ME1/1b.
0192    */
0193   IndexType chamberIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic) const {
0194     return startChamberIndexInEndcap(ie, is, ir) + ic - 1;  // -1 so start index _is_ ic=1
0195   }
0196 
0197   /**
0198    * Linear index to label each CSC in CSC system.
0199    * Argument is the CSCDetId of some CSC chamber.
0200    *
0201    * Output is 1-468 (CSCs 2008) 469-540 (with ME42)
0202    *
0203    * \warning: Since both ME1a and ME1b are part of one ME11 chamber
0204    * the output is the same for input {is=1, ir=1} and {is=1, ir=4}, i.e.
0205    * chamberIndex for ME1/1a is the same as for ME1/1b.
0206    */
0207   IndexType chamberIndex(const CSCDetId &id) const {
0208     return chamberIndex(id.endcap(), id.station(), id.ring(), id.chamber());
0209   }
0210   //@}
0211 
0212   /// \name layerIndexMethods
0213   //@{
0214   /**
0215    * Linear index for layer 'il' of chamber 'ic' in ring 'ir' of station 'is' in
0216    * endcap 'ie', in range 1-2808 (CSCs 2008) or 2809-3240 (ME42).
0217    *
0218    * \warning: Since both ME1a and ME1b are part of one ME11 chamber
0219    * the output is the same for input {is=1, ir=1} and {is=1, ir=4}, i.e.
0220    * layerIndex for ME1/1a is the same as for ME1/1b.
0221    */
0222   IndexType layerIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il) const {
0223     const IndexType layersInChamber = 6;
0224     return (chamberIndex(ie, is, ir, ic) - 1) * layersInChamber + il;
0225   }
0226 
0227   /**
0228    * Linear index to label each hardware layer in CSC system.
0229    * Argument is the CSCDetId of some CSC layer.
0230    *
0231    * Output is 1-2808 (CSCs 2008) 2809-3240 (ME42)
0232    *
0233    * \warning: Since both ME1a and ME1b are part of one ME11 chamber
0234    * the output is the same for input {is=1, ir=1} and {is=1, ir=4}, i.e.
0235    * layerIndex for ME1/1a is the same as for ME1/1b.
0236    */
0237   IndexType layerIndex(const CSCDetId &id) const {
0238     return layerIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer());
0239   }
0240   //@}
0241 
0242   /// \name stripIndexMethods
0243   //@{
0244   /**
0245    * Number of strip channel indices for a layer in a chamber
0246    * defined by station number 'is' and ring number 'ir'.
0247    *
0248    * Station label range 1-4, Ring label range 1-4 (4=ME1a)
0249    *
0250    * This depends on the ordering of the channels in the database.
0251    * E.g., in startup scenario there are 80 indices allocated per ME1/1 layer
0252    * with 1-64 belonging to ME1b and 65-80 belonging to ME1a. So the ME1/a
0253    * database indices are mapped to extend the ME1/b index ranges, which is how
0254    * the raw hardware chnnels numbering is implemented.
0255    *
0256    * In the currently implemented upgrade scenario on the other hand, the ME1b
0257    * still keeps the 80 indices wide ranges (with the last 16 of them remaining
0258    * unused), while the ME1/1A gets its own 48 indices wide ranges.
0259    */
0260   virtual IndexType stripChannelsPerLayer(IndexType is, IndexType ir) const = 0;
0261 
0262   /**
0263    * Linear index for 1st strip channel in ring 'ir' of station 'is' in endcap
0264    * 'ie'.
0265    *
0266    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-4
0267    * (4=ME1a)
0268    */
0269   virtual LongIndexType stripChannelStart(IndexType ie, IndexType is, IndexType ir) const = 0;
0270 
0271   /**
0272    * Linear index for strip channel istrip in layer 'il' of chamber 'ic' of ring
0273    * 'ir' in station 'is' of endcap 'ie'.
0274    *
0275    * \warning: You must input labels within hardware ranges. No trapping on
0276    * out-of-range values!
0277    */
0278   LongIndexType stripChannelIndex(
0279       IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il, IndexType istrip) const {
0280     return stripChannelStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * stripChannelsPerLayer(is, ir) + (istrip - 1);
0281   }
0282 
0283   /**
0284    * Linear index for strip channel 'istrip' in layer labeled by CSCDetId 'id'
0285    *
0286    * \warning: You must input labels within hardware ranges. No trapping on
0287    * out-of-range values!
0288    */
0289   LongIndexType stripChannelIndex(const CSCDetId &id, IndexType istrip) const {
0290     return stripChannelIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), istrip);
0291   }
0292   //@}
0293 
0294   /// \name chipIndexMethods
0295   //@{
0296   /**
0297    * Number of Buckeye chips indices per layer in a chamber in ring 'ir' of
0298    * station 'is'.
0299    *
0300    * Station label range 1-4, Ring label range 1-4 (4=ME1a)
0301    */
0302   virtual IndexType chipsPerLayer(IndexType is, IndexType ir) const = 0;
0303 
0304   /**
0305    * Linear index for 1st Buckeye chip in ring 'ir' of station 'is' in endcap
0306    * 'ie'.
0307    *
0308    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-4
0309    * (4=ME1a)
0310    */
0311   virtual IndexType chipStart(IndexType ie, IndexType is, IndexType ir) const = 0;
0312 
0313   /**
0314    * Linear index for Buckeye chip 'ichip' in layer 'il' of chamber 'ic' of ring
0315    * 'ir' in station 'is' of endcap 'ie'.
0316    *
0317    * \warning: You must input labels within hardware ranges. No trapping on
0318    * out-of-range values! E.g., if you provide ir=4 in ganged case, it would
0319    * still be treated the same as ir=1, but ichip must be 5 for it to make
0320    * sense!
0321    */
0322   IndexType chipIndex(IndexType ie, IndexType is, IndexType ir, IndexType ic, IndexType il, IndexType ichip) const {
0323     return chipStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * chipsPerLayer(is, ir) + (ichip - 1);
0324   }
0325 
0326   /**
0327    * Linear index for Buckeye chip 'ichip' in layer labelled by CSCDetId 'id'.
0328    *
0329    * \warning: The supplied CSCDetId must be a layer id, and ichip must be h/w
0330    * chip number in a chamber. No trapping on out-of-range values! E.g., if you
0331    * provide ME1a id in ganged case, it would still be treated the same as whole
0332    * ME11 id, but ichip must be 5 for it to make sense!
0333    */
0334   IndexType chipIndex(const CSCDetId &id, IndexType ichip) const {
0335     return chipIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), ichip);
0336   }
0337 
0338   /**
0339    * Chip number in a chamber for a Buckeye chip processing strip 'istrip'.
0340    *
0341    * Input is hardware strip channel 1-80.
0342    * \warning: for ganged ME1a istrip would have to be in 65-80, while for
0343    * unganged ME1a it would be in 1-48
0344    *
0345    * Output is 1-5.
0346    */
0347   IndexType chipIndex(IndexType istrip) const { return (istrip - 1) / 16 + 1; }
0348   //@}
0349 
0350   /// \name gasGainIndexMethods
0351   //@{
0352   /**
0353    * Number of HV segments per layer in a chamber in ring ir of station is.
0354    *
0355    * Station label range 1-4, Ring label range 1-4 (4=ME1a)
0356    *
0357    * ME1a (ir=4), ME1b(ir=1) and whole ME11 are all assumed to have the same
0358    * single HV segment
0359    */
0360   IndexType hvSegmentsPerLayer(IndexType is, IndexType ir) const {
0361     const IndexType nSinL[16] = {1, 3, 3, 1, 3, 5, 0, 0, 3, 5, 0, 0, 3, 5, 0, 0};
0362     return nSinL[(is - 1) * 4 + ir - 1];
0363   }
0364 
0365   /**
0366    * Linear index inside a chamber for HV segment
0367    * given station, ring, and wiregroup number.
0368    *
0369    * Output is 1-5.
0370    *
0371    * ME1a (ir=4), ME1b(ir=1) and whole ME11 are all assumed to have the same
0372    * single HV segment
0373    */
0374   IndexType hvSegmentIndex(IndexType is, IndexType ir, IndexType iwire) const;
0375 
0376   /**
0377    * Number of Gas Gain sectors per layer in a chamber in ring ir of station is.
0378    *
0379    * Station label range 1-4, Ring label range 1-4 (4=ME1a)
0380    *
0381    * \warning: for ganged case, the ir=4 ME1a input would give the same result
0382    * as ir=1
0383    */
0384   IndexType sectorsPerLayer(IndexType is, IndexType ir) const {
0385     return chipsPerLayer(is, ir) * hvSegmentsPerLayer(is, ir);
0386   }
0387 
0388   /**
0389    * Linear index for 1st Gas gain sector in ring 'ir' of station 'is' in endcap
0390    * 'ie'.
0391    *
0392    * Endcap label range 1-2, Station label range 1-4, Ring label range 1-4
0393    * (4=ME1a)
0394    *
0395    * \warning:
0396    *   current: ME1a chip is the last 1 of the 5 chips total in each layer of an
0397    * ME11 chamber, and an input ir=4 in this case would give the same result as
0398    * ir=1 upgraded:  ME1a has 3 own chips, which are appended to the end of the
0399    * index range, ME1b still keeps 5 chips with chip #5 index unused.
0400    */
0401   virtual IndexType sectorStart(IndexType ie, IndexType is, IndexType ir) const = 0;
0402 
0403   /**
0404    * Linear index for Gas gain sector, based on the HV segment# and the chip#
0405    * located in layer 'il' of chamber 'ic' of ring 'ir' in station 'is' of
0406    * endcap 'ie'.
0407    *
0408    * Output is 1-45144 (CSCs 2008) and 45145-55944 (ME42) and 55945-57240 (ME1a)
0409    *
0410    * \warning: You must input labels within hardware ranges. No trapping on
0411    * out-of-range values! E.g., if you provide ir=4 in ganged case, it would
0412    * still be treated the same as ir=1, but ichip must be 5 for it to make
0413    * sense!
0414    */
0415   IndexType gasGainIndex(IndexType ie,
0416                          IndexType is,
0417                          IndexType ir,
0418                          IndexType ic,
0419                          IndexType il,
0420                          IndexType ihvsegment,
0421                          IndexType ichip) const {
0422     return sectorStart(ie, is, ir) + ((ic - 1) * 6 + il - 1) * sectorsPerLayer(is, ir) +
0423            (ihvsegment - 1) * chipsPerLayer(is, ir) + (ichip - 1);
0424   }
0425 
0426   /**
0427    * Linear index for Gas gain sector, based on CSCDetId 'id', cathode strip
0428    * 'istrip' and anode wire 'iwire'
0429    *
0430    * \warning: You must input labels within hardware ranges (e.g., 'id' must
0431    * correspond to a specific layer 1-6). No trapping on out-of-range values!
0432    * E.g., if you provide ME1a id in ganged case, it would still be treated the
0433    * same as whole ME11 id, but istrip must be a h/w strip number in 64-80 in
0434    * that case!
0435    */
0436   IndexType gasGainIndex(const CSCDetId &id, IndexType istrip, IndexType iwire) const {
0437     return gasGainIndex(id.endcap(),
0438                         id.station(),
0439                         id.ring(),
0440                         id.chamber(),
0441                         id.layer(),
0442                         hvSegmentIndex(id.station(), id.ring(), iwire),
0443                         chipIndex(istrip));
0444   }
0445 
0446   /**
0447    * Linear index for Gas gain sector, based on CSCDetId 'id', the HV segment#
0448    * and the chip#. Note: to allow method overloading, the parameters order is
0449    * reversed comparing to the (id,strip,wire) method
0450    *
0451    * Output is 1-45144 (CSCs 2008) and 45145-55944 (ME42) and 55945-57240 (ME1a)
0452    *
0453    * \warning: Use at your own risk! You must input labels within hardware
0454    * ranges. No trapping on out-of-range values! The supplied CSCDetId must be a
0455    * layer id, and ichip must be h/w chip number in a chamber. E.g., if you
0456    * provide ME1a id in ganged case, it would still be treated the same as whole
0457    * ME11 id, but ichip must be 5 for it to make sense!
0458    */
0459   IndexType gasGainIndex(IndexType ihvsegment, IndexType ichip, const CSCDetId &id) const {
0460     return gasGainIndex(id.endcap(), id.station(), id.ring(), id.chamber(), id.layer(), ihvsegment, ichip);
0461   }
0462   //@}
0463 
0464   /// \name reverseIndexMethods
0465   /// reverse look-up methods: index --> detid + etc.
0466   //@{
0467   /**
0468    * CSCDetId for a physical chamber labelled by the chamber index (1-468
0469    * non-ME4/2, 469-540 ME4/2)
0470    *
0471    * No distinction between ME1/1a and ME1/1b.
0472    */
0473   CSCDetId detIdFromChamberIndex(IndexType ici) const;
0474 
0475   /**
0476    * CSCDetId for a physical layer labelled by the layer index (1-2808
0477    * non-ME4/2, 2809-3240 ME4/2)
0478    *
0479    * No distinction between ME1/1a and ME1/1b.
0480    */
0481   CSCDetId detIdFromLayerIndex(IndexType ili) const;
0482 
0483   /**
0484    * CSCDetId + strip channel within layer from conditions data strip index.
0485    *
0486    * \warning This function changes meaning with ganged and unganged ME1/1a.
0487    * If ME1/1a is ganged then an ME1/1a strip index returns ME1/1b CSCDetId +
0488    * channel in range 65-80. <br> If ME1/1a is unganged then an ME1/1a strip
0489    * index returns ME1/1a CSCDetId + channel in range 1-48.
0490    */
0491   virtual std::pair<CSCDetId, IndexType> detIdFromStripChannelIndex(LongIndexType ichi) const = 0;
0492 
0493   /**
0494    * CSCDetId + chip within chamber from conditions data chip index.
0495    *
0496    * \warning This function changes meaning with ganged and unganged ME1/1a.
0497    * If ME1/1a is ganged then an ME1/1a chip index returns ME1/1b CSCDetId +
0498    * chip=5. <br> If ME1/1a is unganged then an ME1/1a chip index returns ME1/1a
0499    * CSCDetId + chip# in range 1-3.
0500    */
0501   virtual std::pair<CSCDetId, IndexType> detIdFromChipIndex(IndexType ichi) const = 0;
0502 
0503   /**
0504    * CSCDetId + HV segment + chip within chamber from conditions data gas gain
0505    * index.
0506    *
0507    * \warning This function changes meaning with ganged and unganged ME1/1a.
0508    * If ME1/1a is ganged then an ME1/1a gas gain index returns ME1/1b CSCDetId +
0509    * HVsegment=1 + chip=5. <br> If ME1/1a is unganged then an ME1/1a gas gain
0510    * index returns ME1/1a CSCDetId + HVsegment=1 + chip# in range 1-3.
0511    */
0512   virtual GasGainIndexType detIdFromGasGainIndex(IndexType igg) const = 0;
0513 
0514   //@}
0515 
0516   /**
0517    * Create the "Igor Index" for a strip channel.
0518    * This is integer ie*100000 + is*10000 + ir*1000 + ic*10 + il.
0519    *
0520    * \warning The channel is NOT encoded. BUT... channel is passed in as a
0521    * reference and is converted from 1-16 to 65-80 if the chamber is ME1/1a and
0522    * ganged.
0523    *
0524    */
0525   virtual int dbIndex(const CSCDetId &id, int &channel) const = 0;
0526 
0527   /**
0528    * Encoded chambers label value from cache for input chamber index.
0529    * For debugging only!
0530    */
0531   IndexType chamberLabelFromChamberIndex(IndexType) const;
0532 
0533 protected:
0534   /**
0535    * Decode CSCDetId from the encoded chamber values in chamberLabel cache
0536    * vector. Requires endcap label since that is not encoded in cache.
0537    */
0538   CSCDetId detIdFromChamberLabel(IndexType ie, IndexType icl) const;
0539 
0540   /**
0541    * Encode a chamber's is, ir, ic values as is*1000 + ir*100 + ic in linear
0542    * vector with serial index 1-270. Save space in this vector by not storing
0543    * ie.
0544    */
0545   std::vector<IndexType> chamberLabel_;
0546 };
0547 
0548 #endif