CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/RecoLocalMuon/CSCRecHitD/src/CSCHitFromStripOnly.cc

Go to the documentation of this file.
00001 // This is  CSCHitFromStripOnly.cc
00002 
00003 #include "RecoLocalMuon/CSCRecHitD/src/CSCHitFromStripOnly.h"
00004 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripData.h"
00005 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripHitData.h"
00006 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripHit.h"
00007 #include "RecoLocalMuon/CSCRecHitD/src/CSCPedestalChoice.h"
00008 
00009 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00010 
00011 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00012 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
00013 
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 #include "FWCore/Utilities/interface/Exception.h"
00016 
00017 #include <algorithm>
00018 #include <string>
00019 #include <vector>
00020 
00021 
00022 CSCHitFromStripOnly::CSCHitFromStripOnly( const edm::ParameterSet& ps ) : recoConditions_(0), calcped_(0) {
00023   
00024   useCalib                   = ps.getParameter<bool>("CSCUseCalibrations");
00025   bool useStaticPedestals    = ps.getParameter<bool>("CSCUseStaticPedestals");
00026   int noOfTimeBinsForDynamicPed = ps.getParameter<int>("CSCNoOfTimeBinsForDynamicPedestal");
00027 
00028   theThresholdForAPeak       = ps.getParameter<double>("CSCStripPeakThreshold");
00029   theThresholdForCluster     = ps.getParameter<double>("CSCStripClusterChargeCut");
00030 
00031   LogTrace("CSCRecHit")  << "[CSCHitFromStripOnly] CSCUseStaticPedestals = " << useStaticPedestals;
00032   if ( !useStaticPedestals ) LogTrace("CSCRecHit")  << "[CSCHitFromStripOnly] CSCNoOfTimeBinsForDynamicPedestal = " 
00033                                                     << noOfTimeBinsForDynamicPed;
00034 
00035   if ( useStaticPedestals ) {
00036     calcped_ = new CSCStaticPedestal();
00037   }
00038   else {
00039     if ( noOfTimeBinsForDynamicPed == 1 ) {
00040       calcped_ = new CSCDynamicPedestal1();
00041     }
00042     else {
00043       calcped_ = new CSCDynamicPedestal2(); // NORMAL DEFAULT!
00044     }
00045   }
00046 
00047 }
00048 
00049 
00050 CSCHitFromStripOnly::~CSCHitFromStripOnly() {
00051   delete calcped_;
00052 }
00053 
00054 
00055 /* runStrip
00056  *
00057  * Search for strip with ADC output exceeding theThresholdForAPeak.  For each of these strips,
00058  * build a cluster of strip of size theClusterSize (typically 3 strips).  Finally, make
00059  * a Strip Hit out of these clusters by finding the center-of-mass position of the hit
00060  */
00061 std::vector<CSCStripHit> CSCHitFromStripOnly::runStrip( const CSCDetId& id, const CSCLayer* layer,
00062                                                const CSCStripDigiCollection::Range& rstripd ) 
00063 {       
00064 
00065   std::vector<CSCStripHit> hitsInLayer;
00066   
00067   // cache layer info for ease of access
00068   id_        = id;
00069   layer_     = layer;
00070   nstrips_   = layer->chamber()->specs()->nStrips();
00071 
00072   tmax_cluster = 5;
00073 
00074   // Get gain correction weights for all strips in layer, and cache in gainWeight.
00075   // They're used in fillPulseHeights below.
00076   if ( useCalib ) {
00077     recoConditions_->stripWeights( id, gainWeight );
00078   }
00079   
00080   // Store pulseheights from SCA and find maxima (potential hits)
00081   fillPulseHeights( rstripd );
00082   findMaxima(id);      
00083 
00084   // Make a Strip Hit out of each strip local maximum
00085   for ( size_t imax = 0; imax != theMaxima.size(); ++imax ) {
00086 
00087     // Initialize parameters entering the CSCStripHit
00088     clusterSize = theClusterSize;
00089     theStrips.clear();
00090     strips_adc.clear();
00091     strips_adcRaw.clear();
00092 
00093     // makeCluster calls findHitOnStripPosition to determine the centroid position
00094 
00095     // Remember, the array starts at 0, but the stripId starts at 1...
00096     float strippos = makeCluster( theMaxima[imax]+1 );    
00097     
00098     //if ( strippos < 0 || tmax_cluster < 3 ){
00099     // the strippos (as calculated here) is not used later on in
00101     // with the negative charges allowed it can become negative
00102     if (  tmax_cluster < 3 ){
00103       theClosestMaximum.push_back(99); // to keep proper vector size
00104       continue;
00105     }
00106     //---- If two maxima are too close the error assigned will be width/sqrt(12) - see CSCXonStrip_MatchGatti.cc
00107     int maximum_to_left = 99; //---- If there is one maximum - the distance is set to 99 (strips)
00108     int maximum_to_right = 99;
00109     if(imax<theMaxima.size()-1){
00110       maximum_to_right = theMaxima.at(imax+1) - theMaxima.at(imax);
00111     }
00112     if(imax>0 ){
00113       maximum_to_left =  theMaxima.at(imax-1) - theMaxima.at(imax);
00114     }
00115     if(fabs(maximum_to_right) < fabs(maximum_to_left)){
00116       theClosestMaximum.push_back(maximum_to_right);
00117     }
00118     else{
00119       theClosestMaximum.push_back(maximum_to_left);
00120     }
00121     
00122     //---- Check if a neighbouring strip is a dead strip
00123     //bool deadStrip = isNearDeadStrip(id, theMaxima.at(imax)); 
00124     bool deadStripL = isDeadStrip(id, theMaxima.at(imax)-1);
00125     bool deadStripR = isDeadStrip(id, theMaxima.at(imax)+1);
00126     short int aDeadStrip = 0;
00127     if(!deadStripL && !deadStripR){
00128       aDeadStrip = 0;
00129     }
00130     else if(deadStripL && deadStripR){
00131       aDeadStrip = 255;
00132     }
00133     else{
00134       if(deadStripL){
00135         aDeadStrip = theMaxima.at(imax)-1;
00136       }
00137       else{
00138         aDeadStrip = theMaxima.at(imax)+1;
00139       }
00140     }
00141     //std::cout << " Size of theStrips from SCSHitFromStripOnly: " <<  theStrips.size() << std::endl;
00142     
00145     std::vector<int> theL1AStrips;
00146     for(int ila=0; ila<(int)theStrips.size(); ila++){
00147        bool stripMatchCounter=false;
00148        for ( CSCStripDigiCollection::const_iterator itl1 = rstripd.first; itl1 != rstripd.second; ++itl1 ) {
00149            int stripNproto = (*itl1).getStrip();
00150            if(id_.ring() != 4){
00151            if(theStrips[ila]==stripNproto){
00152              stripMatchCounter=true;
00153              std::vector<int> L1AP=(*itl1).getL1APhase();
00154              int L1AbitOnPlace=0;
00155              for(int iBit=0; iBit<(int)L1AP.size(); iBit++){
00156                 L1AbitOnPlace=L1AbitOnPlace|(L1AP[iBit] << (15-iBit));          
00157              }
00158              theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
00159            }
00160          }
00161          else{
00162            for(int tripl=0; tripl<3; ++tripl){
00163            if(theStrips[ila]==(stripNproto+tripl*16)){
00164              stripMatchCounter=true;
00165              std::vector<int> L1AP=(*itl1).getL1APhase();
00166              int L1AbitOnPlace=0;
00167              for(int iBit=0; iBit<(int)L1AP.size(); iBit++){
00168                 L1AbitOnPlace=L1AbitOnPlace|(L1AP[iBit] << (15-iBit));          
00169              }
00170              theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
00171             }
00172           }
00173         }
00174       }
00175     if(!stripMatchCounter){
00176              theL1AStrips.push_back(theStrips[ila]);
00177            }
00178     }
00180 
00181    CSCStripHit striphit( id, strippos, tmax_cluster, theL1AStrips, strips_adc, strips_adcRaw, 
00182                           theConsecutiveStrips.at(imax), theClosestMaximum.at(imax), aDeadStrip);
00183    hitsInLayer.push_back( striphit ); 
00184   }
00185   
00187   /*  
00188       for(std::vector<CSCStripHit>::const_iterator itSHit=hitsInLayer.begin(); itSHit!=hitsInLayer.end(); ++itSHit){
00189          (*itSHit).print(); 
00190          }  
00191   */
00192   return hitsInLayer;
00193 }
00194 
00195 
00196 /* makeCluster
00197  *
00198  */
00199 float CSCHitFromStripOnly::makeCluster( int centerStrip ) {
00200   
00201   float strippos = -1.;
00202   clusterSize = theClusterSize;
00203   std::vector<CSCStripHitData> stripDataV;
00204  
00205   // We only want to use strip position in terms of strip # for the strip hit. //@@ What other choice is there?
00206     
00207   // If the cluster size is such that you go beyond the edge of detector, shrink cluster appropriately
00208   for ( int i = 1; i < theClusterSize/2 + 1; ++i ) {
00209  
00210     if ( centerStrip - i < 1 || centerStrip + i > int(nstrips_) ) {
00211 
00212       // Shrink cluster size, but keep it an odd number of strips.
00213       clusterSize = 2*i - 1;  
00214     }
00215   }
00216   for ( int i = -clusterSize/2; i <= clusterSize/2; ++i ) {
00217     CSCStripHitData data = makeStripData(centerStrip, i);
00218     stripDataV.push_back( data );
00219     theStrips.push_back( centerStrip + i );
00220   }
00221   strippos = findHitOnStripPosition( stripDataV, centerStrip );
00222   
00223   return strippos;
00224 }
00225 
00226 
00230 CSCStripHitData CSCHitFromStripOnly::makeStripData(int centerStrip, int offset) {
00231   
00232   CSCStripHitData prelimData;
00233   int thisStrip = centerStrip+offset;
00234 
00235   int tmax      = thePulseHeightMap[centerStrip-1].tmax();
00236   tmax_cluster  = tmax;
00237 
00238   std::vector<float> adc(4);
00239   std::vector<float> adcRaw(4);
00240 
00241   // Fill adc & adcRaw
00242         
00243   int istart = tmax-1;
00244   int istop  = std::min( tmax+2, 7 ) ; // there are only time bins 0-7
00245   adc[3] = 0.1; // in case it isn't filled
00246         
00247   if ( tmax > 2 && tmax < 7 ) { // for time bins 3-6
00248     int ibin = thisStrip-1;
00249                 
00250     std::copy( thePulseHeightMap[ibin].ph().begin()+istart, 
00251          thePulseHeightMap[ibin].ph().begin()+istop+1, adc.begin() );
00252                         
00253     std::copy( thePulseHeightMap[ibin].phRaw().begin()+istart, 
00254          thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw.begin() );
00255   } 
00256   else {
00257     adc[0] = 0.1;
00258     adc[1] = 0.1;
00259     adc[2] = 0.1;
00260     adc[3] = 0.1;
00261     adcRaw = adc;
00262     LogTrace("CSCRecHit")  << "[CSCHitFromStripOnly::makeStripData] Tmax out of range: contact CSC expert!";
00263   }
00264   
00265   if ( offset == 0 ) {
00266     prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
00267   } else {
00268     int sign = offset>0 ? 1 : -1;
00269     // If there's another maximum that would like to use part of this cluster, 
00270     // it gets shared in proportion to the height of the maxima
00271     for ( int i = 1; i <= clusterSize/2; ++i ) {
00272 
00273       // Find the direction of the offset
00274       int testStrip = thisStrip + sign*i;
00275       std::vector<int>::iterator otherMax = find(theMaxima.begin(), theMaxima.end(), testStrip-1);
00276 
00277       // No other maxima found, so just store
00278       if ( otherMax == theMaxima.end() ) {
00279         prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);      } 
00280       else {
00281         
00282         // Another maximum found - share       
00283         std::vector<float> adc1(4);
00284         std::vector<float> adcRaw1(4);
00285         std::vector<float> adc2(4);
00286         std::vector<float> adcRaw2(4);
00287         // In case we only copy (below) into 3 of the 4 bins i.e. when istart=5, istop=7
00288         adc1[3]    = 0.1; 
00289         adc2[3]    = 0.1; 
00290         adcRaw1[3] = 0.1; 
00291         adcRaw2[3] = 0.1; 
00292 
00293         // Fill adcN with content of time bins tmax-1 to tmax+2 (if it exists!)
00294         if ( tmax > 2 && tmax < 7 ) { // for time bin tmax from 3-6
00295           int ibin = testStrip-1;
00296           int jbin = centerStrip-1;
00297           std::copy(thePulseHeightMap[ibin].ph().begin()+istart, 
00298                thePulseHeightMap[ibin].ph().begin()+istop+1, adc1.begin());
00299                                 
00300           std::copy(thePulseHeightMap[ibin].phRaw().begin()+istart, 
00301                thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw1.begin());
00302                                                                                 
00303           std::copy(thePulseHeightMap[jbin].ph().begin()+istart, 
00304                thePulseHeightMap[jbin].ph().begin()+istop+1, adc2.begin());  
00305                                                 
00306           std::copy(thePulseHeightMap[jbin].phRaw().begin()+istart, 
00307                thePulseHeightMap[jbin].phRaw().begin()+istop+1, adcRaw2.begin());
00308         } 
00309         else {
00310           adc1.assign(4, 0.1);
00311           adcRaw1 = adc1;
00312           adc2.assign(4, 0.1);
00313           adcRaw2 = adc2;
00314         }
00315                                 
00316         // Scale shared strip B ('adc') by ratio of peak of ADC counts from central strip A ('adc2')
00317         // to sum of A and neighbouring maxima C ('adc1')
00318 
00319         for (size_t k = 0; k < 4; ++k){
00320           if(adc1[k]>0    && adc2[k]>0)    adc[k]    = adc[k] * adc2[k] / ( adc1[k]+adc2[k] );
00321           if(adcRaw1[k]>0 && adcRaw2[k]>0) adcRaw[k] = adcRaw[k] * adcRaw2[k] / ( adcRaw1[k]+adcRaw2[k] );     
00322         }
00323         prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
00324       }
00325     }
00326   }
00327   return prelimData;
00328 }
00329  
00330 
00331 /* fillPulseHeights
00332  *
00333  */
00334 void CSCHitFromStripOnly::fillPulseHeights( const CSCStripDigiCollection::Range& rstripd ) {
00335   
00336   // Loop over strip digis in one CSCLayer and fill PulseHeightMap with pedestal-subtracted
00337   // SCA pulse heights.
00338   
00339   thePulseHeightMap.clear();
00340   thePulseHeightMap.resize(100); //@@ WHY NOT JUST 80?
00341 
00342   // for storing sca pulseheights once they may no longer be integer (e.g. after ped subtraction)
00343   std::vector<float> sca;
00344   sca.reserve(8);
00345   for ( CSCStripDigiCollection::const_iterator it = rstripd.first; it != rstripd.second; ++it ) {
00346     int  thisChannel        = (*it).getStrip(); 
00347     std::vector<int> scaRaw = (*it).getADCCounts();
00348     sca.clear();
00349     // Fill sca from scaRaw, implicitly converting to float
00350     std::copy( scaRaw.begin(), scaRaw.end(), std::back_inserter( sca ));
00351 
00352     //@@ Find bin with largest pulseheight (_before_ ped subtraction - shouldn't matter, right?)
00353     int tmax =  std::max_element( sca.begin(), sca.end() ) - sca.begin(); // counts from 0
00354 
00355     // get pedestal - calculated as appropriate - for this sca pulse
00356     float ped = calcped_->pedestal(sca, recoConditions_, id_, thisChannel );
00357 
00358     // subtract the pedestal (from BOTH sets of sca pulseheights)
00359     std::for_each( sca.begin(), sca.end(), CSCSubtractPedestal( ped ) );
00360     std::for_each( scaRaw.begin(), scaRaw.end(), CSCSubtractPedestal( ped ) );
00361 
00362     //@@ Max in first 3 or last time bins is unacceptable, if so set to zero (why?)
00363     float phmax = 0.;
00364     if ( tmax > 2 && tmax < 7 ) {
00365       phmax = sca[tmax];
00366     }
00367                 
00368     // Fill the map, possibly apply gains from cond data, and unfold ME1A channels
00369     // (To apply gains use CSCStripData::op*= which scales only the non-raw sca ph's;
00370     // but note that both sca & scaRaw are pedestal-subtracted.)
00371 
00372     if ( id_.ring() != 4 ) { // non-ME1a
00373       thePulseHeightMap[thisChannel-1] = CSCStripData( thisChannel, phmax, tmax, scaRaw, sca );
00374       if ( useCalib ) thePulseHeightMap[thisChannel-1] *= gainWeight[thisChannel-1];
00375     } 
00376     else { // ME1a, so unfold its 16 channels to its 48 strips
00377       for ( int j = 0; j < 3; ++j ) {
00378         thePulseHeightMap[thisChannel-1+16*j] = CSCStripData( thisChannel+16*j, phmax, tmax, scaRaw, sca );
00379         if ( useCalib ) thePulseHeightMap[thisChannel-1+16*j] *= gainWeight[thisChannel-1];
00380       }
00381     }
00382 
00383   }
00384 }
00385 
00386 
00387 /* findMaxima
00388  *
00389  * fills vector 'theMaxima' with the local maxima in the pulseheight distribution
00390  * of the strips. The threshold defining a maximum is a configurable parameter.
00391  * A typical value is 30.
00392  */
00393 void CSCHitFromStripOnly::findMaxima(const CSCDetId& id) {
00394   
00395   theMaxima.clear();
00396   theConsecutiveStrips.clear();
00397   theClosestMaximum.clear();
00398   for ( size_t i=0; i!=thePulseHeightMap.size(); ++i ) {
00399 
00400     // sum 3 strips so that hits between strips are not suppressed
00401     float heightCluster = 0.;
00402     
00403     bool maximumFound = false;
00404     // Left edge of chamber
00405     if(!isDeadStrip(id, i+1)){ // is it i or i+1 
00406       if ( i == 0 ) {
00407         heightCluster = thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
00408         // Have found a strip Hit if...
00409         if(thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
00410            isPeakOK(i,heightCluster)){
00411           theMaxima.push_back(i);
00412           maximumFound = true;
00413         }
00414         // Right edge of chamber
00415       } else if ( i == thePulseHeightMap.size()-1) {  
00416         heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax();
00417         // Have found a strip Hit if...
00418         if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
00419            isPeakOK(i,heightCluster)){
00420           theMaxima.push_back(i);
00421           maximumFound = true;
00422         }
00423         // Any other strips 
00424       } else {
00425         heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
00426         // Have found a strip Hit if...
00427         if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
00428            thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
00429          isPeakOK(i,heightCluster)){
00430           theMaxima.push_back(i);
00431           maximumFound = true;
00432         }
00433       }
00434     }
00435     //---- Consecutive strips with charge (real cluster); if too wide - measurement is not accurate 
00436     if(maximumFound){
00437       int numberOfConsecutiveStrips = 1;
00438       float testThreshold = 10.;//---- ADC counts; 
00439                                 //---- this is not XTalk corrected so it is correct in first approximation only
00440       int j = 0;
00441       for(int l = 0; l<8; ++l){
00442         if(j<0) edm::LogWarning("FailedStripCountingWrongConsecutiveStripNumber") << "This should never occur!!! Contact CSC expert!";
00443         ++j;
00444         bool signalPresent = false;
00445         for(int k = 0; k<2; ++k){
00446           j*= -1;//---- check from left and right
00447           int anotherConsecutiveStrip = i+j;
00448           if(anotherConsecutiveStrip>=0 && anotherConsecutiveStrip<int( thePulseHeightMap.size() )){
00449             if(thePulseHeightMap[anotherConsecutiveStrip].phmax()>testThreshold){
00450               ++numberOfConsecutiveStrips;
00451               signalPresent = true;
00452             }
00453           }
00454         }
00455         if(!signalPresent){
00456           break;
00457         }
00458       }
00459       theConsecutiveStrips.push_back(numberOfConsecutiveStrips);
00460     }
00461   }
00462 }
00463 //
00464 
00465 bool CSCHitFromStripOnly::isPeakOK(int iStrip, float heightCluster){
00466   int i = iStrip;
00467   bool peakOK =  ( thePulseHeightMap[i].phmax()>theThresholdForAPeak &&  
00468                    heightCluster > theThresholdForCluster && 
00469                    // ... and proper peak time; note that the values below are used elsewhere in this file;
00470                    // they should become parameters or at least constants defined in appropriate place
00471                    thePulseHeightMap[i].tmax() > 2 && thePulseHeightMap[i].tmax() < 7); 
00472   return peakOK;
00473 }
00474 
00475 
00476 /* findHitOnStripPosition
00477  *
00478  */
00479 float CSCHitFromStripOnly::findHitOnStripPosition( const std::vector<CSCStripHitData>& data, const int& centerStrip ) {
00480   
00481   float strippos = -1.;
00482   
00483   if ( data.size() < 1 ) return strippos;
00484   
00485   // biggestStrip is strip with largest pulse height
00486   // Use pointer subtraction
00487 
00488   int biggestStrip = max_element(data.begin(), data.end()) - data.begin();
00489   strippos = data[biggestStrip].strip() * 1.;
00490   
00491   // If more than one strip:  use centroid to find center of cluster
00492   // but only use time bin == tmax (otherwise, bias centroid).
00493   float sum  = 0.;
00494   float sum_w= 0.;
00495 
00496   std::vector<float> w(4);
00497   std::vector<float> wRaw(4);
00498   
00499   for ( size_t i = 0; i != data.size(); ++i ) {
00500     w = data[i].ph();
00501     wRaw = data[i].phRaw();
00502 
00503     // (Require ADC to be > 0.)
00504     // No later studies suggest that this only do harm
00505     /*
00506     for ( size_t j = 0; j != w.size(); ++j ) {
00507       if ( w[j] < 0. ) w[j] = 0.001;
00508     }
00509     */
00510 
00511 
00512     // Fill the data members 
00513     std::copy( w.begin(), w.end(), std::back_inserter(strips_adc));
00514     std::copy( wRaw.begin(), wRaw.end(), std::back_inserter(strips_adcRaw));
00515 
00516     if ( data[i].strip() < 1 ){
00517       LogTrace("CSCRecHit") << "problem in indexing of strip, strip id is: " << data[i].strip();
00518     } 
00519     sum_w += w[1];
00520     sum   += w[1] * data[i].strip();
00521   }
00522 
00523   if ( sum_w > 0.) strippos = sum / sum_w;    
00524 
00525   return strippos;
00526 }
00527 
00528 bool CSCHitFromStripOnly::isNearDeadStrip(const CSCDetId& id, int centralStrip){
00529 
00530   //@@ Tim says: not sure I understand this properly... but just moved code to CSCRecoConditions
00531   // where it can handle the conversion from strip to channel etc.
00532   return recoConditions_->nearBadStrip( id, centralStrip );
00533 
00534 } 
00535 
00536 bool CSCHitFromStripOnly::isDeadStrip(const CSCDetId& id, int centralStrip){
00537   return recoConditions_->badStrip( id, centralStrip );
00538 
00539 } 
00540 
00541 // Define space for static
00542 const int CSCHitFromStripOnly::theClusterSize;