CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoLocalTracker/SiStripClusterizer/src/SiStripApvShotCleaner.cc

Go to the documentation of this file.
00001 #include "RecoLocalTracker/SiStripClusterizer/interface/SiStripApvShotCleaner.h"
00002 #include <algorithm>
00003 #include <boost/foreach.hpp>
00004 
00005 //Uncomment the following #define to have print debug
00006 //#define DEBUGME
00007 
00008 SiStripApvShotCleaner::
00009 SiStripApvShotCleaner():
00010   pDetSet(0),
00011   maxNumOfApvs(6),  //FED Default: 6 (i.e. max num apvs )
00012   stripsPerApv(128),
00013   stripsForMedian(64){}
00014 
00015 
00016 
00017 bool SiStripApvShotCleaner::
00018 clean(const edm::DetSet<SiStripDigi>& in, edm::DetSet<SiStripDigi>::const_iterator& scan, edm::DetSet<SiStripDigi>::const_iterator& end){
00019   if(in.size()<64)
00020     return false;
00021   
00022   if(loop(in)){
00023     reset(scan,end);
00024     return true;
00025   }
00026   return false;
00027 }
00028 
00029 bool SiStripApvShotCleaner::
00030 loop(const edm::DetSet<SiStripDigi>& in){
00031 
00032 #ifdef DEBUGME 
00033   std::stringstream ss;  
00034   ss << __func__ << " working on detid " << in.detId() << " for a digi.size=" << in.size();
00035 #endif
00036   
00037   shots_=false;
00038   BOOST_FOREACH(bool& val,shotApv_)
00039     val=false;
00040   
00041   cacheDetId=in.detId();
00042 
00043   //Find the position in the DetSet where the first strip of an apv should be inserted
00044   // needed to deduce if at least stripsForMedian strips per apv have been fired
00045   for(size_t i=0;i<=maxNumOfApvs;++i){
00046     
00047     SiStripDigi d(i*stripsPerApv,0); //Fake digi, at the edge of the apv
00048     pFirstDigiOfApv[i] = std::lower_bound(in.begin(),in.end(),d);
00049 
00050     //if satisfied it means that the number of digis in the apv i-1 is above stripsForMedia -> apvShot
00051     if(i>0 && pFirstDigiOfApv[i]-pFirstDigiOfApv[i-1]>stripsForMedian){
00052       shots_=true;
00053       shotApv_[i-1]=true;
00054 #ifdef DEBUGME 
00055       ss << " found an apv shot of " << pFirstDigiOfApv[i]-pFirstDigiOfApv[i-1] << " digis in detid " << in.detId() << " apv " << i << std::endl;
00056 #endif
00057     }
00058     
00059     //---------------------
00060     //Just for debug REMOVE
00061     /*
00062     if(i>0){
00063       ss << "detid " << in.detId() << " apv " << i-1 << " number digis " << pFirstDigiOfApv[i]-pFirstDigiOfApv[i-1] << " \t shot " << shotApv_[i-1] << std::endl;
00064       if(pFirstDigiOfApv[i]-pFirstDigiOfApv[i-1]>stripsForMedian-2){
00065         edm::DetSet<SiStripDigi>::const_iterator dig=pFirstDigiOfApv[i-1];
00066         while(dig!=pFirstDigiOfApv[i]){
00067           ss << "\t strip " << dig->strip() << " dig.adc " << dig->adc();
00068           dig++;
00069         }
00070         ss << std::endl;
00071       }
00072     }
00073     */
00074     //-------------------------------
00075   }
00076   
00077 #ifdef DEBUGME 
00078   edm::LogInfo("ApvShot") << ss.str();
00079 #endif
00080 
00081   if(!shots_)
00082     return false;
00083 
00084   dumpInVector(pFirstDigiOfApv,maxNumOfApvs);
00085   return true;
00086 }
00087 
00088 void SiStripApvShotCleaner::
00089 dumpInVector(edm::DetSet<SiStripDigi>::const_iterator* pFirstDigiOfApv,size_t maxNumOfApvs){ 
00090   vdigis.clear();
00091   //loop on Apvs and remove shots. if an apv doesn't have shots, copy it
00092   for(size_t i=0;i<maxNumOfApvs;++i){
00093     apvDigis.clear();
00094 
00095     if(shotApv_[i]){
00096       apvDigis.insert(apvDigis.end(),pFirstDigiOfApv[i],pFirstDigiOfApv[i+1]);
00097       subtractCM();
00098       stable_sort(apvDigis.begin(),apvDigis.end());
00099       vdigis.insert(vdigis.end(),apvDigis.begin(),apvDigis.end());
00100     }else{
00101       vdigis.insert(vdigis.end(),pFirstDigiOfApv[i],pFirstDigiOfApv[i+1]);
00102     }
00103   }
00104   
00105 #ifdef DEBUGME 
00106   std::stringstream ss;
00107   ss <<"detid " << cacheDetId << " new digi.size " << vdigis.size() << "\n";
00108   for(size_t i=0;i<vdigis.size();++i)
00109     ss << "\t " << i << " strip " << vdigis[i].strip() << " adc " << vdigis[i].adc() ;
00110   edm::LogInfo("ApvShot") << ss.str() << std::endl;
00111 #endif
00112 }
00113 
00114 void SiStripApvShotCleaner::subtractCM(){
00115 
00116   //order by charge
00117   stable_sort(apvDigis.begin(),apvDigis.end(),orderingByCharge());
00118 
00119   //ignore case where 64th strip is 0ADC
00120   if(apvDigis[stripsForMedian].adc()==0){
00121 #ifdef DEBUGME 
00122         std::stringstream ss;
00123         ss << "case with strip64=0 --> detid= "<<cacheDetId<< "\n";
00124         edm::LogInfo("ApvShot") << ss.str();
00125 #endif
00126      return;
00127   }
00128 
00129   //Find the Median
00130   float CM = .5*(apvDigis[stripsForMedian].adc()+apvDigis[stripsForMedian-1].adc());
00131   
00132   
00133   if(CM<=0) 
00134     return;
00135 
00136   //Subtract the median
00137   size_t i=0;
00138   for(;i<stripsForMedian&&apvDigis[i].adc()>CM;++i){
00139     uint16_t adc=apvDigis[i].adc()>253?apvDigis[i].adc():(uint16_t)(apvDigis[i].adc()-CM);
00140     apvDigis[i]=SiStripDigi(apvDigis[i].strip(),adc);
00141   }
00142   apvDigis.resize(i);
00143 
00144 #ifdef DEBUGME 
00145   std::stringstream ss;
00146   ss << "[subtractCM] detid " << cacheDetId << "  CM is " << CM << " the remaining strips after CM subtraction are  " << i;
00147   edm::LogInfo("ApvShot") << ss.str();
00148 #endif
00149 }
00150 
00151 
00152 void SiStripApvShotCleaner::
00153 reset(edm::DetSet<SiStripDigi>::const_iterator& a, edm::DetSet<SiStripDigi>::const_iterator& b){
00154   refresh();
00155   pDetSet = new edm::DetSet<SiStripDigi>(cacheDetId);
00156   pDetSet->data.swap(vdigis);
00157   a=pDetSet->begin();
00158   b=pDetSet->end();
00159 }
00160 
00161 void SiStripApvShotCleaner::
00162 refresh(){
00163   if(pDetSet!=NULL)
00164     delete pDetSet;
00165 }