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), histo_(nullptr, "") {
18  ;
19 }
20 
21 // ----------------------------------------------------------------------------
22 //
23 void FedTimingAlgorithm::extract(const std::vector<TH1*>& histos) {
24  if (!anal()) {
25  edm::LogWarning(mlCommissioning_) << "[FedTimingAlgorithm::" << __func__ << "]"
26  << " NULL pointer to Analysis object!";
27  return;
28  }
29 
30  // Check number of histograms
31  if (histos.size() != 1) {
33  }
34 
35  // Extract FED key from histo title
36  if (!histos.empty()) {
37  anal()->fedKey(extractFedKey(histos.front()));
38  }
39 
40  // Extract histograms
41  std::vector<TH1*>::const_iterator ihis = histos.begin();
42  for (; ihis != histos.end(); ihis++) {
43  // Check for NULL pointer
44  if (!(*ihis)) {
45  continue;
46  }
47 
48  // Check name
49  SiStripHistoTitle title((*ihis)->GetName());
50  if (title.runType() != sistrip::FED_TIMING) {
52  continue;
53  }
54 
55  // Extract timing histo
56  histo_.first = *ihis;
57  histo_.second = (*ihis)->GetName();
58  }
59 }
60 
61 // ----------------------------------------------------------------------------
62 //
64  if (!anal()) {
65  edm::LogWarning(mlCommissioning_) << "[FedTimingAlgorithm::" << __func__ << "]"
66  << " NULL pointer to base Analysis object!";
67  return;
68  }
69 
71  FedTimingAnalysis* anal = dynamic_cast<FedTimingAnalysis*>(tmp);
72  if (!anal) {
73  edm::LogWarning(mlCommissioning_) << "[FedTimingAlgorithm::" << __func__ << "]"
74  << " NULL pointer to derived Analysis object!";
75  return;
76  }
77 
78  if (!histo_.first) {
80  return;
81  }
82 
83  // Transfer histogram contents/errors/stats to containers
84  uint16_t non_zero = 0;
85  float max = -1.e9;
86  float min = 1.e9;
87  uint16_t nbins = static_cast<uint16_t>(histo_.first->GetNbinsX());
88  std::vector<float> bin_contents;
89  std::vector<float> bin_errors;
90  std::vector<float> bin_entries;
91  bin_contents.reserve(nbins);
92  bin_errors.reserve(nbins);
93  bin_entries.reserve(nbins);
94  for (uint16_t ibin = 0; ibin < nbins; ibin++) {
95  bin_contents.push_back(histo_.first->GetBinContent(ibin + 1));
96  bin_errors.push_back(histo_.first->GetBinError(ibin + 1));
97  //bin_entries.push_back( histo_.first->GetBinEntries(ibin+1) );
98  if (bin_entries[ibin]) {
99  if (bin_contents[ibin] > max) {
100  max = bin_contents[ibin];
101  }
102  if (bin_contents[ibin] < min) {
103  min = bin_contents[ibin];
104  }
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()) {
146  tickmark = tick[tick.size() % 2 ? tick.size() / 2 : tick.size() / 2];
147  }
148  if (!base.empty()) {
149  baseline = base[base.size() % 2 ? base.size() / 2 : base.size() / 2];
150  }
151  //LogTrace(mlCommissioning_) << " Tick mark level: " << tickmark << " Baseline level: " << baseline
152  //<< " Range: " << (tickmark-baseline);
153  if ((tickmark - baseline) < 50.) {
155  return;
156  }
157 
158  // Find rms spread in "baseline" samples
159  float mean = 0.;
160  float mean2 = 0.;
161  for (uint16_t ibin = 0; ibin < base.size(); ibin++) {
162  mean += base[ibin];
163  mean2 += base[ibin] * base[ibin];
164  }
165  if (!base.empty()) {
166  mean = mean / base.size();
167  mean2 = mean2 / base.size();
168  } else {
169  mean = 0.;
170  mean2 = 0.;
171  }
172  float baseline_rms = 0.;
173  if (mean2 > mean * mean) {
174  baseline_rms = sqrt(mean2 - mean * mean);
175  } else {
176  baseline_rms = 0.;
177  }
178  //LogTrace(mlCommissioning_) << " Spread in baseline samples: " << baseline_rms;
179 
180  // Find rising edges (derivative across two bins > range/2)
181  std::map<uint16_t, float> edges;
182  for (uint16_t ibin = 1; ibin < nbins - 1; ibin++) {
183  if (bin_entries[ibin + 1] && bin_entries[ibin - 1]) {
184  float derivative = bin_contents[ibin + 1] - bin_contents[ibin - 1];
185  if (derivative > 5. * baseline_rms) {
186  edges[ibin] = derivative;
187  //LogTrace(mlCommissioning_) << " Found edge #" << edges.size() << " at bin " << ibin
188  //<< " and with derivative " << derivative;
189  }
190  }
191  }
192 
193  // Iterate through "edges" std::map
194  bool found = false;
195  uint16_t deriv_bin = sistrip::invalid_;
196  float max_deriv = -1. * sistrip::invalid_;
197  std::map<uint16_t, float>::iterator iter = edges.begin();
198  while (!found && iter != edges.end()) {
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_deriv = 0;
206  if (static_cast<uint32_t>(bin) < 1 || static_cast<uint32_t>(bin + 1) >= nbins) {
207  continue;
208  }
209  temp_deriv = bin_contents[bin + 1] - bin_contents[bin - 1];
210 
211  // Store max derivative
212  if (temp_deriv > max_deriv) {
213  max_deriv = temp_deriv;
214  deriv_bin = bin;
215  }
216 
217  // Check if samples following edge are all "high"
218  if (ii > 10 && ii < 40 && bin_entries[bin] && bin_contents[bin] < baseline + 5 * baseline_rms) {
219  valid = false;
220  }
221  }
222 
223  // Break from loop if tick mark found
224  if (valid) {
225  found = true;
226  } else {
227  max_deriv = -1. * sistrip::invalid_;
228  deriv_bin = sistrip::invalid_;
229  edges.erase(iter);
230  }
231 
232  iter++;
233  }
234 
235  // Set monitorables (but not PLL coarse and fine here)
236  if (!edges.empty()) {
237  anal->time_ = deriv_bin;
238  anal->error_ = 0.;
239  anal->base_ = baseline;
240  anal->peak_ = tickmark;
241  anal->height_ = tickmark - baseline;
242  } else {
244  anal->base_ = baseline;
245  anal->peak_ = tickmark;
246  anal->height_ = tickmark - baseline;
247  }
248 }
CommissioningAnalysis *const anal() const
static const char unexpectedTask_[]
Derivative< X, A >::type derivative(const A &_)
Definition: Derivative.h:18
Utility class that holds histogram title.
static const char numberOfHistos_[]
base
Main Program
Definition: newFWLiteAna.py:92
static const char numberOfBins_[]
void analyse() override
sistrip classes
uint32_t extractFedKey(const TH1 *const)
static const char missingTickMark_[]
static const char mlCommissioning_[]
T sqrt(T t)
Definition: SSEVec.h:19
virtual void addErrorCode(const std::string &error)
Analysis for timing run using APV tick marks.
const uint32_t & fedKey() const
ii
Definition: cuy.py:589
void extract(const std::vector< TH1 *> &) override
static const uint16_t invalid_
Definition: Constants.h:16
static const char smallDataRange_[]
histos
Definition: combine.py:4
Abstract base for derived classes that provide analysis of commissioning histograms.
Log< level::Warning, false > LogWarning
tmp
align.sh
Definition: createJobs.py:716
static const char nullPtr_[]