00001 #include "DQM/SiStripCommissioningAnalysis/interface/FastFedCablingAlgorithm.h" 00002 #include "CondFormats/SiStripObjects/interface/FastFedCablingAnalysis.h" 00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h" 00004 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h" 00005 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00006 #include "TProfile.h" 00007 #include "TH1.h" 00008 #include <iostream> 00009 #include <sstream> 00010 #include <iomanip> 00011 #include <cmath> 00012 00013 using namespace sistrip; 00014 00015 // ---------------------------------------------------------------------------- 00016 // 00017 FastFedCablingAlgorithm::FastFedCablingAlgorithm( const edm::ParameterSet & pset, FastFedCablingAnalysis* const anal ) 00018 : CommissioningAlgorithm(anal), 00019 histo_(0,"") 00020 {;} 00021 00022 // ---------------------------------------------------------------------------- 00023 // 00024 void FastFedCablingAlgorithm::extract( const std::vector<TH1*>& histos ) { 00025 00026 if ( !anal() ) { 00027 edm::LogWarning(mlCommissioning_) 00028 << "[FastFedCablingAlgorithm::" << __func__ << "]" 00029 << " NULL pointer to Analysis object!"; 00030 return; 00031 } 00032 00033 // Check number of histograms 00034 if ( histos.size() != 1 ) { 00035 anal()->addErrorCode(sistrip::numberOfHistos_); 00036 } 00037 00038 // Extract FED key from histo title 00039 if ( !histos.empty() ) { anal()->fedKey( extractFedKey( histos.front() ) ); } 00040 00041 // Extract histograms 00042 std::vector<TH1*>::const_iterator ihis = histos.begin(); 00043 for ( ; ihis != histos.end(); ihis++ ) { 00044 00045 // Check for NULL pointer 00046 if ( !(*ihis) ) { continue; } 00047 00048 // Check name 00049 SiStripHistoTitle title( (*ihis)->GetName() ); 00050 if ( title.runType() != sistrip::FAST_CABLING ) { 00051 anal()->addErrorCode(sistrip::unexpectedTask_); 00052 continue; 00053 } 00054 00055 // Extract cabling histo 00056 histo_.first = *ihis; 00057 histo_.second = (*ihis)->GetName(); 00058 00059 } 00060 00061 } 00062 00063 // ----------------------------------------------------------------------------- 00064 // 00065 void FastFedCablingAlgorithm::analyse() { 00066 00067 if ( !anal() ) { 00068 edm::LogWarning(mlCommissioning_) 00069 << "[FastFedCablingAlgorithm::" << __func__ << "]" 00070 << " NULL pointer to base Analysis object!"; 00071 return; 00072 } 00073 00074 CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() ); 00075 FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( tmp ); 00076 if ( !anal ) { 00077 edm::LogWarning(mlCommissioning_) 00078 << "[FastFedCablingAlgorithm::" << __func__ << "]" 00079 << " NULL pointer to derived Analysis object!"; 00080 return; 00081 } 00082 00083 if ( !histo_.first ) { 00084 anal->addErrorCode(sistrip::nullPtr_); 00085 return; 00086 } 00087 00088 TProfile* histo = dynamic_cast<TProfile*>(histo_.first); 00089 if ( !histo ) { 00090 anal->addErrorCode(sistrip::nullPtr_); 00091 return; 00092 } 00093 00094 // Initialization 00095 uint16_t zero_entries = 0; 00096 uint16_t nbins = static_cast<uint16_t>( histo->GetNbinsX() ); 00097 std::vector<float> contents; 00098 std::vector<float> errors; 00099 std::vector<float> entries; 00100 contents.reserve( nbins ); 00101 errors.reserve( nbins ); 00102 entries.reserve( nbins ); 00103 00104 // Copy histo contents to containers and find min/max 00105 anal->max_ = -1.*sistrip::invalid_; 00106 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) { 00107 contents.push_back( histo->GetBinContent(ibin+1) ); 00108 errors.push_back( histo->GetBinError(ibin+1) ); 00109 entries.push_back( histo->GetBinEntries(ibin+1) ); 00110 if ( entries[ibin] ) { 00111 if ( contents[ibin] > anal->max_ ) { anal->max_ = contents[ibin]; } 00112 if ( contents[ibin] < anal->min_ ) { anal->min_ = contents[ibin]; } 00113 } else { zero_entries++; } 00114 } 00115 if ( anal->max_ < -1. * sistrip::valid_ ) { anal->max_ = sistrip::invalid_; } 00116 00117 // Check number of bins 00118 if ( contents.size() != FastFedCablingAnalysis::nBitsForDcuId_ + FastFedCablingAnalysis::nBitsForLldCh_ ) { 00119 anal->addErrorCode(sistrip::numberOfBins_); 00120 return; 00121 } 00122 00123 // Check for bins with zero entries 00124 if ( zero_entries ) { 00125 anal->addErrorCode(sistrip::noEntries_); 00126 return; 00127 } 00128 00129 // Check min and max found 00130 if ( anal->max_ > sistrip::valid_ || 00131 anal->min_ > sistrip::valid_ ) { 00132 return; 00133 } 00134 00135 // Calculate range and mid-range levels 00136 anal->range_ = anal->max_ - anal->min_; 00137 anal->midRange_ = anal->min_ + anal->range_ / 2.; 00138 00139 // Check if range is above threshold 00140 if ( anal->range_ < FastFedCablingAnalysis::threshold_ ) { 00141 anal->addErrorCode(sistrip::smallDataRange_); 00142 return; 00143 } 00144 00145 // Identify samples to be either "low" or "high" 00146 std::vector<float> high; 00147 std::vector<float> low; 00148 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) { 00149 if ( entries[ibin] ) { 00150 if ( contents[ibin] < anal->midRange_ ) { 00151 low.push_back( contents[ibin] ); 00152 } else { 00153 high.push_back( contents[ibin] ); 00154 } 00155 } 00156 } 00157 00158 // Find median of high and low levels 00159 sort( high.begin(), high.end() ); 00160 sort( low.begin(), low.end() ); 00161 if ( !high.empty() ) { anal->highMedian_ = high[ high.size()%2 ? high.size()/2 : high.size()/2 ]; } 00162 if ( !low.empty() ) { anal->lowMedian_ = low[ low.size()%2 ? low.size()/2 : low.size()/2 ]; } 00163 00164 // Check if light levels above thresholds 00165 //if ( anal->highMedian_ < FastFedCablingAnalysis::dirtyThreshold_ ) { anal->addErrorCode(sistrip::invalidLightLevel_); } 00166 //if ( anal->lowMedian_ < FastFedCablingAnalysis::trimDacThreshold_ ) { anal->addErrorCode(sistrip::invalidTrimDacLevel_); } 00167 00168 // Find mean and rms in "low" samples 00169 anal->lowMean_ = 0.; 00170 anal->lowRms_ = 0.; 00171 for ( uint16_t ibin = 0; ibin < low.size(); ibin++ ) { 00172 anal->lowMean_ += low[ibin]; 00173 anal->lowRms_ += low[ibin] * low[ibin]; 00174 } 00175 if ( !low.empty() ) { 00176 anal->lowMean_ = anal->lowMean_ / low.size(); 00177 anal->lowRms_ = anal->lowRms_ / low.size(); 00178 } else { 00179 anal->lowMean_ = 1. * sistrip::invalid_; 00180 anal->lowRms_ = 1. * sistrip::invalid_; 00181 } 00182 if ( anal->lowMean_ < sistrip::valid_ ) { 00183 anal->lowRms_ = sqrt( fabs(anal->lowRms_-anal->lowMean_*anal->lowMean_) ); 00184 } else { 00185 anal->lowMean_ = 1. * sistrip::invalid_; 00186 anal->lowRms_ = 1. * sistrip::invalid_; 00187 } 00188 00189 // Find mean and rms in "high" samples 00190 anal->highMean_ = 0.; 00191 anal->highRms_ = 0.; 00192 for ( uint16_t ibin = 0; ibin < high.size(); ibin++ ) { 00193 anal->highMean_ += high[ibin]; 00194 anal->highRms_ += high[ibin] * high[ibin]; 00195 } 00196 if ( !high.empty() ) { 00197 anal->highMean_ = anal->highMean_ / high.size(); 00198 anal->highRms_ = anal->highRms_ / high.size(); 00199 } else { 00200 anal->highMean_ = 1. * sistrip::invalid_; 00201 anal->highRms_ = 1. * sistrip::invalid_; 00202 } 00203 if ( anal->highMean_ < sistrip::valid_ ) { 00204 anal->highRms_ = sqrt( fabs(anal->highRms_- anal->highMean_*anal->highMean_) ); 00205 } else { 00206 anal->highMean_ = 1. * sistrip::invalid_; 00207 anal->highRms_ = 1. * sistrip::invalid_; 00208 } 00209 00210 // Check if light levels above thresholds 00211 //if ( anal->highMean_ < FastFedCablingAnalysis::dirtyThreshold_ ) { anal->addErrorCode(sistrip::invalidLightLevel_); } 00212 //if ( anal->lowMean_ < FastFedCablingAnalysis::trimDacThreshold_ ) { anal->addErrorCode(sistrip::invalidTrimDacLevel_); } 00213 00214 // Recalculate range 00215 if ( anal->highMean_ < 1. * sistrip::valid_ && 00216 anal->lowMean_ < 1. * sistrip::valid_ ) { 00217 anal->range_ = anal->highMean_ - anal->lowMean_; 00218 anal->midRange_ = anal->lowMean_ + anal->range_ / 2.; 00219 } else { 00220 anal->range_ = 1. * sistrip::invalid_; 00221 anal->midRange_ = 1. * sistrip::invalid_; 00222 } 00223 00224 // Check if updated range is valid and above threshold 00225 if ( anal->range_ > 1. * sistrip::valid_ || 00226 anal->range_ < FastFedCablingAnalysis::threshold_ ) { 00227 anal->addErrorCode(sistrip::smallDataRange_); 00228 return; 00229 } 00230 00231 // Extract DCU id 00232 anal->dcuHardId_ = 0; 00233 for ( uint16_t ibin = 0; ibin < FastFedCablingAnalysis::nBitsForDcuId_; ibin++ ) { 00234 if ( entries[ibin] ) { 00235 if ( contents[ibin] > anal->midRange_ ) { 00236 anal->dcuHardId_ += 0xFFFFFFFF & (1<<ibin); 00237 } 00238 } 00239 } 00240 if ( !anal->dcuHardId_ ) { anal->dcuHardId_ = sistrip::invalid32_; } 00241 00242 // Extract DCU id 00243 anal->lldCh_ = 0; 00244 for ( uint16_t ibin = 0; ibin < FastFedCablingAnalysis::nBitsForLldCh_; ibin++ ) { 00245 if ( entries[FastFedCablingAnalysis::nBitsForDcuId_+ibin] ) { 00246 if ( contents[FastFedCablingAnalysis::nBitsForDcuId_+ibin] > anal->midRange_ ) { 00247 anal->lldCh_ += ( 0x3 & (1<<ibin) ); 00248 } 00249 } 00250 } 00251 anal->lldCh_++; // starts from 1 00252 if ( !anal->lldCh_ ) { anal->lldCh_ = sistrip::invalid_; } 00253 00254 }