Go to the documentation of this file.00001 #include "DQM/SiStripCommissioningAnalysis/interface/OptoScanAlgorithm.h"
00002 #include "CondFormats/SiStripObjects/interface/OptoScanAnalysis.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h"
00004 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
00005 #include "DQM/SiStripCommissioningAnalysis/src/Utility.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "TProfile.h"
00008 #include "TH1.h"
00009 #include <iostream>
00010 #include <sstream>
00011 #include <iomanip>
00012
00013 using namespace sistrip;
00014
00015
00016
00017 OptoScanAlgorithm::OptoScanAlgorithm( const edm::ParameterSet & pset, OptoScanAnalysis* const anal )
00018 : CommissioningAlgorithm(anal),
00019 histos_( 4, std::vector<Histo>( 3, Histo(0,"") ) ),
00020 targetGain_(pset.getParameter<double>("TargetGain"))
00021 {
00022 edm::LogInfo(mlCommissioning_)
00023 << "[PedestalsAlgorithm::" << __func__ << "]"
00024 << " Set target gain to: " << targetGain_;
00025 }
00026
00027
00028
00029 void OptoScanAlgorithm::extract( const std::vector<TH1*>& histos ) {
00030
00031 if ( !anal() ) {
00032 edm::LogWarning(mlCommissioning_)
00033 << "[OptoScanAlgorithm::" << __func__ << "]"
00034 << " NULL pointer to Analysis object!";
00035 return;
00036 }
00037
00038
00039 if ( histos.size() != 12 ) {
00040 anal()->addErrorCode(sistrip::numberOfHistos_);
00041 }
00042
00043
00044 if ( !histos.empty() ) anal()->fedKey( extractFedKey( histos.front() ) );
00045
00046
00047 std::vector<TH1*>::const_iterator ihis = histos.begin();
00048 for ( ; ihis != histos.end(); ihis++ ) {
00049
00050
00051 if ( !(*ihis) ) { continue; }
00052
00053
00054 SiStripHistoTitle title( (*ihis)->GetName() );
00055 if ( title.runType() != sistrip::OPTO_SCAN ) {
00056 anal()->addErrorCode(sistrip::unexpectedTask_);
00057 continue;
00058 }
00059
00060
00061 uint16_t gain = sistrip::invalid_;
00062 if ( title.extraInfo().find(sistrip::extrainfo::gain_) != std::string::npos ) {
00063 std::stringstream ss;
00064 ss << title.extraInfo().substr( title.extraInfo().find(sistrip::extrainfo::gain_) + (sizeof(sistrip::extrainfo::gain_) - 1), 1 );
00065 ss >> std::dec >> gain;
00066 }
00067 uint16_t digital = sistrip::invalid_;
00068 if ( title.extraInfo().find(sistrip::extrainfo::digital_) != std::string::npos ) {
00069 std::stringstream ss;
00070 ss << title.extraInfo().substr( title.extraInfo().find(sistrip::extrainfo::digital_) + (sizeof(sistrip::extrainfo::digital_) - 1), 1 );
00071 ss >> std::dec >> digital;
00072 }
00073 bool baseline_rms = false;
00074 if ( title.extraInfo().find(sistrip::extrainfo::baselineRms_) != std::string::npos ) {
00075 baseline_rms = true;
00076 }
00077
00078 if ( gain <= 3 ) {
00079 if ( digital <= 1 ) {
00080 histos_[gain][digital].first = *ihis;
00081 histos_[gain][digital].second = (*ihis)->GetName();
00082 } else if ( baseline_rms ) {
00083 histos_[gain][2].first = *ihis;
00084 histos_[gain][2].second = (*ihis)->GetName();
00085 } else {
00086 anal()->addErrorCode(sistrip::unexpectedExtraInfo_);
00087 }
00088 } else {
00089 anal()->addErrorCode(sistrip::unexpectedExtraInfo_);
00090 }
00091
00092 }
00093
00094 }
00095
00096
00097
00098 void OptoScanAlgorithm::analyse() {
00099
00100 if ( !anal() ) {
00101 edm::LogWarning(mlCommissioning_)
00102 << "[OptoScanAlgorithm::" << __func__ << "]"
00103 << " NULL pointer to base Analysis object!";
00104 return;
00105 }
00106
00107 CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() );
00108 OptoScanAnalysis* anal = dynamic_cast<OptoScanAnalysis*>( tmp );
00109 if ( !anal ) {
00110 edm::LogWarning(mlCommissioning_)
00111 << "[OptoScanAlgorithm::" << __func__ << "]"
00112 << " NULL pointer to derived Analysis object!";
00113 return;
00114 }
00115
00116
00117 for ( uint16_t igain = 0; igain < 4; igain++ ) {
00118
00119
00120 TH1* base_his = histos_[igain][0].first;
00121 TH1* peak_his = histos_[igain][1].first;
00122 TH1* noise_his = histos_[igain][2].first;
00123
00124 if ( !base_his ) {
00125 anal->addErrorCode(sistrip::nullPtr_);
00126 return;
00127 }
00128
00129 if ( !peak_his ) {
00130 anal->addErrorCode(sistrip::nullPtr_);
00131 return;
00132 }
00133
00134 if ( !noise_his ) {
00135 anal->addErrorCode(sistrip::nullPtr_);
00136 return;
00137 }
00138
00139 TProfile* base_histo = dynamic_cast<TProfile*>(base_his);
00140 if ( !base_histo ) {
00141 anal->addErrorCode(sistrip::nullPtr_);
00142 return;
00143 }
00144
00145 TProfile* peak_histo = dynamic_cast<TProfile*>(peak_his);
00146 if ( !peak_histo ) {
00147 anal->addErrorCode(sistrip::nullPtr_);
00148 return;
00149 }
00150
00151 TProfile* noise_histo = dynamic_cast<TProfile*>(noise_his);
00152 if ( !noise_histo ) {
00153 anal->addErrorCode(sistrip::nullPtr_);
00154 return;
00155 }
00156
00157
00158 uint16_t nbins = static_cast<uint16_t>( peak_histo->GetNbinsX() );
00159 if ( static_cast<uint16_t>( base_histo->GetNbinsX() ) != nbins ) {
00160 anal->addErrorCode(sistrip::numberOfBins_);
00161 if ( static_cast<uint16_t>( base_histo->GetNbinsX() ) < nbins ) {
00162 nbins = static_cast<uint16_t>( base_histo->GetNbinsX() );
00163 }
00164 }
00165
00166
00167 std::vector<float> peak_contents(0);
00168 std::vector<float> peak_errors(0);
00169 std::vector<float> peak_entries(0);
00170 std::vector<float> base_contents(0);
00171 std::vector<float> base_errors(0);
00172 std::vector<float> base_entries(0);
00173 std::vector<float> noise_contents(0);
00174 std::vector<float> noise_errors(0);
00175 std::vector<float> noise_entries(0);
00176 float peak_max = -1.*sistrip::invalid_;
00177 float peak_min = 1.*sistrip::invalid_;
00178 float base_max = -1.*sistrip::invalid_;
00179 float base_min = 1.*sistrip::invalid_;
00180 float noise_max = -1.*sistrip::invalid_;
00181 float noise_min = 1.*sistrip::invalid_;
00182
00183
00184 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
00185
00186
00187 peak_contents.push_back( peak_histo->GetBinContent(ibin+1) );
00188 peak_errors.push_back( peak_histo->GetBinError(ibin+1) );
00189 peak_entries.push_back( peak_histo->GetBinEntries(ibin+1) );
00190 if ( peak_entries[ibin] ) {
00191 if ( peak_contents[ibin] > peak_max ) { peak_max = peak_contents[ibin]; }
00192 if ( peak_contents[ibin] < peak_min && ibin ) { peak_min = peak_contents[ibin]; }
00193 }
00194
00195
00196 base_contents.push_back( base_histo->GetBinContent(ibin+1) );
00197 base_errors.push_back( base_histo->GetBinError(ibin+1) );
00198 base_entries.push_back( base_histo->GetBinEntries(ibin+1) );
00199 if ( base_entries[ibin] ) {
00200 if ( base_contents[ibin] > base_max ) { base_max = base_contents[ibin]; }
00201 if ( base_contents[ibin] < base_min && ibin ) { base_min = base_contents[ibin]; }
00202 }
00203
00204
00205 noise_contents.push_back( noise_histo->GetBinContent(ibin+1) );
00206 noise_errors.push_back( noise_histo->GetBinError(ibin+1) );
00207 noise_entries.push_back( noise_histo->GetBinEntries(ibin+1) );
00208 if ( noise_entries[ibin] ) {
00209 if ( noise_contents[ibin] > noise_max ) { noise_max = noise_contents[ibin]; }
00210 if ( noise_contents[ibin] < noise_min && ibin ) { noise_min = noise_contents[ibin]; }
00211 }
00212
00213 }
00214
00215
00216
00217
00218 float zero_light_level = sistrip::invalid_;
00219 float zero_light_error = sistrip::invalid_;
00220 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
00221 if ( base_entries[ibin] ) {
00222 zero_light_level = base_contents[ibin];
00223 zero_light_error = base_errors[ibin];
00224 break;
00225 }
00226 }
00227
00228 float zero_light_thres = sistrip::invalid_;
00229 if ( zero_light_level <= sistrip::maximum_ &&
00230 zero_light_error <= sistrip::maximum_ ) {
00231 zero_light_thres = zero_light_level + 5. * zero_light_error;
00232 } else {
00233 std::stringstream ss;
00234 ss << sistrip::invalidZeroLightLevel_ << "ForGain" << igain;
00235 anal->addErrorCode( ss.str() );
00236 continue;
00237 }
00238
00239
00240 float base_range = base_max - base_min;
00241
00242
00243 float max = peak_max < base_max ? peak_max : base_max;
00244 float min = peak_min > base_min ? peak_min : base_min;
00245 float range = max - min;
00246
00247
00248 std::vector<bool> above_zero_light;
00249 above_zero_light.resize(3,true);
00250
00251
00252 sistrip::LinearFit peak_high;
00253 sistrip::LinearFit base_high;
00254 sistrip::LinearFit base_low;
00255
00256
00257 uint16_t peak_bin = 0;
00258 uint16_t base_bin = 0;
00259 uint16_t low_bin = 0;
00260 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
00261
00262
00263 if ( base_entries[ibin] ) {
00264 above_zero_light.erase( above_zero_light.begin() );
00265 if ( base_contents[ibin] > zero_light_thres ) { above_zero_light.push_back( true ); }
00266 else { above_zero_light.push_back( false ); }
00267 if ( above_zero_light.size() != 3 ) { above_zero_light.resize(3,false); }
00268 }
00269
00270
00271 if ( peak_entries[ibin] &&
00272 peak_contents[ibin] > ( min + 0.2*range ) &&
00273 peak_contents[ibin] < ( min + 0.8*range ) ) {
00274 if ( !peak_bin ) { peak_bin = ibin; }
00275 if ( ( ibin - peak_bin ) < 10 ) {
00276 peak_high.add( ibin, peak_contents[ibin] );
00277 }
00278 }
00279
00280 if ( base_entries[ibin] &&
00281 base_contents[ibin] > ( min + 0.2*range ) &&
00282 base_contents[ibin] < ( min + 0.8*range ) ) {
00283 if ( !base_bin ) { base_bin = ibin; }
00284 if ( ( ibin - base_bin ) < 10 ) {
00285 base_high.add( ibin, base_contents[ibin] );
00286 }
00287 }
00288
00289 if ( base_entries[ibin] &&
00290
00291 base_contents[ibin] > ( base_min + 0.2*base_range ) &&
00292 base_contents[ibin] < ( base_min + 0.6*base_range ) ) {
00293 if ( !low_bin ) { low_bin = ibin; }
00294 if ( ( ibin - low_bin ) < 10 ) {
00295 base_low.add( ibin, base_contents[ibin] );
00296 }
00297 }
00298
00299 }
00300
00301
00302 float mid = min + 0.5*range;
00303 sistrip::LinearFit::Params peak_params;
00304 sistrip::LinearFit::Params base_params;
00305 peak_high.fit( peak_params );
00306 base_high.fit( base_params );
00307
00308 float peak_pos = sistrip::invalid_;
00309 float base_pos = sistrip::invalid_;
00310 float width = sistrip::invalid_;
00311 if ( peak_params.b_ > 0. ) {
00312 peak_pos = ( mid - peak_params.a_ ) / peak_params.b_;
00313 }
00314 if ( base_params.b_ > 0. ) {
00315 base_pos = ( mid - base_params.a_ ) / base_params.b_;
00316 }
00317 if ( base_pos < sistrip::valid_ &&
00318 peak_pos < sistrip::valid_ ) {
00319 width = base_pos - peak_pos;
00320 }
00321
00322
00323 sistrip::LinearFit::Params low_params;
00324 base_low.fit( low_params );
00325 float lift_off = sistrip::invalid_;
00326 if ( low_params.b_ > 0. ) {
00327 lift_off = ( zero_light_level - low_params.a_ ) / low_params.b_;
00328 }
00329
00330
00331
00332
00333 if ( low_params.b_ > 0. ) {
00334 anal->baseSlope_[igain] = low_params.b_;
00335 }
00336
00337
00338 if ( lift_off <= sistrip::maximum_ ) {
00339 anal->bias_[igain] = static_cast<uint16_t>( lift_off ) + 2;
00340 } else { anal->bias_[igain] = OptoScanAnalysis::defaultBiasSetting_; }
00341
00342
00343 if ( lift_off <= sistrip::maximum_ ) {
00344 anal->liftOff_[igain] = 0.45 * lift_off;
00345 }
00346
00347
00348 if ( width < sistrip::invalid_ ) {
00349 anal->threshold_[igain] = 0.45 * ( lift_off - width/2. );
00350 }
00351
00352
00353 anal->zeroLight_[igain] = zero_light_level;
00354
00355
00356 uint16_t bin_number = sistrip::invalid_;
00357 if ( anal->threshold_[igain] < sistrip::valid_ ) {
00358
00359
00360
00361
00362 bin_number = (uint16_t) (lift_off + width / 3.);
00363 }
00364 if ( bin_number < sistrip::valid_ ) {
00365 if ( bin_number < noise_contents.size() ) {
00366 anal->linkNoise_[igain] = noise_contents[bin_number];
00367 } else { anal->addErrorCode(sistrip::unexpectedBinNumber_); }
00368 }
00369
00370
00371 if ( low_params.b_ <= sistrip::maximum_ &&
00372 width <= sistrip::maximum_ ) {
00373 anal->tickHeight_[igain] = width * low_params.b_;
00374 }
00375
00376
00377 if ( anal->tickHeight_[igain] < sistrip::invalid_-1. ) {
00378 anal->measGain_[igain] = anal->tickHeight_[igain] * OptoScanAnalysis::fedAdcGain_ / 0.800;
00379 } else { anal->measGain_[igain] = sistrip::invalid_; }
00380
00381 }
00382
00383
00384 const float target_gain = targetGain_;
00385
00386 float diff_in_gain = sistrip::invalid_;
00387 for ( uint16_t igain = 0; igain < 4; igain++ ) {
00388
00389
00390 if ( anal->measGain_[igain] > sistrip::maximum_ ) { continue; }
00391
00392
00393 if ( fabs( anal->measGain_[igain] - target_gain ) < diff_in_gain ) {
00394 anal->gain_ = igain;
00395 diff_in_gain = fabs( anal->measGain_[igain] - target_gain );
00396 }
00397
00398 }
00399
00400
00401 if ( anal->gain_ > sistrip::maximum_ ) { anal->gain_ = OptoScanAnalysis::defaultGainSetting_; }
00402
00403 }
00404
00405
00406
00407 CommissioningAlgorithm::Histo OptoScanAlgorithm::histo( const uint16_t& gain,
00408 const uint16_t& digital_level ) const {
00409 if ( gain <= 3 && digital_level <= 1 ) { return histos_[gain][digital_level]; }
00410 else { return Histo(0,""); }
00411 }