00001 #include "DQM/SiStripCommissioningSources/interface/OptoScanTask.h"
00002 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h"
00004 #include "DQMServices/Core/interface/DQMStore.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include <algorithm>
00007 #include <math.h>
00008
00009 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00010 #include <iomanip>
00011
00012 using namespace sistrip;
00013
00014
00015
00016 OptoScanTask::OptoScanTask( DQMStore* dqm,
00017 const FedChannelConnection& conn ) :
00018 CommissioningTask( dqm, conn, "OptoScanTask" ),
00019 opto_()
00020 {}
00021
00022
00023
00024 OptoScanTask::~OptoScanTask() {
00025 }
00026
00027
00028
00029 void OptoScanTask::book() {
00030
00031 uint16_t nbins = 50;
00032 uint16_t gains = 4;
00033
00034 std::string title;
00035
00036
00037 opto_.resize( gains );
00038 for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) { opto_[igain].resize(3); }
00039
00040 for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) {
00041 for ( uint16_t ihisto = 0; ihisto < 3; ihisto++ ) {
00042
00043
00044 std::stringstream extra_info;
00045 extra_info << sistrip::extrainfo::gain_ << igain;
00046 if ( ihisto == 0 || ihisto == 1 ) {
00047 extra_info << sistrip::extrainfo::digital_ << ihisto;
00048 } else {
00049 extra_info << sistrip::extrainfo::baselineRms_;
00050 }
00051
00052
00053 title = SiStripHistoTitle( sistrip::EXPERT_HISTO,
00054 sistrip::OPTO_SCAN,
00055 sistrip::FED_KEY,
00056 fedKey(),
00057 sistrip::LLD_CHAN,
00058 connection().lldChannel(),
00059 extra_info.str() ).title();
00060
00061
00062 opto_[igain][ihisto].histo( dqm()->bookProfile( title, title,
00063 nbins, 0.5, nbins*1.+0.5,
00064 1024, -0.5, 1023.5 ) );
00065
00066 opto_[igain][ihisto].vNumOfEntries_.resize(nbins,0);
00067 opto_[igain][ihisto].vSumOfContents_.resize(nbins,0);
00068 opto_[igain][ihisto].vSumOfSquares_.resize(nbins,0);
00069
00070 }
00071 }
00072
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 void OptoScanTask::fill( const SiStripEventSummary& summary,
00083 const edm::DetSet<SiStripRawDigi>& digis ) {
00084
00085
00086
00087 if ( digis.data.empty() ) {
00088 edm::LogWarning(mlDqmSource_)
00089 << "[OptoScanTask::" << __func__ << "]"
00090 << " Unexpected number of digis! "
00091 << digis.data.size();
00092 } else {
00093
00094
00095 uint16_t gain = summary.lldGain();
00096 uint16_t bias = summary.lldBias();
00097
00098 if ( gain >= opto_.size() ) {
00099 opto_.resize( gain );
00100 for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) {
00101 if ( opto_[gain].size() != 3 ) { opto_[gain].resize( 3 ); }
00102 }
00103 edm::LogWarning(mlDqmSource_)
00104 << "[OptoScanTask::" << __func__ << "]"
00105 << " Unexpected gain value! " << gain;
00106 }
00107
00108 if ( bias > 50 ) { return; }
00109
00110
00111 std::vector<float> baseline;
00112 std::pair<float,float> digital_range;
00113 digital_range.first = sistrip::invalid_;
00114 digital_range.second = sistrip::invalid_;
00115 float baseline_rms = sistrip::invalid_;
00116
00117 locateTicks( digis, digital_range, baseline, baseline_rms );
00118
00119 uint16_t bin = bias - 1;
00120
00121
00122 if ( digital_range.first < 1. * sistrip::valid_ ) {
00123 updateHistoSet( opto_[gain][0], bin, digital_range.first );
00124 }
00125
00126
00127 if ( digital_range.second < 1. * sistrip::valid_ ) {
00128 updateHistoSet( opto_[gain][1], bin, digital_range.second );
00129 }
00130
00131
00132 if ( baseline_rms < 1. * sistrip::valid_ ) {
00133 updateHistoSet( opto_[gain][2], bin, baseline_rms );
00134 }
00135
00136 }
00137
00138 }
00139
00140
00141
00142
00143 void OptoScanTask::update() {
00144
00145 for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) {
00146 for ( uint16_t ihisto = 0; ihisto < opto_[igain].size(); ihisto++ ) {
00147 updateHistoSet( opto_[igain][ihisto] );
00148 }
00149 }
00150
00151 }
00152
00153
00154
00155 void OptoScanTask::locateTicks( const edm::DetSet<SiStripRawDigi>& digis,
00156 std::pair<float,float>& range,
00157 std::vector<float>& baseline,
00158 float& baseline_rms ) {
00159
00160
00161 std::vector<uint16_t> adc;
00162 adc.reserve( digis.data.size() );
00163 for ( uint16_t iadc = 0; iadc < digis.data.size(); iadc++ ) { adc.push_back( digis.data[iadc].adc() ); }
00164 sort( adc.begin(), adc.end() );
00165
00166
00167 if ( true ) {
00168
00169 if ( adc.size() > 70 ) {
00170
00171
00172 range.first = adc.front();
00173 range.second = adc.back();
00174
00175
00176 std::vector<uint16_t>::const_iterator ii = adc.begin();
00177 std::vector<uint16_t>::const_iterator jj = adc.end() - 8 * ( ( adc.size() / 70 ) + 1 );
00178 std::vector<uint16_t> truncated;
00179 truncated.resize( jj - ii );
00180 std::copy( ii, jj, truncated.begin() );
00181 if ( truncated.empty() ) { return; }
00182
00183
00184 float b_mean = 0.;
00185 std::vector<uint16_t>::const_iterator iii = truncated.begin();
00186 std::vector<uint16_t>::const_iterator jjj = truncated.end();
00187 for ( ; iii != jjj; ++iii ) { b_mean += *iii; }
00188 b_mean /= ( 1. * truncated.size() );
00189
00190
00191 float b_rms = 0.;
00192 std::vector<uint16_t>::const_iterator iiii = truncated.begin();
00193 std::vector<uint16_t>::const_iterator jjjj = truncated.end();
00194 for ( ; iiii != jjjj; ++iiii ) { b_rms += fabs( *iiii - b_mean ); }
00195
00196
00197 baseline_rms = sqrt ( b_rms / ( 1. * truncated.size() ) );
00198
00199 } else {
00200 edm::LogWarning(mlDqmSource_)
00201 << "[OptoScanTask::" << __func__ << "]"
00202 << " Insufficient ADC values: " << adc.size();
00203 }
00204
00205 } else {
00206
00207
00208 std::vector<float> base;
00209 base.reserve( adc.size() );
00210 float base_mean = 0.;
00211 float base_rms = 0.;
00212 float base_median = 0.;
00213
00214
00215 std::vector<float> tick;
00216 tick.reserve( adc.size() );
00217 float tick_mean = 0.;
00218 float tick_rms = 0.;
00219 float tick_median = 0.;
00220
00221
00222 uint16_t mid_range = adc.front() + ( adc.back() - adc.front() ) / 2;
00223
00224
00225 std::vector<uint16_t>::const_iterator iter = adc.begin();
00226 std::vector<uint16_t>::const_iterator jter = adc.end();
00227 for ( ; iter != jter; iter++ ) {
00228 if ( *iter <= mid_range ) {
00229 base.push_back( *iter );
00230 base_mean += *iter;
00231 base_rms += (*iter) * (*iter);
00232 } else {
00233 tick.push_back( *iter );
00234 tick_mean += *iter;
00235 tick_rms += (*iter) * (*iter);
00236 }
00237 }
00238
00239
00240 if ( !base.empty() ) {
00241 base_mean = base_mean / base.size();
00242 base_rms = base_rms / base.size();
00243 base_rms = sqrt( fabs( base_rms - base_mean*base_mean ) );
00244 } else {
00245 base_mean = 1. * sistrip::invalid_;
00246 base_rms = 1. * sistrip::invalid_;
00247 base_median = 1. * sistrip::invalid_;
00248 }
00249
00250
00251 if ( !tick.empty() ) {
00252 tick_mean = tick_mean / tick.size();
00253 tick_rms = tick_rms / tick.size();
00254 tick_rms = sqrt( fabs( tick_rms - tick_mean*tick_mean ) );
00255 } else {
00256 tick_mean = 1. * sistrip::invalid_;
00257 tick_rms = 1. * sistrip::invalid_;
00258 tick_median = 1. * sistrip::invalid_;
00259 }
00260
00261 baseline.reserve( base.size() );
00262 baseline.assign( base.begin(), base.end() );
00263 range.first = base_mean;
00264 range.second = tick_mean;
00265 baseline_rms = base_rms;
00266
00267 }
00268
00269 }
00270
00271
00272
00273 void OptoScanTask::deprecated( const edm::DetSet<SiStripRawDigi>& digis,
00274 std::pair< uint16_t, uint16_t >& digital_range,
00275 bool first_tick_only ) {
00276
00277
00278
00279
00280 std::vector<uint16_t> adc; adc.reserve( digis.data.size() );
00281 for ( uint16_t iadc = 0; iadc < digis.data.size(); iadc++ ) { adc.push_back( digis.data[iadc].adc() ); }
00282 sort( adc.begin(), adc.end() );
00283 uint16_t size = adc.size();
00284
00285
00286 float sum = 0, sum2 = 0, num = 0;
00287 for ( uint16_t iadc = static_cast<uint16_t>( 0.1*size );
00288 iadc < static_cast<uint16_t>( 0.9*adc.size() ); iadc++ ) {
00289 sum += adc[iadc];
00290 sum2 += adc[iadc] * adc[iadc];
00291 num++;
00292 }
00293 float mean = 0, mean2 = 0, sigma = 0;
00294 if ( num ) {
00295 mean = sum / num;
00296 mean2 = sum2 / num;
00297 if ( mean2 > mean*mean ) { sigma = sqrt( mean2 - mean*mean ); }
00298 }
00299
00300
00301 float threshold = mean + sigma * 5.;
00302
00303 std::vector<uint32_t> baseline;
00304 std::vector<uint32_t> tickmark;
00305 for ( uint16_t iadc = 0; iadc < adc.size(); iadc++ ) {
00306 if ( adc[iadc] > threshold ) { tickmark.push_back( adc[iadc] ); }
00307 else { baseline.push_back( adc[iadc] ); }
00308 }
00309
00310
00311 if ( !baseline.empty() ) {
00312 uint16_t sample = baseline.size()%2 ? baseline.size()/2 : baseline.size()/2-1;
00313 digital_range.first = baseline[ sample ];
00314 } else { digital_range.first = 1025; }
00315
00316 if ( !tickmark.empty() ) {
00317 uint16_t sample = tickmark.size()%2 ? tickmark.size()/2 : tickmark.size()/2-1;
00318 digital_range.second = tickmark[ sample ];
00319 } else { digital_range.second = 1025; }
00320
00321 }