CMS 3D CMS Logo

OptoScanTask.cc
Go to the documentation of this file.
6 #include <algorithm>
7 #include <cmath>
8 
10 #include <iomanip>
11 
12 using namespace sistrip;
13 
14 // -----------------------------------------------------------------------------
15 //
17  : CommissioningTask(dqm, conn, "OptoScanTask"), opto_() {}
18 
19 // -----------------------------------------------------------------------------
20 //
22 
23 // -----------------------------------------------------------------------------
24 //
26  uint16_t nbins = 50;
27  uint16_t gains = 4;
28 
29  // Resize "histo sets"
30  opto_.resize(gains);
31  for (uint16_t igain = 0; igain < opto_.size(); igain++) {
32  opto_[igain].resize(3);
33  }
34 
35  for (uint16_t igain = 0; igain < opto_.size(); igain++) {
36  for (uint16_t ihisto = 0; ihisto < 3; ihisto++) {
37  // Extra info
38  std::stringstream extra_info;
39  extra_info << sistrip::extrainfo::gain_ << igain;
40  if (ihisto == 0 || ihisto == 1) {
41  extra_info << sistrip::extrainfo::digital_ << ihisto;
42  } else {
44  }
45 
46  // Title
50  fedKey(),
52  connection().lldChannel(),
53  extra_info.str())
54  .title();
55 
56  // Book histo
57  opto_[igain][ihisto].histo(dqm()->bookProfile(title,
58  title,
59  nbins,
60  0.5,
61  nbins * 1. + 0.5, // range is bias setting (1-50)
62  1024,
63  -0.5,
64  1023.5));
65 
66  opto_[igain][ihisto].vNumOfEntries_.resize(nbins, 0);
67  opto_[igain][ihisto].vSumOfContents_.resize(nbins, 0);
68  opto_[igain][ihisto].vSumOfSquares_.resize(nbins, 0);
69 
70  } // end loop on histos
71  } // end loop on gains
72 }
73 
74 // -----------------------------------------------------------------------------
75 //
77  //@@ if scope mode length is in trigger fed, then
78  //@@ can add check here on number of digis
79  if (digis.data.empty()) {
80  edm::LogWarning(mlDqmSource_) << "[OptoScanTask::" << __func__ << "]"
81  << " Unexpected number of digis! " << digis.data.size();
82  } else {
83  // Retrieve opt bias and gain setting from SiStripEventSummary
84  uint16_t gain = summary.lldGain();
85  uint16_t bias = summary.lldBias();
86 
87  if (gain >= opto_.size()) {
88  opto_.resize(gain);
89  for (uint16_t igain = 0; igain < opto_.size(); igain++) {
90  if (opto_[gain].size() != 3) {
91  opto_[gain].resize(3);
92  }
93  }
94  edm::LogWarning(mlDqmSource_) << "[OptoScanTask::" << __func__ << "]"
95  << " Unexpected gain value! " << gain;
96  }
97 
98  if (bias > 50) {
99  return;
100  } // only use bias settings 1-50
101 
102  // Find digital "0" and digital "1" levels from tick marks within scope mode data
103  std::vector<float> baseline;
104  std::pair<float, float> digital_range;
105  digital_range.first = sistrip::invalid_;
106  digital_range.second = sistrip::invalid_;
107  float baseline_rms = sistrip::invalid_;
108 
109  locateTicks(digis, digital_range, baseline, baseline_rms);
110 
111  uint16_t bin = bias - 1; // fill "bins" (0-49), not bias (1-50)
112 
113  // Digital "0"
114  if (digital_range.first < 1. * sistrip::valid_) {
115  updateHistoSet(opto_[gain][0], bin, digital_range.first);
116  }
117 
118  // Digital "1"
119  if (digital_range.second < 1. * sistrip::valid_) {
120  updateHistoSet(opto_[gain][1], bin, digital_range.second);
121  }
122 
123  // Baseline rms
124  if (baseline_rms < 1. * sistrip::valid_) {
125  updateHistoSet(opto_[gain][2], bin, baseline_rms);
126  }
127  }
128 }
129 
130 // -----------------------------------------------------------------------------
131 //
133  for (uint16_t igain = 0; igain < opto_.size(); igain++) {
134  for (uint16_t ihisto = 0; ihisto < opto_[igain].size(); ihisto++) {
135  updateHistoSet(opto_[igain][ihisto]);
136  }
137  }
138 }
139 
140 // -----------------------------------------------------------------------------
141 //
143  std::pair<float, float>& range,
144  std::vector<float>& baseline,
145  float& baseline_rms) {
146  // Copy ADC values and sort
147  std::vector<uint16_t> adc;
148  adc.reserve(digis.data.size());
149  for (uint16_t iadc = 0; iadc < digis.data.size(); iadc++) {
150  // only take the adc from the first APV (multiplexing alternates the digis)
151  // this was asked by Karl et al
152  if (iadc % 2 == 0) {
153  adc.push_back(digis.data[iadc].adc());
154  }
155  }
156  sort(adc.begin(), adc.end());
157 
158  // To make sure we have a tickmark, which comes every 70 bxs,
159  // fully contained in the scope 'frame' we are analyzing
160  // standard length is 280, sufficient to contain a full apv frame
161  // in this run there is no frame though, just baseline and tickmarks
162  if (adc.size() > 70) {
163  // Define tick mark top" level as "max" ADC values
164  range.second = adc.back();
165 
166  // Construct vector to hold "baseline samples" (exclude tick mark samples)
167  std::vector<uint16_t> truncated;
168  std::vector<uint16_t>::const_iterator ii = adc.begin();
169  // remove twice the expected number of tick samples, otherwise you bias the baseline mean and rms
170  std::vector<uint16_t>::const_iterator jj = adc.end() - 4 * ((adc.size() / 70) + 1);
171  truncated.resize(jj - ii);
172  std::copy(ii, jj, truncated.begin());
173  if (truncated.empty()) {
174  return;
175  }
176 
177  // Calc mean baseline level
178  float b_mean = 0.;
179  std::vector<uint16_t>::const_iterator iii = truncated.begin();
180  std::vector<uint16_t>::const_iterator jjj = truncated.end();
181  for (; iii != jjj; ++iii) {
182  b_mean += *iii;
183  }
184  b_mean /= (1. * truncated.size());
185  range.first = b_mean;
186 
187  // Calc baseline noise
188  float b_rms = 0.;
189  std::vector<uint16_t>::const_iterator iiii = truncated.begin();
190  std::vector<uint16_t>::const_iterator jjjj = truncated.end();
191  for (; iiii != jjjj; ++iiii) {
192  b_rms += fabs(*iiii - b_mean);
193  }
194  // Set baseline "noise" (requires any possible APV frames are filtered from the data!)
195  baseline_rms = sqrt(b_rms / (1. * truncated.size()));
196 
197  } else {
198  edm::LogWarning(mlDqmSource_) << "[OptoScanTask::" << __func__ << "]"
199  << " Insufficient ADC values: " << adc.size();
200  }
201 }
size
Write out results.
Utility class that holds histogram title.
~OptoScanTask() override
Definition: OptoScanTask.cc:21
static const char mlDqmSource_[]
static const uint16_t valid_
Definition: Constants.h:17
sistrip classes
void updateHistoSet(HistoSet &, const uint32_t &bin, const float &value)
static const char baselineRms_[]
std::vector< std::vector< HistoSet > > opto_
Definition: OptoScanTask.h:24
Class containning control, module, detector and connection information, at the level of a FED channel...
T sqrt(T t)
Definition: SSEVec.h:19
const uint32_t & fedKey() const
void book() override
Definition: OptoScanTask.cc:25
static const char digital_[]
void fill(const SiStripEventSummary &summary, const edm::DetSet< SiStripRawDigi > &digis) override
Definition: OptoScanTask.cc:76
DQMStore *const dqm() const
ii
Definition: cuy.py:589
constexpr float gains[NGAINS]
Definition: EcalConstants.h:11
OptoScanTask(DQMStore *dqm, const FedChannelConnection &conn)
Definition: OptoScanTask.cc:16
static const uint16_t invalid_
Definition: Constants.h:16
collection_type data
Definition: DetSet.h:80
conn
Definition: getInfo.py:9
static const char gain_[]
const FedChannelConnection & connection() const
Log< level::Warning, false > LogWarning
Definition: DQMStore.h:18
uint16_t *__restrict__ uint16_t const *__restrict__ adc
void locateTicks(const edm::DetSet< SiStripRawDigi > &scope_mode_data, std::pair< float, float > &digital_range, std::vector< float > &baseline, float &baseline_rms)
void update() override