#include <DQM/SiStripCommissioningAnalysis/interface/ApvTimingAlgorithm.h>
Public Member Functions | |
ApvTimingAlgorithm (ApvTimingAnalysis *const ) | |
const Histo & | histo () const |
Container of histogram pointer and title. | |
virtual | ~ApvTimingAlgorithm () |
Private Member Functions | |
void | analyse () |
Performs histogram anaysis. | |
ApvTimingAlgorithm () | |
Private constructor. | |
void | extract (const std::vector< TH1 * > &) |
Extracts and organises histograms. | |
Private Attributes | |
Histo | histo_ |
Container of histogram pointer and title. |
Wingham, R.Bainbridge Analysis for timing run using APV tick marks.
Definition at line 15 of file ApvTimingAlgorithm.h.
ApvTimingAlgorithm::ApvTimingAlgorithm | ( | ApvTimingAnalysis * const | anal | ) |
Definition at line 16 of file ApvTimingAlgorithm.cc.
00017 : CommissioningAlgorithm(anal), 00018 histo_(0,"") 00019 {;}
virtual ApvTimingAlgorithm::~ApvTimingAlgorithm | ( | ) | [inline, virtual] |
ApvTimingAlgorithm::ApvTimingAlgorithm | ( | ) | [inline, private] |
void ApvTimingAlgorithm::analyse | ( | ) | [private, virtual] |
Performs histogram anaysis.
Implements CommissioningAlgorithm.
Definition at line 64 of file ApvTimingAlgorithm.cc.
References ApvTimingAnalysis::addErrorCode(), CommissioningAlgorithm::anal(), ApvTimingAnalysis::base_, funct::derivative(), prof2calltree::edges, ApvTimingAnalysis::height_, histo(), histo_, sistrip::incompletePlateau_, sistrip::invalid_, iter, max, mean(), min, sistrip::missingTickMark_, sistrip::mlCommissioning_, sistrip::noRisingEdges_, sistrip::nullPtr_, sistrip::numberOfBins_, ApvTimingAnalysis::peak_, sistrip::rejectedCandidate_, sistrip::smallDataRange_, sistrip::smallTickMarkHeight_, python::multivaluedict::sort(), funct::sqrt(), pyDBSRunClass::temp, dimuonsSequences_cff::threshold, sistrip::tickMarkBelowThresh_, ApvTimingAnalysis::tickMarkHeightThreshold_, ApvTimingAnalysis::time_, tmp, TrackValidation_HighPurity_cff::valid, and sistrip::valid_.
00064 { 00065 00066 if ( !anal() ) { 00067 edm::LogWarning(mlCommissioning_) 00068 << "[ApvTimingAlgorithm::" << __func__ << "]" 00069 << " NULL pointer to base Analysis object!"; 00070 return; 00071 } 00072 00073 CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() ); 00074 ApvTimingAnalysis* anal = dynamic_cast<ApvTimingAnalysis*>( tmp ); 00075 if ( !anal ) { 00076 edm::LogWarning(mlCommissioning_) 00077 << "[ApvTimingAlgorithm::" << __func__ << "]" 00078 << " NULL pointer to derived Analysis object!"; 00079 return; 00080 } 00081 00082 if ( !histo_.first ) { 00083 anal->addErrorCode(sistrip::nullPtr_); 00084 return; 00085 } 00086 00087 TProfile* histo = dynamic_cast<TProfile*>(histo_.first); 00088 if ( !histo ) { 00089 anal->addErrorCode(sistrip::nullPtr_); 00090 return; 00091 } 00092 00093 // Transfer histogram contents/errors/stats to containers 00094 uint16_t non_zero = 0; 00095 float max = -1. * sistrip::invalid_; 00096 float min = 1. * sistrip::invalid_; 00097 uint16_t nbins = static_cast<uint16_t>( histo->GetNbinsX() ); 00098 std::vector<float> bin_contents; 00099 std::vector<float> bin_errors; 00100 std::vector<float> bin_entries; 00101 bin_contents.reserve( nbins ); 00102 bin_errors.reserve( nbins ); 00103 bin_entries.reserve( nbins ); 00104 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) { 00105 bin_contents.push_back( histo->GetBinContent(ibin+1) ); 00106 bin_errors.push_back( histo->GetBinError(ibin+1) ); 00107 bin_entries.push_back( histo->GetBinEntries(ibin+1) ); 00108 if ( bin_entries[ibin] ) { 00109 if ( bin_contents[ibin] > max ) { max = bin_contents[ibin]; } 00110 if ( bin_contents[ibin] < min ) { min = bin_contents[ibin]; } 00111 non_zero++; 00112 } 00113 } 00114 if ( bin_contents.size() < 100 ) { 00115 anal->addErrorCode(sistrip::numberOfBins_); 00116 return; 00117 } 00118 00119 // Calculate range (max-min) and threshold level (range/2) 00120 float threshold = min + ( max - min ) / 2.; 00121 anal->base_ = min; 00122 anal->peak_ = max; 00123 anal->height_ = max - min; 00124 if ( max - min < ApvTimingAnalysis::tickMarkHeightThreshold_ ) { 00125 anal->addErrorCode(sistrip::smallDataRange_); 00126 return; 00127 } 00128 00129 // Associate samples with either "tick mark" or "baseline" 00130 std::vector<float> tick; 00131 std::vector<float> base; 00132 for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) { 00133 if ( bin_entries[ibin] ) { 00134 if ( bin_contents[ibin] < threshold ) { 00135 base.push_back( bin_contents[ibin] ); 00136 } else { 00137 tick.push_back( bin_contents[ibin] ); 00138 } 00139 } 00140 } 00141 00142 // Find median level of tick mark and baseline 00143 float tickmark = 0.; 00144 float baseline = 0.; 00145 sort( tick.begin(), tick.end() ); 00146 sort( base.begin(), base.end() ); 00147 if ( !tick.empty() ) { tickmark = tick[ tick.size()%2 ? tick.size()/2 : tick.size()/2 ]; } 00148 if ( !base.empty() ) { baseline = base[ base.size()%2 ? base.size()/2 : base.size()/2 ]; } 00149 anal->base_ = baseline; 00150 anal->peak_ = tickmark; 00151 anal->height_ = tickmark - baseline; 00152 if ( tickmark - baseline < ApvTimingAnalysis::tickMarkHeightThreshold_ ) { 00153 anal->addErrorCode(sistrip::smallTickMarkHeight_); 00154 return; 00155 } 00156 00157 // Find rms spread in "baseline" samples 00158 float mean = 0.; 00159 float mean2 = 0.; 00160 for ( uint16_t ibin = 0; ibin < base.size(); ibin++ ) { 00161 mean += base[ibin]; 00162 mean2 += base[ibin] * base[ibin]; 00163 } 00164 if ( !base.empty() ) { 00165 mean = mean / base.size(); 00166 mean2 = mean2 / base.size(); 00167 } else { 00168 mean = 0.; 00169 mean2 = 0.; 00170 } 00171 float baseline_rms = sqrt( fabs( mean2 - mean*mean ) ); 00172 00173 // Find rising edges (derivative across two bins > threshold) 00174 std::map<uint16_t,float> edges; 00175 for ( uint16_t ibin = 1; ibin < nbins-1; ibin++ ) { 00176 if ( bin_entries[ibin+1] && 00177 bin_entries[ibin-1] ) { 00178 float derivative = bin_contents[ibin+1] - bin_contents[ibin-1]; 00179 if ( derivative > 3.*baseline_rms ) { 00180 edges[ibin] = derivative; 00181 } 00182 } 00183 } 00184 if ( edges.empty() ) { 00185 anal->addErrorCode(sistrip::noRisingEdges_); 00186 return; 00187 } 00188 00189 // Iterate through "edges" map 00190 uint16_t max_derivative_bin = sistrip::invalid_; 00191 float max_derivative = -1.*sistrip::invalid_; 00192 00193 bool found = false; 00194 std::map<uint16_t,float>::iterator iter = edges.begin(); 00195 while ( !found && iter != edges.end() ) { 00196 00197 // Iterate through 50 subsequent samples 00198 bool valid = true; 00199 for ( uint16_t ii = 0; ii < 50; ii++ ) { 00200 uint16_t bin = iter->first + ii; 00201 00202 // Calc local derivative 00203 float temp = 0; 00204 if ( static_cast<uint32_t>(bin-1) < 0 || 00205 static_cast<uint32_t>(bin+1) >= nbins ) { 00206 valid = false; //@@ require complete plateau is found within histo 00207 anal->addErrorCode(sistrip::incompletePlateau_); 00208 continue; 00209 } 00210 temp = bin_contents[bin+1] - bin_contents[bin-1]; 00211 00212 // Store max derivative 00213 if ( temp > max_derivative ) { 00214 max_derivative = temp; 00215 max_derivative_bin = bin; 00216 } 00217 00218 // Check if samples following edge are all "high" 00219 if ( ii > 10 && ii < 40 && bin_entries[bin] && 00220 bin_contents[bin] < baseline + 5.*baseline_rms ) { 00221 valid = false; 00222 } 00223 00224 } 00225 00226 // Break from loop if tick mark found 00227 if ( valid ) { found = true; } 00228 else { 00229 max_derivative = -1.*sistrip::invalid_; 00230 max_derivative_bin = sistrip::invalid_; 00231 //edges.erase(iter); 00232 anal->addErrorCode(sistrip::rejectedCandidate_); 00233 } 00234 00235 iter++; // next candidate 00236 00237 } 00238 00239 // Record time monitorable and check tick mark height 00240 if ( max_derivative_bin <= sistrip::valid_ ) { 00241 anal->time_ = max_derivative_bin * 25. / 24.; 00242 if ( anal->height_ < ApvTimingAnalysis::tickMarkHeightThreshold_ ) { 00243 anal->addErrorCode(sistrip::tickMarkBelowThresh_); 00244 } 00245 } else { 00246 anal->addErrorCode(sistrip::missingTickMark_); 00247 } 00248 00249 }
void ApvTimingAlgorithm::extract | ( | const std::vector< TH1 * > & | histos | ) | [private, virtual] |
Extracts and organises histograms.
Implements CommissioningAlgorithm.
Definition at line 23 of file ApvTimingAlgorithm.cc.
References CommissioningAnalysis::addErrorCode(), CommissioningAlgorithm::anal(), sistrip::APV_TIMING, CommissioningAlgorithm::extractFedKey(), CommissioningAnalysis::fedKey(), histo_, sistrip::mlCommissioning_, sistrip::numberOfHistos_, indexGen::title, and sistrip::unexpectedTask_.
00023 { 00024 00025 if ( !anal() ) { 00026 edm::LogWarning(mlCommissioning_) 00027 << "[ApvTimingAlgorithm::" << __func__ << "]" 00028 << " NULL pointer to Analysis object!"; 00029 return; 00030 } 00031 00032 // Check number of histograms 00033 if ( histos.size() != 1 ) { 00034 anal()->addErrorCode(sistrip::numberOfHistos_); 00035 } 00036 00037 // Extract FED key from histo title 00038 if ( !histos.empty() ) { anal()->fedKey( extractFedKey( histos.front() ) ); } 00039 00040 // Extract histograms 00041 std::vector<TH1*>::const_iterator ihis = histos.begin(); 00042 for ( ; ihis != histos.end(); ihis++ ) { 00043 00044 // Check for NULL pointer 00045 if ( !(*ihis) ) { continue; } 00046 00047 // Check name 00048 SiStripHistoTitle title( (*ihis)->GetName() ); 00049 if ( title.runType() != sistrip::APV_TIMING ) { 00050 anal()->addErrorCode(sistrip::unexpectedTask_); 00051 continue; 00052 } 00053 00054 // Extract timing histo 00055 histo_.first = *ihis; 00056 histo_.second = (*ihis)->GetName(); 00057 00058 } 00059 00060 }
const ApvTimingAlgorithm::Histo & ApvTimingAlgorithm::histo | ( | ) | const [inline] |
Container of histogram pointer and title.
Definition at line 46 of file ApvTimingAlgorithm.h.
References histo_.
Referenced by analyse().
00046 { return histo_; }
Histo ApvTimingAlgorithm::histo_ [private] |