AdcChannelMetric.h
Go to the documentation of this file.
1 // AdcChannelMetric.h
2 
3 // David Adams
4 // April 2018
5 //
6 // Tool to evalute metrics for single ADC channel and make histograms
7 // of metric vs. channel for ranges of channels.
8 //
9 // If plots are made, graphs are shown instead of histograms.
10 // If a plot range is specified then values outside the range are
11 // shown at the nearest range limit.
12 //
13 // Subclasses may be used to extend the list of
14 // metrics (names and algorithms).
15 //
16 // Configuration:
17 // LogLevel - 0=silent, 1=init, 2=each event, >2=more
18 // Metric - Name of the plotted metric. This can be the name of any
19 // metadata field or any of the following single values:
20 // pedestal
21 // pedestalDiff - pedestal - (pedestal reference)
22 // pedestalRms - pedestal noise from the ADC channel data (e.g. filled by pedestal finder)
23 // fembID [0, 120) in protoDUNE
24 // apaFembID - FEMB number in the APA [0, 20)
25 // fembChannel - channel # in the FEMB [0, 128)
26 // or any of the following calculated values
27 // rawRms - RMS of (ADC - pedestal)
28 // samRms - RMS of sample
29 // samRmsNN - RMS of integration over NN contiguous samples (NN = 1, 2, ...)
30 // rawTailFraction - Fraction of ticks with |raw - ped| > 3*noise
31 // sigFrac: Fraction of samples that are signal.
32 // sigRms: RMS of the signal samples.
33 // nsgRms: RMS of the not-signal samples.
34 // nsgRmsNN: RMS of integration over NN contiguous not-signal samples.
35 // In the case a data view other than the top (DataView not blank), the single values
36 // are taken from the first entry. The calculated values include all entries.
37 // DataView - Name of the data view to use.
38 // PedestalReference - Name of the FloatArrayTool that holds the pedestal reference values.
39 // If the value is "first", the pedestal for the first event is used.
40 // MetricSummaryView - If not empty and a summary is requested, this specifies the view
41 // that is plotted, this view of the metric summary is plotted.
42 // The format is is VVV or VVV:EEE where VVV=position and EEE=error
43 // can be any of the following. Default is "mean:dmean".
44 // count - Number of values
45 // mean - Mean of the value
46 // dmean - error on the mean = rms/sqrt(count)
47 // rms - RMS of the values
48 // drms - error on the RMS
49 // sdev - RMS from the mean of the values
50 // min - Minimum value
51 // max - Maximum value
52 // center - 0.5*(min+max)
53 // range - max - min
54 // halfRange - 0.5*range
55 // ChannelRanges - Channel ranges for which metric channel histograms and plots are made.
56 // Ranges are obtained from the tool channelRanges.
57 // Special name "all" or "" plots all channels with label "All".
58 // If the list is empty, all are plotted.
59 // MetricMin - Formula for the minimum for the metric axis.
60 // MetricMax - Formula for the maximum for the metric axis.
61 // MetricBins - If nonzero, # channels vs metric is plotted with this binning instead of
62 // metric vs channel.
63 // ChannelLineModulus - Repeat spacing for vertical lines
64 // ChannelLinePattern - Pattern for dotted vertical lines
65 // ChannelLinePatternSolid - Pattern for solid horizontal lines
66 // HistName - Histogram name (should be unique within Root file)
67 // If the HistName name does not include "EVENT%", then only summary histogram
68 // and plot are created.
69 // If name is blank, no histogram is created.
70 // HistTitle - Histogram title
71 // MetricLabel - Histogram label for the metric axis
72 // PlotSizeX, PlotSizeY: Size in pixels of the plot file.
73 // Root default (700x500?) is used if either is zero.
74 // PlotFileName - Name for output plot file.
75 // If blank, no file is written.
76 // Existing file with the same name is replaced.
77 // PlotUsesStatus - If nonzero plot colors indicate channel status (good, bad noisy).
78 // RootFileName - Name for the output root file.
79 // If blank, histograms are not written out.
80 // Existing file with the same is updated.
81 // MetadataFlags - Vector of any of none of the following:
82 // write - Write value as ADC channel metadata.
83 // warnpresent - Warn if metadata field is present before write.
84 // read - read value from metadata (instead of calculation) if present
85 // warnabsent - Warn if requested metatdata field is not present
86 // For the title and file names, the following sustitutions are made:
87 // %RUN% --> run number
88 // %SUBRUN% --> subrun number
89 // %EVENT% --> event number
90 // %CHAN1% --> First channel number
91 // %CHAN2% --> Last channel number
92 // %CRNAME% --> Channel range name
93 // %CRLABEL% --> Channel range label
94 // Drawings may include vertical lines intended to show boundaries of APAs,
95 // FEMBs, wire planes, etc.
96 //
97 // Lines are draw at N*ChannelLineModulus + ChannelLinePattern[i] for any
98 // integer N and any value if i in range of the array which are within
99 // the drawn channel range.
100 // If ChannelLineModulus is zero, then lines are drawn for the channels in
101 // ChannelLinePattern and ChannelLinePaternSolid.
102 
103 #ifndef AdcChannelMetric_H
104 #define AdcChannelMetric_H
105 
107 #include "fhiclcpp/ParameterSet.h"
111 #include <vector>
112 
114 namespace lariov {
115  class ChannelStatusProvider;
116 }
117 
118 class FloatArrayTool;
119 class RunDataTool;
120 
122 
123 public:
124 
125  using Name = std::string;
126  using NameVector = std::vector<Name>;
127  using Index = unsigned int;
128  using IndexVector = std::vector<Index>;
129  using IndexRangeVector = std::vector<IndexRange>;
130 
132 
133  ~AdcChannelMetric() override;
134 
135  // Initialize this tool.
136  // We cache the status for each channel.
137  // Does nothing if already called unlesss force is true.
138  void initialize(bool force =false);
139 
140  // Tool interface.
141  DataMap view(const AdcChannelData& acd) const override;
142  DataMap viewMap(const AdcChannelDataMap& acds) const override;
143  DataMap update(AdcChannelData& acd) const override;
144  DataMap updateMap(AdcChannelDataMap& acds) const override;
145 
146  // Local method that directly returns the metric value and units.
147  // Subclasses may overrride this to add metrics. They are expected to
148  // call the fcl ctor of this class.
149  // The weight is used when averaging over events, e.g. the number
150  // of samples or ROIs contributing to the metric value.
151  virtual int
152  getMetric(const AdcChannelData& acd, Name met, double& metricValue,
153  Name& metricUnits, double& metricWeight) const;
154 
155 private:
156 
157  // Configuration data.
180 
181  // Derived data.
182  bool m_mdRead;
183  bool m_mdWrite;
187 
188  // Channel ranges.
190 
191  // Summary info.
196 
197  // Pedestal reference tool.
199 
200  // ADC string tool.
202 
203  // Channel status provider.
205 
206  // Make replacements in a name.
207  Name nameReplace(Name name, const AdcChannelData& acd, const IndexRange& ran) const;
208 
209  // Summary data for one channel.
210  // Calculates mean, RMS, their uncertainties and more from accumulated data.
211  // Note that the RMS may be more appropriate for RMS-like variables like noise
212  // as it averages squares instead of values.
213  //
214  // The value for each event is added with a weight that is used in the calculation
215  // of the mea, RMS and other values. Only the relative values of the weights
216  // affects these calculations.
217  //
218  // Uncertainties are evaluated by dividing the variance by sqrt(Neff) where Neff
219  // is the effective number independent measurements. Its value depends on
220  // the the weight flag:
221  // 0 - Neff = # events with weight > 0
222  // 1 - Neff = sum of weights
224  public:
225  Index weightFlag = 0;
226  Index eventCount = 0;
227  Index weightedEventCount = 0;
228  double weightSum;
229  double sum = 0.0;
230  double sumsq = 0.0;
231  double minval = 0.0;
232  double maxval = 0.0;
233  // Add an entry.
234  void add(double val, double weight) {
235  ++eventCount;
236  if ( weight <= 0.0 ) return;
237  ++weightedEventCount;
238  if ( weightSum == 0 || val < minval ) minval = val;
239  if ( weightSum == 0 || val > maxval ) maxval = val;
240  weightSum += weight;
241  sum += weight*val;
242  sumsq += weight*val*val;
243  }
244  double neff() const { return weightFlag ? weightSum : weightedEventCount; }
245  double mean() const { return weightSum ? sum/weightSum : 0.0; }
246  double dmean() const { return weightSum > 0.0 ? sdev()/sqrt(neff()) : 0.0; }
247  double meansq() const { return weightSum ? sumsq/weightSum : 0.0; }
248  double rms() const {
249  return sqrt(meansq());
250  }
251  double drms() const {
252  if ( weightSum <= 0.0 ) return 0.0;
253  double rmsVal = rms();
254  double rmsVar = meansq() + rmsVal*(rmsVal - 2.0*mean());
255  return rmsVar > 0.0 ? sqrt(rmsVar/neff()) : 0.0;
256  }
257  double sdev() const {
258  double valm = mean();
259  double arg = meansq() - valm*valm;
260  return arg > 0 ? sqrt(arg) : 0.0;
261  }
262  double center() const { return 0.5*(minval + maxval); }
263  double range() const { return maxval - minval; }
264  // Return if the provided string is a value name.
265  static bool isValueName(Name vnam) {
266  const std::set<Name> sumVals =
267  {"weightFlag", "eventCount", "weightedEventCount", "weightSum",
268  "mean", "rms", "sdev", "min", "max", "dmean", "drms",
269  "center", "range", "halfRange"};
270  return sumVals.find(vnam) != sumVals.end();
271  }
272  // Return a value by name.
273  double getValue(Name vnam) const {
274  if ( vnam == "weightFlag" ) return weightFlag;
275  if ( vnam == "weightedEventCount" ) return weightedEventCount;
276  if ( vnam == "eventCount" ) return eventCount;
277  if ( vnam == "weightSum" ) return weightSum;
278  if ( vnam == "mean" ) return mean();
279  if ( vnam == "rms" ) return rms();
280  if ( vnam == "sdev" ) return sdev();
281  if ( vnam == "min" ) return minval;
282  if ( vnam == "max" ) return maxval;
283  if ( vnam == "center" ) return center();
284  if ( vnam == "range" ) return range();
285  if ( vnam == "halfRange" ) return 0.5*range();
286  if ( vnam == "dmean" ) return dmean();
287  if ( vnam == "drms" ) return drms();
288  return 0.0;
289  }
290  };
291 
292  class Metric {
293  public:
294  double value =0.0;
295  double error =0.0;
296  void setValue(double a_value) { value = a_value; }
297  void setError(double a_error) { error = a_error; }
298  bool operator<(const Metric& rhs) const { return value < rhs.value; }
299  };
300  using MetricMap = std::map<Index, Metric>;
301  using MetricSummaryVector = std::vector<MetricSummary>;
302  using MetricSummaryMap = std::map<IndexRange, MetricSummaryVector>;
303 
304  // This subclass carries the state for this tool, i.e. data that can change
305  // after initialization.
306  class State {
307  public:
308  Index initCount = 0;
309  Index callCount = 0;
310  Index firstRun =0;
311  Index lastRun =0;
312  Index firstEvent =0;
313  Index lastEvent =0;
314  Index eventCount =0;
315  Index runCount =0;
316  MetricSummaryMap crsums; // Summary for each channel.
317  MetricMap pedRefs; // Reference pedestal for each channel;
318  bool update(Index run, Index event);
320  float metricMin =0;
321  float metricMax =100;
322  };
323 
324  // Shared pointer so we can make sure only one reference is out at a time.
325  using StatePtr = std::shared_ptr<State>;
327 
328  // Return the state.
329  State& getState() const { return *m_state; }
330 
331  // Tool interface plus map to hold results.
332  // The update methods can attach the metrics to the channel data.
333  // The view methods ignore those reults.
334  DataMap viewMapLocal(const AdcChannelDataMap& acds, MetricMap& mets) const;
335 
336  // Create the plot for one range.
337  DataMap viewMapForOneRange(const AdcChannelDataMap& acds, const IndexRange& ran,
338  MetricMap& mets) const;
339 
340  // Local method that fills the metric histogram and creates plots
341  // for the provided range and data.
342  void processMetricsForOneRange(const IndexRange& ran, const MetricMap& mets, TH1* ph,
343  Name ofname, Name ofrname, bool useErrors) const;
344 
345  // Local method to create the histogram.
346  TH1* createHisto(const AdcChannelData& acd, const IndexRange& ran) const;
347 
348  // Return the status for a channel.
349  // 0 - unknown (no status provider).
350  // 1 - got (not bad and not noisy)
351  // 2 - bad
352  // 3 - good
353  Index channelStatus(Index icha) const;
354 
355  // Evaluate the metric formulas and store results in the state.
356  void evaluateFormulas() const;
357 
358 };
359 
360 
361 #endif
static QCString name
Definition: declinfo.cpp:673
void setValue(double a_value)
ParFormula * m_MetricMax
const FloatArrayTool * m_pPedestalReference
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
std::map< IndexRange, MetricSummaryVector > MetricSummaryMap
unsigned int Index
std::string string
Definition: nybbler.cc:12
const AdcChannelStringTool * m_adcStringBuilder
error
Definition: include.cc:26
NameVector m_ChannelRanges
const lariov::ChannelStatusProvider * m_pChannelStatusProvider
std::vector< MetricSummary > MetricSummaryVector
std::vector< Name > NameVector
State & getState() const
void setError(double a_error)
weight
Definition: test.py:257
IndexRangeVector m_crs
IndexVector m_ChannelCounts
std::vector< Index > IndexVector
NameVector m_MetadataFlags
Class providing information about the quality of channels.
static constexpr double ps
Definition: Units.h:99
IndexVector m_ChannelLinePattern
Filters for channels, events, etc.
std::shared_ptr< State > StatePtr
def center(depos, point)
Definition: depos.py:117
double getValue(Name vnam) const
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
RunDataTool * m_prdtool
static bool isValueName(Name vnam)
std::vector< IndexRange > IndexRangeVector
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
bool operator<(const Metric &rhs) const
IndexVector m_ChannelLinePatternSolid
ParFormula * m_MetricMin
Event finding and building.
std::map< Index, Metric > MetricMap
void add(double val, double weight)