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 }