CMS 3D CMS Logo

ApvTimingAlgorithm.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_(nullptr,"")
19 {;}
20 
21 // ----------------------------------------------------------------------------
22 //
23 void ApvTimingAlgorithm::extract( const std::vector<TH1*>& histos ) {
24 
25  if ( !anal() ) {
27  << "[ApvTimingAlgorithm::" << __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::APV_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  << "[ApvTimingAlgorithm::" << __func__ << "]"
69  << " NULL pointer to base Analysis object!";
70  return;
71  }
72 
74  ApvTimingAnalysis* anal = dynamic_cast<ApvTimingAnalysis*>( tmp );
75  if ( !anal ) {
77  << "[ApvTimingAlgorithm::" << __func__ << "]"
78  << " NULL pointer to derived Analysis object!";
79  return;
80  }
81 
82  if ( !histo_.first ) {
84  return;
85  }
86 
87  TProfile* histo = dynamic_cast<TProfile*>(histo_.first);
88  if ( !histo ) {
90  return;
91  }
92 
93  // Transfer histogram contents/errors/stats to containers
94  uint16_t non_zero = 0;
95  float max = -1. * sistrip::invalid_;
96  float min = 1. * sistrip::invalid_;
97  uint16_t nbins = static_cast<uint16_t>( histo->GetNbinsX() );
98  std::vector<float> bin_contents;
99  std::vector<float> bin_errors;
100  std::vector<float> bin_entries;
101  bin_contents.reserve( nbins );
102  bin_errors.reserve( nbins );
103  bin_entries.reserve( nbins );
104  for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
105  bin_contents.push_back( histo->GetBinContent(ibin+1) );
106  bin_errors.push_back( histo->GetBinError(ibin+1) );
107  bin_entries.push_back( histo->GetBinEntries(ibin+1) );
108  if ( bin_entries[ibin] ) {
109  if ( bin_contents[ibin] > max ) { max = bin_contents[ibin]; }
110  if ( bin_contents[ibin] < min ) { min = bin_contents[ibin]; }
111  non_zero++;
112  }
113  }
114  if ( bin_contents.size() < 100 ) {
116  return;
117  }
118 
119  // Calculate range (max-min) and threshold level (range/2)
120  float threshold = min + ( max - min ) / 2.;
121  anal->base_ = min;
122  anal->peak_ = max;
123  anal->height_ = max - min;
126  return;
127  }
128 
129  // Associate samples with either "tick mark" or "baseline"
130  std::vector<float> tick;
131  std::vector<float> base;
132  for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
133  if ( bin_entries[ibin] ) {
134  if ( bin_contents[ibin] < threshold ) {
135  base.push_back( bin_contents[ibin] );
136  } else {
137  tick.push_back( bin_contents[ibin] );
138  }
139  }
140  }
141 
142  // Find median level of tick mark and baseline
143  float tickmark = 0.;
144  float baseline = 0.;
145  sort( tick.begin(), tick.end() );
146  sort( base.begin(), base.end() );
147  if ( !tick.empty() ) { tickmark = tick[ tick.size()%2 ? tick.size()/2 : tick.size()/2 ]; }
148  if ( !base.empty() ) { baseline = base[ base.size()%2 ? base.size()/2 : base.size()/2 ]; }
149  anal->base_ = baseline;
150  anal->peak_ = tickmark;
151  anal->height_ = tickmark - baseline;
152  if ( tickmark - baseline < ApvTimingAnalysis::tickMarkHeightThreshold_ ) {
154  return;
155  }
156 
157  // Find rms spread in "baseline" samples
158  float mean = 0.;
159  float mean2 = 0.;
160  for ( uint16_t ibin = 0; ibin < base.size(); ibin++ ) {
161  mean += base[ibin];
162  mean2 += base[ibin] * base[ibin];
163  }
164  if ( !base.empty() ) {
165  mean = mean / base.size();
166  mean2 = mean2 / base.size();
167  } else {
168  mean = 0.;
169  mean2 = 0.;
170  }
171  float baseline_rms = sqrt( fabs( mean2 - mean*mean ) );
172 
173 
174  // Find rising edges (derivative across two bins > threshold)
175  std::map<uint16_t,float> edges;
176  for ( uint16_t ibin = 1; ibin < nbins-1; ibin++ ) {
177  if ( bin_entries[ibin+1] &&
178  bin_entries[ibin-1] ) {
179  float derivative = bin_contents[ibin+1] - bin_contents[ibin-1];
180  if ( derivative > 3.*baseline_rms ) {
181  edges[ibin] = derivative;
182  }
183  }
184  }
185  if ( edges.empty() ) {
187  return;
188  }
189 
190 
191  // Iterate through "edges" map
192  uint16_t max_derivative_bin = sistrip::invalid_;
193  float max_derivative = -1.*sistrip::invalid_;
194 
195  bool found = false;
196  std::map<uint16_t,float>::iterator iter = edges.begin();
197  while ( !found && iter != edges.end() ) {
198 
199  // Iterate through 50 subsequent samples
200  bool valid = true;
201  for ( uint16_t ii = 0; ii < 50; ii++ ) {
202  uint16_t bin = iter->first + ii;
203 
204  // Calc local derivative
205  float temp = 0.;
206  if ( static_cast<uint32_t>(bin) < 1 ||
207  static_cast<uint32_t>(bin+1) >= nbins ) {
208  valid = false; //@@ require complete plateau is found within histo
210  continue;
211  }
212  temp = bin_contents[bin+1] - bin_contents[bin-1];
213 
214  // Store max derivative
215  if ( temp > max_derivative ) {
216  max_derivative = temp;
217  max_derivative_bin = bin;
218  }
219 
220  // Check if samples following edge are all "high"
221  if ( ii > 10 && ii < 40 && bin_entries[bin] &&
222  bin_contents[bin] < baseline + 5.*baseline_rms ) {
223  valid = false;
224  }
225 
226  }
227 
228  // Break from loop if tick mark found
229  if ( valid ) { found = true; }
230 
231  /*
232  else {
233  max_derivative = -1.*sistrip::invalid_;
234  max_derivative_bin = sistrip::invalid_;
235  //edges.erase(iter);
236  anal->addErrorCode(sistrip::rejectedCandidate_);
237  }
238  */
239 
240  iter++; // next candidate
241 
242  }
243 
244 
245 
246  if ( !found ) { //Try tick mark recovery
247 
248  max_derivative_bin = sistrip::invalid_;
249  max_derivative = -1.*sistrip::invalid_;
250 
251  // Find rising edges_r (derivative_r across five bins > threshold)
252  std::map<uint16_t,float> edges_r;
253  for ( uint16_t ibin_r = 1; ibin_r < nbins-1; ibin_r++ ) {
254  if (bin_entries[ibin_r+4] &&
255  bin_entries[ibin_r+3] &&
256  bin_entries[ibin_r+2] &&
257  bin_entries[ibin_r+1] &&
258  bin_entries[ibin_r] &&
259  bin_entries[ibin_r-1]) {
260  float derivative_r = bin_contents[ibin_r+1] - bin_contents[ibin_r-1];
261  float derivative_r1 = bin_contents[ibin_r+1] - bin_contents[ibin_r];
262  float derivative_r2 = bin_contents[ibin_r+2] - bin_contents[ibin_r+1];
263  float derivative_r3 = bin_contents[ibin_r+3] - bin_contents[ibin_r+2];
264 
265  if ( derivative_r > 3.*baseline_rms &&
266  derivative_r1 > 1.*baseline_rms &&
267  derivative_r2 > 1.*baseline_rms &&
268  derivative_r3 > 1.*baseline_rms ) {
269  edges_r[ibin_r] = derivative_r;
270  }
271  }
272  }
273  if ( edges_r.empty() ) {
275  return;
276  }
277 
278  // Iterate through "edges_r" map
279  float max_derivative_r = -1.*sistrip::invalid_;
280 
281  bool found_r = false;
282  std::map<uint16_t,float>::iterator iter_r = edges_r.begin();
283  while ( !found_r && iter_r != edges_r.end() ) {
284 
285  // Iterate through 50 subsequent samples
286  bool valid_r = true;
287  int lowpointcount_r = 0;
288  const int lowpointallow_r = 25; //Number of points allowed to fall below threshhold w/o invalidating tick mark
289  for ( uint16_t ii_r = 0; ii_r < 50; ii_r++ ) {
290  uint16_t bin_r = iter_r->first + ii_r;
291 
292  // Calc local derivative_r
293  float temp_r = 0.;
294  if ( static_cast<uint32_t>(bin_r) < 1 ||
295  static_cast<uint32_t>(bin_r+1) >= nbins ) {
296  valid_r = false; //@@ require complete plateau is found_r within histo
298  continue;
299  }
300  temp_r = bin_contents[bin_r+1] - bin_contents[bin_r-1];
301 
302  // Store max derivative_r
303  if ( temp_r > max_derivative_r && ii_r < 10) {
304  max_derivative_r = temp_r;
305  max_derivative = temp_r;
306  max_derivative_bin = bin_r;
307  }
308 
309 
310  // Check if majority of samples following edge are all "high"
311  if ( ii_r > 10 && ii_r < 40 && bin_entries[bin_r] &&
312  bin_contents[bin_r] < baseline + 5.*baseline_rms ) {
313  lowpointcount_r++;
314  if(lowpointcount_r > lowpointallow_r){
315  valid_r = false;
316  }
317  }
318  }
319 
320  // Break from loop if recovery tick mark found
321  if ( valid_r ) {
322  found_r = true;
323  found = true;
325  }
326  else {
327  max_derivative_r = -1.*sistrip::invalid_;
328  max_derivative = -1.*sistrip::invalid_;
329  max_derivative_bin = sistrip::invalid_;
330  //edges_r.erase(iter_r);
332  }
333 
334  iter_r++; // next candidate
335 
336  }
337  } //End tick mark recovery
338 
339  // Record time monitorable and check tick mark height
340  if ( max_derivative_bin <= sistrip::valid_ ) {
341  anal->time_ = max_derivative_bin * 25. / 24.;
344  }
345  } else {
347  }
348 
349 }
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 float tickMarkHeightThreshold_
static const uint16_t valid_
Definition: Constants.h:17
#define nullptr
static const char incompletePlateau_[]
static const char numberOfBins_[]
sistrip classes
static const char missingTickMark_[]
static const char rejectedCandidate_[]
static const char mlCommissioning_[]
static const char tickMarkRecovered_[]
void addErrorCode(const std::string &error) override
T sqrt(T t)
Definition: SSEVec.h:18
uint32_t extractFedKey(const TH1 *const )
static const char tickMarkBelowThresh_[]
virtual void addErrorCode(const std::string &error)
T min(T a, T b)
Definition: MathUtil.h:58
base
Make Sure CMSSW is Setup ##.
const Histo & histo() const
ii
Definition: cuy.py:589
bin
set the eta bin as selection string.
static const char smallTickMarkHeight_[]
static const uint16_t invalid_
Definition: Constants.h:16
static const char noRisingEdges_[]
static const char smallDataRange_[]
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
void analyse() override
Abstract base for derived classes that provide analysis of commissioning histograms.
Analysis for timing run using APV tick marks.
void extract(const std::vector< TH1 * > &) override
CommissioningAnalysis *const anal() const
static const char nullPtr_[]