CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CalibTracker/SiStripAPVAnalysis/src/SimplePedestalCalculator.cc

Go to the documentation of this file.
00001 #include "CalibTracker/SiStripAPVAnalysis/interface/SimplePedestalCalculator.h"
00002 #include "DataFormats/SiStripDetId/interface/SiStripSubStructure.h"
00003 
00004 #include <cmath>
00005 #include <numeric>
00006 #include <algorithm>
00007 
00008 using namespace std;
00009 SimplePedestalCalculator::SimplePedestalCalculator(int evnt_ini) :   
00010                         numberOfEvents(0),
00011                         alreadyUsedEvent(false)
00012 {
00013   if (0) cout << "Constructing SimplePedestalCalculator " << endl;
00014   eventsRequiredToCalibrate = evnt_ini; 
00015   //  eventsRequiredToUpdate    = evnt_iter;
00016   //  cutToAvoidSignal          = sig_cut;
00017   init();
00018 }
00019 //
00020 // Initialization.
00021 //
00022 void SimplePedestalCalculator::init() { 
00023   theRawNoise.clear();
00024   thePedestal.clear();
00025   thePedSum.clear();
00026   thePedSqSum.clear();
00027   theEventPerStrip.clear();
00028   theStatus.setCalibrating();
00029 
00030 }
00031 //
00032 //  -- Destructor  
00033 //
00034 SimplePedestalCalculator::~SimplePedestalCalculator() {
00035   if (0) cout << "Destructing SimplePedestalCalculator " << endl;
00036 }
00037 
00038 
00039 //
00040 // -- Set Pedestal Update Status
00041 //
00042 void SimplePedestalCalculator::updateStatus(){
00043   if (theStatus.isCalibrating() && 
00044       numberOfEvents >= eventsRequiredToCalibrate) {
00045     theStatus.setUpdating();
00046   }
00047 }
00048 
00049 
00050 //
00051 // -- Initialize or Update (when needed) Pedestal Values
00052 //
00053 void SimplePedestalCalculator::updatePedestal(ApvAnalysis::RawSignalType& in) {
00054 
00055  if (alreadyUsedEvent == false) {
00056     alreadyUsedEvent = true;
00057     numberOfEvents++;
00058     if (theStatus.isCalibrating()) {
00059       initializePedestal(in);
00060     } else if (theStatus.isUpdating()) {
00061       refinePedestal(in);
00062     }  
00063     updateStatus();
00064   }
00065 
00066 
00067 }
00068 
00069 //
00070 // -- Initialize Pedestal Values using a set of events (eventsRequiredToCalibrate)
00071 //
00072 void SimplePedestalCalculator::initializePedestal(ApvAnalysis::RawSignalType& in) {
00073   if (numberOfEvents == 1) {
00074 
00075     thePedSum.clear();
00076     thePedSqSum.clear();
00077     theEventPerStrip.clear();
00078     
00079     thePedSum.reserve(128);
00080     thePedSqSum.reserve(128);
00081     theEventPerStrip.reserve(128);
00082     
00083     thePedSum.resize(in.data.size(), 0);
00084     thePedSqSum.resize(in.data.size(), 0);
00085     theEventPerStrip.resize(in.data.size(),0);
00086   }
00087 
00088   //eventsRequiredToCalibrate is considered the minimum number of events to be used
00089 
00090   if (numberOfEvents <= eventsRequiredToCalibrate) {
00091     edm::DetSet<SiStripRawDigi>::const_iterator i = in.data.begin();
00092     int ii=0;
00093     for (;i!=in.data.end() ; i++) {
00094       thePedSum[ii]   += (*i).adc();
00095       thePedSqSum[ii] += ((*i).adc())*((*i).adc());
00096       theEventPerStrip[ii]++;
00097       ii++;
00098     }
00099   }
00100   if (numberOfEvents == eventsRequiredToCalibrate) {
00101     thePedestal.clear();
00102     theRawNoise.clear();
00103     edm::DetSet<SiStripRawDigi>::const_iterator i = in.data.begin();
00104     int ii=0;
00105     for (;i!=in.data.end() ; i++) {
00106 
00107 
00108       // the pedestal is calculated as int, as required by FED.
00109       int avVal   = (theEventPerStrip[ii]) 
00110         ? thePedSum[ii]/theEventPerStrip[ii]:0;
00111 
00112       double sqAvVal = (theEventPerStrip[ii]) 
00113         ? thePedSqSum[ii]/theEventPerStrip[ii]:0.0;
00114       double corr_fac = (theEventPerStrip[ii] > 1) 
00115         ? (theEventPerStrip[ii]/(theEventPerStrip[ii]-1)) : 1.0;
00116       double rmsVal  =  (sqAvVal - avVal*avVal > 0.0) 
00117            ? sqrt(corr_fac * (sqAvVal - avVal*avVal)) : 0.0;    
00118       thePedestal.push_back(static_cast<float>(avVal));
00119       theRawNoise.push_back(static_cast<float>(rmsVal));
00120       ii++;
00121     }
00122 
00123   }
00124 }
00125 
00126 //
00127 // -- Update Pedestal Values when needed.
00128 //
00129 
00130 void SimplePedestalCalculator::refinePedestal(ApvAnalysis::RawSignalType& in) {
00131 
00132 
00133   // keep adding th adc count for any events 
00134 
00135   unsigned int ii=0;
00136   ApvAnalysis::RawSignalType::const_iterator i= in.data.begin();
00137   for (; i < in.data.end(); i++) {
00138     
00139     thePedSum[ii]   += (*i).adc();
00140     thePedSqSum[ii] += ((*i).adc())*((*i).adc());
00141     theEventPerStrip[ii]++;
00142     
00143     ii++;
00144   }
00145 
00146 
00147   // calculate a new pedestal any events, so it will come for free when for the last event
00148 
00149   for (unsigned int iii = 0; iii < in.data.size(); iii++) {
00150     if (theEventPerStrip[iii] > 10 ) {
00151       int avVal   = (theEventPerStrip[iii]) 
00152         ? thePedSum[iii]/theEventPerStrip[iii]:0;
00153 
00154       double sqAvVal = (theEventPerStrip[iii]) 
00155         ? thePedSqSum[iii]/theEventPerStrip[iii]:0.0;
00156 
00157       double rmsVal  =  (sqAvVal - avVal*avVal > 0.0) 
00158         ? sqrt(sqAvVal - avVal*avVal) : 0.0;    
00159       
00160       
00161       if (avVal != 0 ) {
00162         thePedestal[iii] = static_cast<float>(avVal);
00163         theRawNoise[iii] = static_cast<float>(rmsVal);
00164       }
00165     }
00166   }
00167 
00168 }
00169 
00170 
00171 
00172 
00173 
00174 //
00175 // Define New Event
00176 // 
00177 
00178 void SimplePedestalCalculator::newEvent(){
00179   alreadyUsedEvent = false;
00180 }