CMS 3D CMS Logo

FedTimingAlgorithm.cc
Go to the documentation of this file.
6 #include "TProfile.h"
7 #include "TH1.h"
8 #include <iostream>
9 #include <iomanip>
10 #include <cmath>
11 
12 using namespace sistrip;
13 
14 // ----------------------------------------------------------------------------
15 //
17  : CommissioningAlgorithm(anal),
18  histo_(0,"")
19 {;}
20 
21 // ----------------------------------------------------------------------------
22 //
23 void FedTimingAlgorithm::extract( const std::vector<TH1*>& histos ) {
24 
25  if ( !anal() ) {
27  << "[FedTimingAlgorithm::" << __func__ << "]"
28  << " NULL pointer to Analysis object!";
29  return;
30  }
31 
32  // Check number of histograms
33  if ( histos.size() != 1 ) {
35  }
36 
37  // Extract FED key from histo title
38  if ( !histos.empty() ) { anal()->fedKey( extractFedKey( histos.front() ) ); }
39 
40  // Extract histograms
41  std::vector<TH1*>::const_iterator ihis = histos.begin();
42  for ( ; ihis != histos.end(); ihis++ ) {
43 
44  // Check for NULL pointer
45  if ( !(*ihis) ) { continue; }
46 
47  // Check name
48  SiStripHistoTitle title( (*ihis)->GetName() );
49  if ( title.runType() != sistrip::FED_TIMING ) {
51  continue;
52  }
53 
54  // Extract timing histo
55  histo_.first = *ihis;
56  histo_.second = (*ihis)->GetName();
57 
58  }
59 
60 }
61 
62 // ----------------------------------------------------------------------------
63 //
65 
66  if ( !anal() ) {
68  << "[FedTimingAlgorithm::" << __func__ << "]"
69  << " NULL pointer to base Analysis object!";
70  return;
71  }
72 
74  FedTimingAnalysis* anal = dynamic_cast<FedTimingAnalysis*>( tmp );
75  if ( !anal ) {
77  << "[FedTimingAlgorithm::" << __func__ << "]"
78  << " NULL pointer to derived Analysis object!";
79  return;
80  }
81 
82  if ( !histo_.first ) {
84  return;
85  }
86 
87  // Transfer histogram contents/errors/stats to containers
88  uint16_t non_zero = 0;
89  float max = -1.e9;
90  float min = 1.e9;
91  uint16_t nbins = static_cast<uint16_t>( histo_.first->GetNbinsX() );
92  std::vector<float> bin_contents;
93  std::vector<float> bin_errors;
94  std::vector<float> bin_entries;
95  bin_contents.reserve( nbins );
96  bin_errors.reserve( nbins );
97  bin_entries.reserve( nbins );
98  for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
99  bin_contents.push_back( histo_.first->GetBinContent(ibin+1) );
100  bin_errors.push_back( histo_.first->GetBinError(ibin+1) );
101  //bin_entries.push_back( histo_.first->GetBinEntries(ibin+1) );
102  if ( bin_entries[ibin] ) {
103  if ( bin_contents[ibin] > max ) { max = bin_contents[ibin]; }
104  if ( bin_contents[ibin] < min ) { min = bin_contents[ibin]; }
105  non_zero++;
106  }
107  }
108 
109  //LogTrace(mlCommissioning_) << " Number of bins with non-zero entries: " << non_zero;
110  if ( bin_contents.size() < 100 ) {
112  return;
113  }
114 
115  // Calculate range (max-min) and threshold level (range/2)
116  float range = max - min;
117  float threshold = min + range / 2.;
118  if ( range < 50. ) {
120  return;
121  }
122  //LogTrace(mlCommissioning_) << " ADC samples: max/min/range/threshold: "
123  //<< max << "/" << min << "/" << range << "/" << threshold;
124 
125  // Associate samples with either "tick mark" or "baseline"
126  std::vector<float> tick;
127  std::vector<float> base;
128  for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
129  if ( bin_entries[ibin] ) {
130  if ( bin_contents[ibin] < threshold ) {
131  base.push_back( bin_contents[ibin] );
132  } else {
133  tick.push_back( bin_contents[ibin] );
134  }
135  }
136  }
137  //LogTrace(mlCommissioning_) << " Number of 'tick mark' samples: " << tick.size()
138  //<< " Number of 'baseline' samples: " << base.size();
139 
140  // Find median level of tick mark and baseline
141  float tickmark = 0.;
142  float baseline = 0.;
143  sort( tick.begin(), tick.end() );
144  sort( base.begin(), base.end() );
145  if ( !tick.empty() ) { tickmark = tick[ tick.size()%2 ? tick.size()/2 : tick.size()/2 ]; }
146  if ( !base.empty() ) { baseline = base[ base.size()%2 ? base.size()/2 : base.size()/2 ]; }
147  //LogTrace(mlCommissioning_) << " Tick mark level: " << tickmark << " Baseline level: " << baseline
148  //<< " Range: " << (tickmark-baseline);
149  if ( (tickmark-baseline) < 50. ) {
151  return;
152  }
153 
154  // Find rms spread in "baseline" samples
155  float mean = 0.;
156  float mean2 = 0.;
157  for ( uint16_t ibin = 0; ibin < base.size(); ibin++ ) {
158  mean += base[ibin];
159  mean2 += base[ibin] * base[ibin];
160  }
161  if ( !base.empty() ) {
162  mean = mean / base.size();
163  mean2 = mean2 / base.size();
164  } else {
165  mean = 0.;
166  mean2 = 0.;
167  }
168  float baseline_rms = 0.;
169  if ( mean2 > mean*mean ) { baseline_rms = sqrt( mean2 - mean*mean ); }
170  else { baseline_rms = 0.; }
171  //LogTrace(mlCommissioning_) << " Spread in baseline samples: " << baseline_rms;
172 
173  // Find rising edges (derivative across two bins > range/2)
174  std::map<uint16_t,float> edges;
175  for ( uint16_t ibin = 1; ibin < nbins-1; ibin++ ) {
176  if ( bin_entries[ibin+1] &&
177  bin_entries[ibin-1] ) {
178  float derivative = bin_contents[ibin+1] - bin_contents[ibin-1];
179  if ( derivative > 5.*baseline_rms ) {
180  edges[ibin] = derivative;
181  //LogTrace(mlCommissioning_) << " Found edge #" << edges.size() << " at bin " << ibin
182  //<< " and with derivative " << derivative;
183  }
184  }
185  }
186 
187  // Iterate through "edges" std::map
188  bool found = false;
189  uint16_t deriv_bin = sistrip::invalid_;
190  float max_deriv = -1.*sistrip::invalid_;
191  std::map<uint16_t,float>::iterator iter = edges.begin();
192  while ( !found && iter != edges.end() ) {
193 
194  // Iterate through 50 subsequent samples
195  bool valid = true;
196  for ( uint16_t ii = 0; ii < 50; ii++ ) {
197  uint16_t bin = iter->first + ii;
198 
199  // Calc local derivative
200  float temp_deriv = 0;
201  if ( static_cast<uint32_t>(bin) < 1 ||
202  static_cast<uint32_t>(bin+1) >= nbins ) { continue; }
203  temp_deriv = bin_contents[bin+1] - bin_contents[bin-1];
204 
205  // Store max derivative
206  if ( temp_deriv > max_deriv ) {
207  max_deriv = temp_deriv;
208  deriv_bin = bin;
209  }
210 
211  // Check if samples following edge are all "high"
212  if ( ii > 10 && ii < 40 && bin_entries[bin] &&
213  bin_contents[bin] < baseline + 5*baseline_rms ) { valid = false; }
214 
215  }
216 
217  // Break from loop if tick mark found
218  if ( valid ) { found = true; }
219  else {
220  max_deriv = -1.*sistrip::invalid_;
221  deriv_bin = sistrip::invalid_;
222  edges.erase(iter);
223  }
224 
225  iter++;
226  }
227 
228  // Set monitorables (but not PLL coarse and fine here)
229  if ( !edges.empty() ) {
230  anal->time_ = deriv_bin;
231  anal->error_ = 0.;
232  anal->base_ = baseline;
233  anal->peak_ = tickmark;
234  anal->height_ = tickmark - baseline;
235  } else {
237  anal->base_ = baseline;
238  anal->peak_ = tickmark;
239  anal->height_ = tickmark - baseline;
240  }
241 
242 }
static const char unexpectedTask_[]
const uint32_t & fedKey() const
Derivative< X, A >::type derivative(const A &_)
Definition: Derivative.h:18
Utility class that holds histogram title.
static const char numberOfHistos_[]
static const char numberOfBins_[]
sistrip classes
static const char missingTickMark_[]
void extract(const std::vector< TH1 * > &)
static const char mlCommissioning_[]
T sqrt(T t)
Definition: SSEVec.h:18
uint32_t extractFedKey(const TH1 *const )
virtual void addErrorCode(const std::string &error)
T min(T a, T b)
Definition: MathUtil.h:58
base
Make Sure CMSSW is Setup ##.
Analysis for timing run using APV tick marks.
ii
Definition: cuy.py:588
bin
set the eta bin as selection string.
static const uint16_t invalid_
Definition: Constants.h:16
static const char smallDataRange_[]
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
Abstract base for derived classes that provide analysis of commissioning histograms.
CommissioningAnalysis *const anal() const
static const char nullPtr_[]