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