CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoLocalTracker/SiStripZeroSuppression/src/IteratedMedianCMNSubtractor.cc

Go to the documentation of this file.
00001 #include "RecoLocalTracker/SiStripZeroSuppression/interface/IteratedMedianCMNSubtractor.h"
00002 
00003 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00004 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
00005 #include "CondFormats/DataRecord/interface/SiStripNoisesRcd.h"
00006 #include "CalibTracker/Records/interface/SiStripQualityRcd.h"
00007 #include <cmath>
00008 
00009 void IteratedMedianCMNSubtractor::init(const edm::EventSetup& es){
00010   uint32_t n_cache_id = es.get<SiStripNoisesRcd>().cacheIdentifier();
00011   uint32_t q_cache_id = es.get<SiStripQualityRcd>().cacheIdentifier();
00012 
00013   if(n_cache_id != noise_cache_id) {
00014     es.get<SiStripNoisesRcd>().get( noiseHandle );
00015     noise_cache_id = n_cache_id;
00016   }
00017   if(q_cache_id != quality_cache_id) {
00018     es.get<SiStripQualityRcd>().get( qualityHandle );
00019     quality_cache_id = q_cache_id;
00020   }
00021 }
00022 
00023 void IteratedMedianCMNSubtractor::subtract(const uint32_t& detId, const uint16_t& firstAPV, std::vector<int16_t>& digis){ subtract_(detId, firstAPV, digis);}
00024 void IteratedMedianCMNSubtractor::subtract(const uint32_t& detId, const uint16_t& firstAPV, std::vector<float>& digis){ subtract_(detId,firstAPV, digis);}
00025 
00026 template<typename T>
00027 inline
00028 void IteratedMedianCMNSubtractor::
00029 subtract_(const uint32_t& detId, const uint16_t& firstAPV, std::vector<T>& digis){
00030 
00031   SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detId);
00032   SiStripQuality::Range detQualityRange = qualityHandle->getRange(detId);
00033 
00034   typename std::vector<T>::iterator fs,ls;
00035   float offset = 0;  
00036   std::vector< std::pair<float,float> > subset;
00037   subset.reserve(128);
00038 
00039   _vmedians.clear(); 
00040   
00041   uint16_t APV=firstAPV;
00042   for( ; APV< digis.size()/128+firstAPV; ++APV)
00043   {
00044     subset.clear();
00045     // fill subset vector with all good strips and their noises
00046     for (uint16_t istrip=APV*128; istrip<(APV+1)*128; ++istrip)
00047     {
00048       if ( !qualityHandle->IsStripBad(detQualityRange,istrip) )
00049       {
00050         std::pair<float,float> pin((float)digis[istrip-firstAPV*128], (float)noiseHandle->getNoiseFast(istrip,detNoiseRange));
00051         subset.push_back( pin );
00052       }
00053     }
00054 
00055     // caluate offset for all good strips (first iteration)
00056     if (subset.size() != 0)
00057       offset = pairMedian(subset);
00058 
00059     // for second, third... iterations, remove strips over threshold
00060     // and recalculate offset on remaining strips
00061     for ( int ii = 0; ii<iterations_-1; ++ii )
00062     {
00063       std::vector< std::pair<float,float> >::iterator si = subset.begin();
00064       while(  si != subset.end() )
00065       {
00066         if( si->first-offset > cut_to_avoid_signal_*si->second )  
00067           si = subset.erase(si);
00068         else
00069           ++si;
00070       }
00071       if ( subset.size() == 0 ) break;
00072       offset = pairMedian(subset);
00073     }        
00074 
00075     _vmedians.push_back(std::pair<short,float>(APV,offset));
00076     
00077     // remove offset
00078     fs = digis.begin()+(APV-firstAPV)*128;
00079     ls = digis.begin()+(APV-firstAPV+1)*128;
00080     while (fs < ls) {
00081       *fs = static_cast<T>(*fs-offset);
00082       fs++;
00083     }
00084 
00085   }
00086 }
00087 
00088 
00089 
00090 inline float IteratedMedianCMNSubtractor::pairMedian( std::vector<std::pair<float,float> >& sample) {
00091   std::vector<std::pair<float,float> >::iterator mid = sample.begin() + sample.size()/2;
00092   std::nth_element(sample.begin(), mid, sample.end());
00093   if( sample.size() & 1 ) //odd size
00094     return (*mid).first;
00095   return ( (*std::max_element(sample.begin(), mid)).first + (*mid).first ) / 2.;
00096 }
00097