CMS 3D CMS Logo

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