CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/DataFormats/MuonDetId/src/CSCIndexer.cc

Go to the documentation of this file.
00001 #include <DataFormats/MuonDetId/interface/CSCIndexer.h>
00002 #include <iostream>
00003 
00004 void CSCIndexer::fillChamberLabel() const {
00005   // Fill the member vector which permits decoding of the linear chamber index
00006   // Logically const since initializes cache only,
00007   // Beware that the ME42 indices 235-270 within this vector do NOT correspond to
00008   // their 'real' linear indices (which are 469-504 for +z)
00009    chamberLabel.resize( 271 ); // one more than #chambers per endcap. Includes ME42.
00010    IndexType count = 0;
00011    chamberLabel[count] = 0;
00012 
00013    for ( IndexType is = 1 ; is != 5; ++is ) {
00014       IndexType irmax = ringsInStation(is);
00015       for ( IndexType ir = 1; ir != irmax+1; ++ir ) {
00016          IndexType icmax = chambersInRingOfStation(is, ir);
00017          for ( IndexType ic = 1; ic != icmax+1; ++ic ) {
00018            chamberLabel[ ++count ] = is*1000 + ir*100 + ic ;
00019          }
00020       } 
00021    }
00022 }
00023 
00024 CSCDetId CSCIndexer::detIdFromChamberIndex_OLD( IndexType ici ) const {
00025 
00026   // Will not work as is for ME42
00027   // ============================
00028 
00029   IndexType ie = 1;
00030   if (ici > 234 ) {
00031      ie = 2;
00032      ici -= 234; 
00033   }
00034   // Now ici is in range 1-234 (assuming valid input in range 1-468)
00035 
00036   // MEij pairs...
00037   const IndexType station[] = {0,1,1,1,2,2,3,3,4};
00038   const IndexType ring[]    = {0,1,2,3,1,2,1,2,1};
00039 
00040   // MEij preceding a given MEij matching linear index above
00041   const IndexType prevs[] =  {0,0,1,1,1,2,2,3,3}; 
00042   const IndexType prevr[] =  {0,0,1,2,3,1,2,1,2};
00043 
00044   IndexType is = 4;
00045   IndexType ir = 1;
00046   for ( IndexType i = 2; i<=8; ++i) {
00047     IndexType js = station[i];
00048     IndexType jr = ring[i];
00049     // if it's before start of MEjs/jr then it's in the previous MEis/ir
00050       if ( ici < startChamberIndexInEndcap(ie,js,jr) ) {
00051         is = prevs[i];
00052         ir = prevr[i];
00053         break;
00054       }
00055       // otherwise it's in ME41
00056   }
00057   IndexType ic = ici - startChamberIndexInEndcap(ie,is,ir) + 1;
00058 
00059   return CSCDetId( ie, is, ir, ic );
00060 }
00061  
00062 CSCDetId CSCIndexer::detIdFromChamberIndex( IndexType ici ) const {
00063   // Expected range of input range argument is 1-540.
00064   // 1-468 for CSCs installed at 2008 start-up. 469-540 for ME42.
00065 
00066   IndexType ie = 1;
00067   if ( ici > 468 ) {
00068     // ME42
00069     ici -= 234; // now in range 235-306
00070     if ( ici > 270 ) { // -z
00071       ie = 2;
00072       ici -= 36; // now in range 235-270
00073     }
00074   }
00075   else { // in range 1-468
00076     if ( ici > 234 ) { // -z
00077       ie = 2;
00078       ici -= 234; // now in range 1-234
00079     }
00080   }
00081   if (chamberLabel.empty()) fillChamberLabel();
00082   IndexType label = chamberLabel[ici];    
00083   return detIdFromChamberLabel( ie, label );
00084 }
00085 
00086 CSCIndexer::IndexType CSCIndexer::chamberLabelFromChamberIndex( IndexType ici ) const {
00087   // This is just for cross-checking
00088 
00089   // Expected range of input range argument is 1-540.
00090   // 1-468 for CSCs installed at 2008 start-up. 469-540 for ME42.
00091 
00092   if ( ici > 468 ) {
00093     // ME42
00094     ici -= 234; // now in range 235-306
00095     if ( ici > 270 ) { // -z
00096       ici -= 36; // now in range 235-270
00097     }
00098   }
00099   else { // in range 1-468
00100     if ( ici > 234 ) { // -z
00101       ici -= 234; // now in range 1-234
00102     }
00103   }
00104   if (chamberLabel.empty()) fillChamberLabel();
00105   return chamberLabel[ici];  
00106 
00107 }
00108 
00109 CSCDetId CSCIndexer::detIdFromChamberLabel( IndexType ie, IndexType label ) const {
00110 
00111   IndexType is = label/1000;
00112   label -= is*1000;
00113   IndexType ir = label/100;
00114   label -= ir*100;
00115   IndexType ic = label;
00116 
00117   return CSCDetId( ie, is, ir, ic );
00118 }
00119 
00120 CSCDetId CSCIndexer::detIdFromLayerIndex( IndexType ili ) const {
00121 
00122   IndexType il = (ili-1)%6 + 1;
00123   IndexType ici = (ili-1)/6 + 1;
00124   CSCDetId id = detIdFromChamberIndex( ici ); 
00125 
00126   return CSCDetId(id.endcap(), id.station(), id.ring(), id.chamber(), il);
00127 }
00128 
00129 std::pair<CSCDetId, CSCIndexer::IndexType>  CSCIndexer::detIdFromStripChannelIndex( LongIndexType isi ) const {
00130 
00131   const LongIndexType lastnonme42 = 217728; // channels in 2008 installed chambers
00132   const LongIndexType lastplusznonme42 = 108864; // = 217728/2
00133   const LongIndexType firstme13  = 34561; // First channel of ME13
00134   const LongIndexType lastme13   = 48384; // Last channel of ME13
00135 
00136   const IndexType lastnonme42layer = 2808;
00137   const IndexType lastplusznonme42layer = 1404; // = 2808/2
00138   const IndexType firstme13layer  = 433; // = 72*6 + 1 (ME13 chambers are 72-108 in range 1-234)
00139   const IndexType lastme13layer   = 648; // = 108*6
00140 
00141   // All chambers but ME13 have 80 channels
00142   IndexType nchan = 80;
00143 
00144   // Set endcap to +z. This should work for ME42 channels too, since we don't need to calculate its endcap explicitly.
00145   IndexType ie = 1;
00146 
00147   LongIndexType istart = 0;
00148   IndexType layerOffset = 0;
00149 
00150   if ( isi <= lastnonme42 ) {   
00151     // Chambers as of 2008 Installation
00152 
00153     if ( isi > lastplusznonme42 ) {
00154       ie = 2;
00155       isi -= lastplusznonme42;
00156     }
00157         
00158     if ( isi > lastme13 ) { // after ME13
00159       istart = lastme13;
00160       layerOffset = lastme13layer;
00161     }
00162     else if ( isi >= firstme13 ) { // ME13
00163       istart = firstme13 - 1;
00164       layerOffset = firstme13layer - 1;
00165       nchan = 64;
00166     }
00167   }
00168   else {
00169      // ME42 chambers
00170 
00171     istart = lastnonme42;
00172     layerOffset = lastnonme42layer;
00173   }
00174 
00175    isi -= istart; // remove earlier group(s)
00176    IndexType ichan = (isi-1)%nchan + 1;
00177    IndexType ili = (isi-1)/nchan + 1;
00178    ili += layerOffset; // add appropriate offset for earlier group(s)
00179    if ( ie != 1 ) ili+= lastplusznonme42layer; // add offset to -z endcap; ME42 doesn't need this.
00180         
00181    return std::pair<CSCDetId, IndexType>(detIdFromLayerIndex(ili), ichan);
00182 }
00183 
00184 
00185 std::pair<CSCDetId, CSCIndexer::IndexType>  CSCIndexer::detIdFromChipIndex( IndexType ici ) const {
00186 
00187   const LongIndexType lastnonme42 = 13608; // chips in 2008 installed chambers
00188   const LongIndexType lastplusznonme42 = 6804; // = 13608/2
00189   const LongIndexType firstme13  = 2161; // First channel of ME13
00190   const LongIndexType lastme13   = 3024; // Last channel of ME13
00191 
00192   const IndexType lastnonme42layer = 2808;
00193   const IndexType lastplusznonme42layer = 1404; // = 2808/2
00194   const IndexType firstme13layer  = 433; // = 72*6 + 1 (ME13 chambers are 72-108 in range 1-234)
00195   const IndexType lastme13layer   = 648; // = 108*6
00196 
00197   // All chambers but ME13 have 5 chips/layer
00198   IndexType nchipPerLayer = 5;
00199 
00200   // Set endcap to +z. This should work for ME42 channels too, since we don't need to calculate its endcap explicitly.
00201   IndexType ie = 1;
00202 
00203   LongIndexType istart = 0;
00204   IndexType layerOffset = 0;
00205 
00206   if ( ici <= lastnonme42 ) {   
00207     // Chambers as of 2008 Installation
00208 
00209     if ( ici > lastplusznonme42 ) {
00210       ie = 2;
00211       ici -= lastplusznonme42;
00212     }
00213         
00214     if ( ici > lastme13 ) { // after ME13
00215       istart = lastme13;
00216       layerOffset = lastme13layer;
00217     }
00218     else if ( ici >= firstme13 ) { // ME13
00219       istart = firstme13 - 1;
00220       layerOffset = firstme13layer - 1;
00221       nchipPerLayer = 4;
00222     }
00223   }
00224   else {
00225      // ME42 chambers
00226 
00227     istart = lastnonme42;
00228     layerOffset = lastnonme42layer;
00229   }
00230 
00231    ici -= istart; // remove earlier group(s)
00232    IndexType ichip = (ici-1)%nchipPerLayer + 1;
00233    IndexType ili = (ici-1)/nchipPerLayer + 1;
00234    ili += layerOffset; // add appropriate offset for earlier group(s)
00235    if ( ie != 1 ) ili+= lastplusznonme42layer; // add offset to -z endcap; ME42 doesn't need this.
00236         
00237    return std::pair<CSCDetId, IndexType>(detIdFromLayerIndex(ili), ichip);
00238 }
00239 
00240 int CSCIndexer::dbIndex(const CSCDetId & id, int & channel)
00241 {
00242   int ec = id.endcap();
00243   int st = id.station();
00244   int rg = id.ring();
00245   int ch = id.chamber();
00246   int la = id.layer();
00247 
00248   // The channels of ME1A are channels 65-80 of ME11
00249   if(st == 1 && rg == 4)
00250     {
00251       rg = 1;
00252       if(channel <= 16) channel += 64; // no trapping for any bizarreness
00253     }
00254   return ec*100000 + st*10000 + rg*1000 + ch*10 + la;
00255 }