AdcChannelMetric_tool.cc
Go to the documentation of this file.
1 // AdcChannelMetric_tool.cc
2 
3 #include "AdcChannelMetric.h"
4 #include <iostream>
5 #include <sstream>
6 #include <iomanip>
7 #include <set>
20 #include "TH1F.h"
21 #include "TGraph.h"
22 #include "TGraphErrors.h"
23 #include "TCanvas.h"
24 #include "TColor.h"
25 #include "TStyle.h"
26 #include "TDirectory.h"
27 #include "TFile.h"
28 
29 using std::string;
30 using std::cout;
31 using std::setw;
32 using std::cin;
33 using std::endl;
34 using std::vector;
35 using std::istringstream;
37 using TGraphVector = std::vector<TGraph*>;
38 using TGraphErrorsVector = std::vector<TGraphErrors*>;
39 
40 //**********************************************************************
41 // local definitiions.
42 //**********************************************************************
43 
44 //**********************************************************************
45 // Sublass methods.
46 //**********************************************************************
47 
48 bool AdcChannelMetric::AdcChannelMetric::State::update(Index run, Index event) {
49  bool runHasChanged = false;
50  if ( callCount == 0 ) {
51  firstRun = run;
52  firstEvent = event;
53  runCount = 1;
54  eventCount = 1;
55  runHasChanged = true;
56  } else {
57  if ( run != lastRun ) {
58  ++runCount;
59  runHasChanged = true;
60  }
61  if ( event != lastEvent ) ++eventCount;
62  }
63  ++callCount;
64  lastEvent = event;
65  lastRun = run;
66  return runHasChanged;
67 }
68 
69 //**********************************************************************
70 // Class methods.
71 //**********************************************************************
72 
74 : m_LogLevel(ps.get<int>("LogLevel")),
75  m_Metric(ps.get<Name>("Metric")),
76  m_DataView(ps.get<Name>("DataView")),
77  m_PedestalReference(ps.get<Name>("PedestalReference")),
78  m_MetricSummaryView(ps.get<Name>("MetricSummaryView")),
79  m_ChannelRanges(ps.get<NameVector>("ChannelRanges")),
80  m_MetricMin(new RootParFormula("MetricMin", ps.get<Name>("MetricMin"))),
81  m_MetricMax(new RootParFormula("MetricMax", ps.get<Name>("MetricMax"))),
82  m_MetricBins(ps.get<Index>("MetricBins")),
83  m_ChannelLineModulus(ps.get<Index>("ChannelLineModulus")),
84  m_ChannelLinePattern(ps.get<IndexVector>("ChannelLinePattern")),
85  m_ChannelLinePatternSolid(ps.get<IndexVector>("ChannelLinePatternSolid")),
86  m_HistName(ps.get<Name>("HistName")),
87  m_HistTitle(ps.get<Name>("HistTitle")),
88  m_MetricLabel(ps.get<Name>("MetricLabel")),
89  m_PlotSizeX(ps.get<Index>("PlotSizeX")),
90  m_PlotSizeY(ps.get<Index>("PlotSizeY")),
91  m_PlotFileName(ps.get<Name>("PlotFileName")),
92  m_PlotUsesStatus(ps.get<int>("PlotUsesStatus")),
93  m_RootFileName(ps.get<Name>("RootFileName")),
94  m_MetadataFlags(ps.get<NameVector>("MetadataFlags")),
95  m_mdRead(false), m_mdWrite(false), m_mdWarnAbsent(false), m_mdWarnPresent(false),
96  m_prdtool(nullptr),
97  m_doSummary(false),
98  m_doSummaryError(false),
99  m_pPedestalReference(nullptr),
100  m_pChannelStatusProvider(nullptr),
101  m_state(new State) {
102  const string myname = "AdcChannelMetric::ctor: ";
103  string stringBuilder = "adcStringBuilder";
105  // Process metadata flags.
106  for ( string mflag : m_MetadataFlags ) {
107  if ( mflag == "read" ) m_mdRead = true;
108  else if ( mflag == "write" ) m_mdWrite = true;
109  else if ( mflag == "warnabsent" ) m_mdWarnAbsent = true;
110  else if ( mflag == "warnpresent" ) m_mdWarnPresent = true;
111  else {
112  cout << myname << "WARNING: Ignoring invalid metadata flag: " << mflag << endl;
113  }
114  }
115  // Fetch the channel ranges.
116  bool toolNotFound = false;
117  const IndexRangeTool* pcrt = nullptr;
118  for ( Name crn : m_ChannelRanges.size() ? m_ChannelRanges : NameVector(1, "") ) {
119  if ( crn.size() == 0 ) {
120  m_crs.emplace_back("all", 0, 0, "All");
121  } else {
122  if ( pcrt == nullptr && !toolNotFound ) {
123  pcrt = ptm->getShared<IndexRangeTool>("channelRanges");
124  if ( pcrt == nullptr ) {
125  cout << myname << "ERROR: IndexRangeTool not found: channelRanges" << endl;
126  }
127  }
128  if ( pcrt != nullptr ) {
129  IndexRange ran = pcrt->get(crn);
130  if ( ran.isValid() ) {
131  m_crs.push_back(ran);
132  } else {
133  cout << myname << "WARNING: Channel range not found: " << crn << endl;
134  }
135  }
136  }
137  }
138  // Initialize the state.
139  for ( const IndexRange& cr : m_crs ) getState().crsums[cr].resize(cr.size());
140  // Fetch the pedestalreference tool.
141  if ( m_PedestalReference.size() ) {
143  if ( m_pPedestalReference == nullptr ) {
144  cout << "WARNING: Pedestal reference tool not found: " << m_PedestalReference << endl;
145  } else {
146  Index nref = m_pPedestalReference->size();
148  cout << myname << "Pedestal reference array has " << nref << " value"
149  << ( nref == 1 ? "" : "s" );
150  if ( nref ) cout << " starting at channel " << off;
151  cout << "." << endl;
152  }
153  }
154  // Fetch the naming tool.
155  m_adcStringBuilder = ptm->getShared<AdcChannelStringTool>(stringBuilder);
156  if ( m_adcStringBuilder == nullptr ) {
157  cout << myname << "WARNING: AdcChannelStringTool not found: " << stringBuilder << endl;
158  }
159  // Fetch the run data tool.
160  if ( m_MetricMin->npar() || m_MetricMax->npar() ) {
161  string stnam = "runDataTool";
162  m_prdtool = ptm->getShared<RunDataTool>(stnam);
163  if ( m_prdtool == nullptr ) {
164  cout << myname << "ERROR: RunDataTool " << stnam
165  << " not found. Metric limits will not be evaluated." << endl;
166  } else {
167  cout << myname << "RunDataTool retrieved." << endl;
168  }
169  }
170  // Set summary fields.
171  m_doSummary = m_HistName.find("EVENT%") == string::npos;
172  if ( m_doSummary ) {
173  const std::set<Name> sumVals = {"count", "mean", "rms", "drms"};
174  if ( m_MetricSummaryView.size() == 0 ) {
175  m_MetricSummaryView = "mean:dmean";
176  cout << myname << "WARNING: Missing metric summary view set to \"" << m_MetricSummaryView
177  << "\"." << endl;
178  }
179  Name vnam = m_MetricSummaryView;
180  Name enam;
181  Name::size_type ipos = vnam.find(":");
182  if ( ipos != Name::npos ) {
183  enam = vnam.substr(ipos+1);
184  vnam = vnam.substr(0, ipos);
185  }
186  if ( ! MetricSummary::isValueName(vnam) ) {
187  cout << myname << "WARNING: Invalid value for metric summary view reset from " << vnam
188  << " to mean." << endl;
189  vnam = "mean";
190  }
191  if ( enam.size() ) {
192  if ( ! MetricSummary::isValueName(enam) ) {
193  cout << myname << "WARNING: Ignoring invalid error for metric summary view: " << enam << endl;
194  } else {
195  m_doSummaryError = true;
196  }
197  }
198  m_summaryValue = vnam;
199  m_summaryError = enam;
200  }
201  // Fetch the channel status service.
202  if ( m_PlotUsesStatus ) {
203  if ( m_LogLevel >= 1 ) cout << myname << "Fetching channel status service." << endl;
205  if ( m_pChannelStatusProvider == nullptr ) {
206  cout << myname << "WARNING: Channel status provider not found." << endl;
207  m_PlotUsesStatus = false;
208  }
209  }
210  // Display the configuration.
211  if ( m_LogLevel ) {
212  cout << myname << "Configuration: " << endl;
213  cout << myname << " LogLevel: " << m_LogLevel << endl;
214  cout << myname << " Metric: " << m_Metric << endl;
215  cout << myname << " DataView: " << m_DataView << endl;
216  cout << myname << " PedestalReference: " << m_PedestalReference << endl;
217  cout << myname << " MetricSummaryView: " << m_MetricSummaryView;
218  if ( m_summaryValue.size() ) {
219  cout << " (" << m_summaryValue;
220  if ( m_summaryError.size() ) cout << " +/- " << m_summaryError;
221  cout << ")";
222  }
223  cout << endl;
224  cout << myname << " ChannelRanges: [";
225  bool first = true;
226  for ( const IndexRange& ran : m_crs ) {
227  if ( ! first ) cout << ", ";
228  else first = false;
229  cout << ran.name;
230  }
231  cout << "]" << endl;
232  cout << myname << " MetricMin: " << m_MetricMin->formulaString() << endl;
233  cout << myname << " MetricMax: " << m_MetricMax->formulaString() << endl;
234  cout << myname << " MetricBins: " << m_MetricBins << endl;
235  cout << myname << " ChannelLineModulus: " << m_ChannelLineModulus << endl;
236  cout << myname << " ChannelLinePattern: {";
237  first = true;
238  for ( Index icha : m_ChannelLinePattern ) {
239  if ( ! first ) cout << ", ";
240  first = false;
241  cout << icha;
242  }
243  cout << "}" << endl;
244  cout << myname << " ChannelLinePatternSolid: {";
245  first = true;
246  for ( Index icha : m_ChannelLinePatternSolid ) {
247  if ( ! first ) cout << ", ";
248  first = false;
249  cout << icha;
250  }
251  cout << "}" << endl;
252  cout << myname << " ChannelCounts: {";
253  first = true;
254  for ( Index icha : m_ChannelCounts ) {
255  if ( ! first ) cout << ", ";
256  first = false;
257  cout << icha;
258  }
259  cout << "}" << endl;
260  cout << myname << " PlotSizeX: " << m_PlotSizeX << endl;
261  cout << myname << " PlotSizeY: " << m_PlotSizeY << endl;
262  cout << myname << " HistName: " << m_HistName << endl;
263  cout << myname << " HistTitle: " << m_HistTitle << endl;
264  cout << myname << " MetricLabel: " << m_MetricLabel << endl;
265  cout << myname << " PlotFileName: " << m_PlotFileName << endl;
266  cout << myname << " PlotUsesStatus: " << m_PlotUsesStatus << endl;
267  cout << myname << " RootFileName: " << m_RootFileName << endl;
268  cout << myname << " MetadataFlags: [";
269  first = true;
270  for ( string mflag : m_MetadataFlags ) {
271  if ( ! first ) cout << ", ";
272  first = false;
273  cout << mflag;
274  }
275  cout << "]" << endl;
276  }
277  // We might have to move this to getMetric.
278  initialize();
279 }
280 
281 //**********************************************************************
282 
284  const string myname = "AdcChannelMetric::dtor: ";
285  Index ncha = 0;
286  Index nchaData = 0;
287  Index nchaDataMax = 0;
288  Index countMax = 0;
289  Index weightSumMax = 0.0;
290  for ( const MetricSummaryMap::value_type& imsm : getState().crsums ) {
291  IndexRange cr = imsm.first;
292  const MetricSummaryVector& msums = imsm.second;
293  if ( m_LogLevel >= 3 ) {
294  cout << myname << "Channel range " << cr.name << endl;
295  }
296  for ( Index kcha=0; kcha<cr.size(); ++kcha ) {
297  const MetricSummary& ms = msums[kcha];
298  ++ncha;
299  if ( ms.eventCount ) {
300  ++nchaData;
301  if ( ms.eventCount > countMax ) {
302  countMax = ms.eventCount;
303  nchaDataMax = 1;
304  } else if ( ms.eventCount == countMax ) {
305  ++nchaDataMax;
306  }
307  if ( ms.weightSum > weightSumMax ) {
308  weightSumMax = ms.weightSum;
309  }
310  }
311  }
312  if ( m_doSummary ) {
313  MetricMap mets;
314  const MetricSummaryVector& msums = getState().crsums[cr];
315  for ( Index kcha=0; kcha<cr.size(); ++kcha ) {
316  Index icha = cr.first() + kcha;
317  const MetricSummary& msum = msums[kcha];
318  if ( msum.eventCount ) {
319  Metric& met = mets[icha];
320  if ( m_summaryValue.size() ) {
321  met.setValue(msum.getValue(m_summaryValue));
322  if ( m_LogLevel >=3 ) cout << myname << "Channel: summary value: " << icha << ": " << met.value;
323  if ( m_summaryError.size() ) {
324  met.setError(msum.getValue(m_summaryError));
325  if ( m_LogLevel >=3 ) cout << " +/- " << met.error;
326  }
327  if ( m_LogLevel >=3 ) cout << endl;
328  }
329  }
330  }
331  AdcChannelData acd;
332  if ( getState().runCount == 1 ) {
333  acd.setEventInfo(
334  getState().firstRun,
335  getState().eventCount==1 ? getState().firstEvent : AdcChannelData::badIndex()
336  );
337  }
338  Name ofpname = nameReplace(m_PlotFileName, acd, cr);
339  Name ofrname = nameReplace(m_RootFileName, acd, cr);
340  TH1* ph = createHisto(acd, cr);
341  processMetricsForOneRange(cr, mets, ph, ofpname, ofrname, true);
342  }
343  }
344  if ( m_LogLevel >= 1 ) {
345  Index w = 1;
346  Index valmax = std::max(ncha, getState().callCount);
347  if ( ncha ) w = log10(valmax) + 1.01;
348  cout << myname << "Summary for metric " << m_Metric << endl;
349  cout << myname << " # inits: " << setw(w) << getState().initCount << endl;
350  cout << myname << " # calls: " << setw(w) << getState().callCount << endl;
351  cout << myname << " # events: " << setw(w) << getState().eventCount << endl;
352  cout << myname << " # runs: " << setw(w) << getState().runCount << endl;
353  cout << myname << " Maximum # entries for a channel: " << setw(w) << countMax << endl;
354  cout << myname << " Maximum weight sum for a channel: " << setw(w) << weightSumMax << endl;
355  cout << myname << " Total # channels in ranges: " << setw(w) << ncha << endl;
356  cout << myname << " # channels without data: " << setw(w) << ncha - nchaData << endl;
357  cout << myname << " # channels with data: " << setw(w) << nchaData << endl;
358  cout << myname << " # channels with max # entries: " << setw(w) << nchaDataMax << endl;
359  if ( m_LogLevel >= 3 ) {
360  Index icnt = 0;
361  for ( const MetricSummaryMap::value_type& imsm : getState().crsums ) {
362  IndexRange cr = imsm.first;
363  cout << "============= Channel range " << cr.name << endl;
364  const MetricSummaryVector& msums = imsm.second;
365  for ( const MetricSummary& msum : msums ) {
366  if ( msum.eventCount ) {
367  cout << "------------- " << m_Metric << "[" << icnt++ << "]" << endl;
368  cout << myname << " weight flag: " << setw(w) << msum.weightFlag << endl;
369  cout << myname << " # events: " << setw(w) << msum.eventCount << endl;
370  cout << myname << " # weighted events: " << setw(w) << msum.weightedEventCount << endl;
371  cout << myname << " Neff: " << setw(w) << msum.neff() << endl;
372  cout << myname << " mean: " << setw(w) << msum.mean() << " +/- "
373  << setw(w) << msum.dmean() << endl;
374  cout << myname << " RMS: " << setw(w) << msum.rms() << " +/- "
375  << setw(w) << msum.drms() << endl;
376  cout << myname << " center: " << setw(w) << msum.center() << " +/- "
377  << setw(w) << 0.5*msum.range() << endl;
378  }
379  }
380  cout << "===================================" << endl;
381  }
382  }
383  }
384 }
385 
386 //**********************************************************************
387 
389  const string myname = "AdcChannelMetric::initialize: ";
390  if ( !force && getState().initCount ) return;
391  if ( m_LogLevel >= 1 ) cout << myname << "Initializing " << m_crs.size()
392  << " channel ranges." << endl;
393  // Loop over channels and fetch status for each.
394  Index ncha = 0;
395  for ( const IndexRange& ran : m_crs ) {
396  for ( Index icha =ran.begin; icha<ran.end; ++icha ) {
397  channelStatus(icha);
398  ++ncha;
399  }
400  }
401  if ( m_LogLevel >= 1 ) cout << myname << "Initialized " << ncha << " channels." << endl;
402  ++getState().initCount;
403 }
404 
405 //**********************************************************************
406 
408  const string myname = "AdcChannelMetric::view: ";
409  DataMap ret;
410  double val = 0.0;
411  double wt = 0.0;
412  Name sunits;
413  int rstat = getMetric(acd, m_Metric, val, sunits, wt);
414  if ( rstat ) return ret.setStatus(rstat);
415  ret.setString("metricName", m_Metric);
416  ret.setFloat("metricValue", val);
417  ret.setFloat("metricWeight", wt);
418  ret.setString("metricUnits", sunits);
419  return ret;
420 }
421 
422 //**********************************************************************
423 
425  const string myname = "AdcChannelMetric::viewMap: ";
426  MetricMap mets;
427  return viewMapLocal(acds, mets);
428 }
429 
430 //**********************************************************************
431 
433  const string myname = "AdcChannelMetric::update: ";
434  DataMap ret = view(acd);
435  string mnam = m_Metric;
436  if ( m_mdWrite ) {
437  if ( m_mdWarnPresent && acd.hasMetadata(mnam) ) {
438  cout << "WARNING: Run-event-channel " << acd.run() << "-" << acd.event() << "-"
439  << acd.channel() << " already has metadata field " << mnam << endl;
440  }
441  float mval = ret.getFloat("metricValue");
442  acd.setMetadata(mnam, mval);
443  }
444  return ret;
445 }
446 
447 //**********************************************************************
448 
450  const string myname = "AdcChannelMetric::updateMap: ";
451  MetricMap mets;
452  DataMap ret = viewMapLocal(acds, mets);
453  if ( m_mdWrite ) {
454  string mnam = m_Metric;
455  for ( const auto& imet : mets ) {
456  Index icha = imet.first;
457  AdcChannelDataMap::iterator iacd = acds.find(icha);
458  if ( iacd == acds.end() ) {
459  cout << myname << "ERROR: Channel map is missing channel " << icha << endl;
460  } else {
461  AdcChannelData& acd = iacd->second;
462  if ( m_mdWarnPresent && acd.hasMetadata(mnam) ) {
463  cout << "WARNING: Run-event-channel " << acd.run() << "-" << acd.event() << "-"
464  << acd.channel() << " already has metadata field " << mnam << endl;
465  }
466  float mval = imet.second.value;
467  acd.setMetadata(mnam, mval);
468  }
469  }
470  }
471  return ret;
472 }
473 
474 //**********************************************************************
475 
477  const string myname = "AdcChannelMetric::viewMapLocal: ";
478  DataMap ret;
479  if ( acds.size() == 0 ) {
480  cout << myname << "Input channel map is empty." << endl;
481  return ret.setStatus(1);
482  }
483  Index chanFirst = acds.begin()->first;
484  Index chanLast = acds.rbegin()->first;
485  if ( m_LogLevel >= 2 ) cout << myname << "Processing " << acds.size() << " channels: ["
486  << chanFirst << ", " << chanLast << "]" << endl;
487  for ( IndexRange ran : m_crs ) {
488  if ( ran.name == "all" ) {
489  ran.begin = chanFirst;
490  ran.end = chanLast + 1;
491  }
492  Index chanLo = std::max(chanFirst, ran.first());
493  Index chanHi = std::min(chanLast, ran.last());
494  if ( chanHi >= chanLo ) ret += viewMapForOneRange(acds, ran, mets);
495  }
496  return ret;
497 }
498 
499 //**********************************************************************
500 
502 viewMapForOneRange(const AdcChannelDataMap& acds, const IndexRange& ran, MetricMap& mets) const {
503  const string myname = "AdcChannelMetric::viewMapForOneRange: ";
504  DataMap ret;
505  vector<int> ichas;
506  vector<float> vals;
507  vector<float> wgts;
508  // Extract the metrics for the subset of this range included in the data.
509  Index icha0 = ran.begin;
510  AdcChannelDataMap::const_iterator iacd1=acds.lower_bound(icha0);
511  AdcChannelDataMap::const_iterator iacd2=acds.upper_bound(ran.last());
512  if ( getState().update(iacd1->second.run(), iacd1->second.event()) ) {
514  }
515  MetricSummaryVector& metricSums = getState().crsums[ran];
516  if ( metricSums.size() < ran.size() ) metricSums.resize(ran.size());
517  for ( AdcChannelDataMap::const_iterator iacd=iacd1; iacd!=iacd2; ++iacd ) {
518  const AdcChannelData& acd = iacd->second;
519  double met;
520  double wt;
521  Name sunits;
522  int rstat = getMetric(acd, m_Metric, met, sunits, wt);
523  if ( rstat ) {
524  cout << myname << "WARNING: Metric evaluation failed for metric " << m_Metric
525  << " channel " << acd.channel() << endl;
526  continue;
527  }
528  Index icha = iacd->first;
529  mets[icha].setValue(met);
530  MetricSummary& metricSum = metricSums[icha-icha0];
531  metricSum.add(met, wt);
532  if ( m_LogLevel >=4 ) {
533  cout << myname << " Chan: met, wt (wsum, range): " << icha << ": " << met << ", " << wt
534  << " (" << metricSum.weightSum << ", " << metricSum.range() << ")" << endl;
535  }
536  ichas.push_back(icha);
537  vals.push_back(met);
538  wgts.push_back(wt);
539  }
540  // Create the histogram for this data and this range.
541  const AdcChannelData& acdFirst = acds.begin()->second;
542  string ofpname;
543  string ofrname;
544  if ( ! m_doSummary ) {
545  ofpname = nameReplace(m_PlotFileName, acdFirst, ran);
546  ofrname = nameReplace(m_RootFileName, acdFirst, ran);
547  }
548  // Fill the histogram and create the plots for this data and this range.
549  if ( m_HistName.size() ) {
550  TH1* ph = createHisto(acdFirst, ran);
551  processMetricsForOneRange(ran, mets, ph, ofpname, ofrname, false);
552  ret.setHist(ph, true);
553  }
554  ret.setString("metricName", m_Metric);
555  ret.setIntVector("metricChannels", ichas);
556  ret.setFloatVector("metricValues", vals);
557  ret.setFloatVector("metricWeights", wgts);
558  return ret;
559 }
560 
561 //**********************************************************************
562 
563 int AdcChannelMetric::getMetric(const AdcChannelData& acdtop, Name met, double& val,
564  Name& sunits, double& weight) const {
565  const string myname = "AdcChannelMetric::getMetric: ";
566  val = 0.0;
567  weight = 0.0;
568  sunits = "";
569  AdcIndex nent = acdtop.viewSize(m_DataView);
570  const AdcChannelData* pacd0 = acdtop.viewEntry(m_DataView, 0);
571  if ( nent && pacd0 == nullptr ) {
572  cout << myname << "ERROR: Channel " << acdtop.channel() << " view " << m_DataView
573  << " is missing its first entry." << endl;
574  return 4;
575  }
576  if ( nent ) weight = 1.0;
577  if ( met == "pedestal" ) {
578  val = nent ? pacd0->pedestal : 0;
579  sunits = "ADC count";
580  } else if ( met == "pedestalDiff" ) {
581  val = nent ? pacd0->pedestal : 0.0;
582  if ( m_pPedestalReference != nullptr ) {
583  double pedRef = m_pPedestalReference->value(acdtop.channel(), 0.0);
584  val -= pedRef;
585  } else if ( m_PedestalReference == "first" && nent ) {
586  Index icha = acdtop.channel();
587  MetricMap& pedRefs = getState().pedRefs;
588  MetricMap::const_iterator ipdr = pedRefs.find(icha);
589  if ( ipdr == pedRefs.end() ) {
590  pedRefs[icha].value = val;
591  val = 0.0;
592  } else {
593  val -= ipdr->second.value;
594  }
595  } else {
596  cout << myname << "WARNING: Pedestal difference requested without reference." << endl;
597  }
598  sunits = "ADC count";
599  } else if ( met == "pedestalRms" ) {
600  val = nent ? pacd0->pedestalRms : 0.0;
601  sunits = "ADC count";
602  } else if ( met == "time" ) {
603  val = acdtop.time();
604  sunits = "sec";
605  } else if ( met == "fembID" ) {
606  val = acdtop.fembID();
607  } else if ( met == "fembChannel" ) {
608  val = acdtop.fembChannel();
609  } else if ( met == "apaFembID" ) {
610  val = acdtop.fembID()%20;
611  } else if ( met == "asic" ) {
612  val = acdtop.fembChannel()/16 + 1;
613  } else if ( met == "nraw" ) {
614  val = 0.0;
615  weight = 1.0;
616  for ( Index ient=0; ient<nent; ++ient ) val += acdtop.viewEntry(m_DataView, ient)->raw.size();
617  } else if ( met == "nsam" ) {
618  val = 0.0;
619  weight = 1.0;
620  for ( Index ient=0; ient<nent; ++ient ) val += acdtop.viewEntry(m_DataView, ient)->samples.size();
621  } else if ( met == "rawRms" ) {
622  double sum = 0.0;
623  AdcIndex nsam = 0;
624  for ( Index ient=0; ient<nent; ++ient ) {
625  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
626  double ped = pacd->pedestal;
627  for ( AdcSignal sig : pacd->raw ) {
628  double dif = double(sig) - ped;
629  sum += dif*dif;
630  ++nsam;
631  }
632  }
633  val = nsam == 0 ? 0.0 : sqrt(sum/nsam);
634  weight = nsam;
635  } else if ( met == "samRms" ) {
636  double sum = 0.0;
637  Index nsam = 0;
638  for ( Index ient=0; ient<nent; ++ient ) {
639  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
640  for ( double sig : pacd->samples ) {
641  sum += sig*sig;
642  ++nsam;
643  }
644  }
645  val = nsam == 0 ? 0.0 : sqrt(sum/nsam);
646  weight = nsam;
647  } else if ( met.substr(0, 6) == "samRms" ) { // samRmsNN, NN is integer
648  val = 0.0;
649  weight = 0.0;
650  istringstream sscnt(met.substr(6));
651  Index ncnt = 0;
652  sscnt >> ncnt;
653  std::vector<float> samSums; // Sum over samples for each group of cnt samples.
654  if ( ncnt == 0 ) {
655  cout << myname << "WARNING: Invalid metric: " << met << endl;
656  } else {
657  float samSum = 0.0;
658  for ( Index ient=0; ient<nent; ++ient ) {
659  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
660  Index nsam = pacd->samples.size();
661  Index samCount = 0;
662  for ( Index isam=0; isam<nsam; ++isam ) {
663  float sam = pacd->samples[isam];
664  samSum += sam;
665  ++samCount;
666  if ( samCount == ncnt ) {
667  samSums.push_back(samSum);
668  samSum = 0.0;
669  samCount = 0;
670  }
671  }
672  }
673  }
674  if ( samSums.size() ) {
675  float sum = 0.0;
676  for ( float samSum : samSums ) sum += samSum*samSum;
677  val = sqrt(sum/samSums.size());
678  weight = samSums.size();
679  }
680  } else if ( met == "sigRms" || met == "nsgRms" ) {
681  double sum = 0.0;
682  Index nsum = 0;
683  Index nsamtot = 0;
684  bool doSignal = met == "sigRms";
685  for ( Index ient=0; ient<nent; ++ient ) {
686  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
687  Index nsam = pacd->samples.size();
688  if ( pacd->signal.size() != nsam ) {
689  cout << myname << "WARNING: signal and sample sizes differ";
690  if ( m_DataView.size() ) cout << " for view entry " << m_DataView << "[" << ient << "]";
691  cout << ": " << pacd->signal.size() << " != " << nsam << "." << endl;
692  } else {
693  for ( Index isam=0; isam<nsam; ++isam ) {
694  if ( pacd->signal[isam] == doSignal ) {
695  double sig = pacd->samples[isam];
696  sum += sig*sig;
697  ++nsum;
698  }
699  ++nsamtot;
700  }
701  }
702  }
703  val = nsum == 0 ? 0.0 : sqrt(sum/nsum);
704  weight = nsum;
705  if ( m_LogLevel >= 4 ) {
706  cout << myname << "Sample count for " << met << " for channel " << acdtop.channel();
707  if ( m_DataView.size() ) cout << " view " << m_DataView;
708  cout << ": " << nsum << "/" << nsamtot << "."
709  << " " << met << " = " << val << endl;
710  }
711  // nsgRmsNN - Integrated noise with NN samples.
712  } else if ( met.substr(0, 6) == "nsgRms" ) {
713  val = 0.0;
714  weight = 0.0;
715  istringstream sscnt(met.substr(6));
716  Index ncnt = 0;
717  sscnt >> ncnt;
718  std::vector<float> samSums; // Sum over samples for each group of ncnt samples.
719  if ( ncnt == 0 ) {
720  cout << myname << "WARNING: Invalid metric: " << met << endl;
721  } else {
722  for ( Index ient=0; ient<nent; ++ient ) {
723  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
724  Index nsam = pacd->samples.size();
725  if ( pacd->signal.size() != nsam ) {
726  cout << myname << "WARNING: signal and sample sizes differ";
727  if ( m_DataView.size() ) cout << " for view entry " << m_DataView << "[" << ient << "]";
728  cout << " metric " << met << ": " << pacd->signal.size() << " != " << nsam << "." << endl;
729  continue;
730  }
731  for ( Index isam0=0; isam0+ncnt<=nsam; ++isam0 ) {
732  bool foundSignal = false;
733  float samSum = 0.0;
734  for ( Index icnt=0; icnt<ncnt; ++icnt ) {
735  Index isam = isam0 + icnt;
736  if ( pacd->signal[isam] ) {
737  foundSignal = true;
738  break;
739  }
740  float sam = pacd->samples[isam];
741  samSum += sam;
742  }
743  if ( foundSignal ) break;
744  samSums.push_back(samSum);
745  }
746  }
747  }
748  if ( samSums.size() ) {
749  float sum = 0.0;
750  for ( float samSum : samSums ) sum += samSum*samSum;
751  val = sqrt(sum/samSums.size());
752  weight = samSums.size();
753  }
754  } else if ( met == "sigFrac" ) {
755  Index nsamtot = 0;
756  Index nsig = 0;
757  for ( Index ient=0; ient<nent; ++ient ) {
758  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
759  Index nsam = pacd->samples.size();
760  if ( pacd->signal.size() != nsam ) {
761  cout << myname << "WARNING: Signal and sample sizes differ for sigFrac";
762  if ( m_DataView.size() ) cout << " view entry " << m_DataView << "[" << ient << "]";
763  cout << ": " << pacd->signal.size() << " != " << nsam << "." << endl;
764  } else {
765  for ( Index isam=0; isam<nsam; ++isam ) {
766  ++nsamtot;
767  if ( pacd->signal[isam] ) ++nsig;
768  }
769  }
770  }
771  val = nsamtot > 0 ? float(nsig)/float(nsamtot) : 0.0;
772  } else if ( met == "rawTailFraction" ) {
773  Index ntail = 0;
774  Index nsam = 0;
775  for ( Index ient=0; ient<nent; ++ient ) {
776  const AdcChannelData* pacd = acdtop.viewEntry(m_DataView, ient);
777  double lim = 3.0*pacd->pedestalRms;
778  double ped = pacd->pedestal;
779  for ( AdcSignal sig : pacd->raw ) {
780  double dif = double(sig) - ped;
781  if ( fabs(dif) > lim ) ++ntail;
782  ++nsam;
783  }
784  }
785  val = nsam > 0 ? double(ntail)/nsam : 0.0;
786  } else if ( nent == 1 && pacd0->hasMetadata(met) ) {
787  if ( nent != 1 ) {
788  cout << myname << "WARNING: Channel " << acdtop.channel()
789  << " filling metadata only for the first of " << nent
790  << " entries." << endl;
791  }
792  val = pacd0->metadata.find(met)->second;
793  // Compound metric: met1+met2
794  // TODO: Move this to ctor.
795  } else if ( met.find("+") != string::npos ) {
796  vector<string> nams;
797  string metsrem = met;
798  string::size_type ipos = 0;
799  val = 0.0;
800  while ( ipos != string::npos ) {
801  ipos = metsrem.find("+");
802  string newmet = metsrem.substr(0, ipos);
803  double newval = 0.0;
804  double newwt = 0.0;
805  int sstat = getMetric(acdtop, newmet, newval, sunits, newwt);
806  if ( sstat ) {
807  cout << myname << "ERROR: Invalid sub-metric name: " << newmet << endl;
808  return 2;
809  }
810  if ( newwt != 1.0 ) {
811  cout << myname << "Evaluation of sub-metric " << newmet << " for metric " << met
812  << " returned non-unity weight " << newwt << endl;
813  return 3;
814  }
815  val += newval;
816  if ( ipos == string::npos ) break;
817  metsrem = metsrem.substr(ipos + 1);
818  }
819  } else {
820  cout << myname << "ERROR: Invalid metric name: " << met << endl;
821  return 1;
822  }
823  if ( m_LogLevel >= 4 ) {
824  cout << myname << setw(20) << met << ": " << val << endl;
825  }
826  return 0;
827 }
828 
829 //**********************************************************************
830 
831 string AdcChannelMetric::
832 nameReplace(string name, const AdcChannelData& acd, const IndexRange& ran) const {
833  StringManipulator sman(name, false);
834  sman.replace("%CRNAME%", ran.name);
835  sman.replace("%CRLABEL%", ran.label());
836  sman.replace("%CRLABEL1%", ran.label(1));
837  sman.replace("%CRLABEL2%", ran.label(2));
839  if ( pnbl == nullptr ) return name;
840  DataMap dm;
841  dm.setInt("chan1", ran.first());
842  dm.setInt("chan2", ran.last());
843  return pnbl->build(acd, dm, name);
844 }
845 
846 //**********************************************************************
847 
849 processMetricsForOneRange(const IndexRange& ran, const MetricMap& mets, TH1* ph,
850  Name ofpname, Name ofrname, bool useErrors) const {
851  const string myname = "AdcChannelMetric::processMetricsForOneRange: ";
852  unsigned int ngraph = m_PlotUsesStatus ? 4 : 1;
853  NameVector statNames = {"All", "Good", "Bad", "Noisy"};
854  LineColors lc;
855  std::vector<int> statCols = {lc.blue(), lc.green(), lc.red(), lc.brown()};
856  Name hname = ph->GetName();
857  Name htitl = ph->GetTitle();
858  // # channels vs. metric
859  if ( m_MetricBins > 0 ) {
860  if ( m_LogLevel >= 2 ) cout << myname << "Plotting # channels vs. metric. Count is " << mets.size() << endl;
861  for ( MetricMap::value_type imet : mets ) {
862  double met = imet.second.value;
863  ph->Fill(met);
864  }
865  if ( ofpname.size() ) {
866  TPadManipulator man;
868  man.add(ph);
869  man.addAxis();
870  man.showUnderflow();
871  man.showOverflow();
872  man.print(ofpname);
873  }
874  } else {
875  // Metric vs. channel.
876  Name slaby = ph->GetYaxis()->GetTitle();
877  TGraphVector graphs(ngraph, nullptr);
878  TGraphErrorsVector egraphs(ngraph, nullptr);
879  if ( m_LogLevel >= 2 ) cout << myname << "Plotting metric vs. channel. Count is " << mets.size() << endl;
880  for ( Index igra=0; igra<ngraph; ++igra ) {
881  string gname = hname;
882  string gtitl = htitl;
883  StringManipulator smanName(gname, false);
884  smanName.replace("%STATUS%", statNames[igra]);
885  StringManipulator smanTitl(gtitl, false);
886  smanTitl.replace("%STATUS%", statNames[igra]);
887  if ( useErrors ) {
888  egraphs[igra] = new TGraphErrors;
889  graphs[igra] = egraphs[igra];
890  } else {
891  graphs[igra] = new TGraph;
892  }
893  TGraph* pg = graphs[igra];
894  pg->SetName(gname.c_str());
895  pg->SetTitle(gtitl.c_str());
896  if ( ! useErrors ) pg->SetMarkerStyle(2);
897  pg->SetMarkerColor(statCols[igra]);
898  pg->SetLineColor(statCols[igra]);
899  pg->GetXaxis()->SetTitle("Channel");
900  pg->GetYaxis()->SetTitle(slaby.c_str());
901  }
902  TGraph* pgAll = graphs[0];
903  TGraphErrors* pgeAll = egraphs[0];
904  double ex = 0.25;
905  Index nfill = 0;
906  Index icha0 = ran.begin;
907  for ( MetricMap::value_type imet : mets ) {
908  Index icha = imet.first;
909  double met = imet.second.value;
910  double err = imet.second.error;
911  if ( m_LogLevel >= 3 ) {
912  cout << myname << " " << met << ": " << met << " +/- " << err << endl;
913  }
914  Index bin = (icha + 1) - icha0;
915  ph->SetBinContent(bin, met);
916  if ( err ) ph->SetBinError(bin, err);
917  double gval = met;
918  Index iptAll = pgAll->GetN();
919  float xcha = icha + 0.5;
920  pgAll->SetPoint(iptAll, xcha, gval);
921  if ( pgeAll != nullptr ) pgeAll->SetPointError(iptAll, ex, err);
922  if ( m_PlotUsesStatus ) {
923  Index stat = channelStatus(icha);
924  if ( stat > 0 ) {
925  TGraph* pgStat = graphs[stat];
926  TGraphErrors* pgeStat = egraphs[stat];
927  Index iptStat = pgStat->GetN();
928  pgStat->SetPoint(iptStat, xcha, gval);
929  if ( pgeStat != nullptr ) pgeStat->SetPointError(iptStat, ex, err);
930  }
931  }
932  ++nfill;
933  }
934  if ( m_LogLevel >= 3 ) cout << myname << "Filled " << nfill << " channels." << endl;
935  if ( ofpname.size() && nfill > 0 ) {
936  TPadManipulator man;
938  //man.add(ph, "hist");
939  //man.add(ph, "axis");
940  man.add(pgAll, "P");
941  if ( m_PlotUsesStatus ) {
942  for ( int igra : {1, 3, 2} ) {
943  TGraph* pgra = graphs[igra];
944  if ( pgra->GetN() ) man.add(pgra, "P");
945  }
946  }
947  man.addAxis();
948  if ( m_ChannelLineModulus ) {
949  for ( Index icha : m_ChannelLinePattern ) {
951  }
952  for ( Index icha : m_ChannelLinePatternSolid ) {
953  man.addVerticalModLines(m_ChannelLineModulus, icha, 1.0, 1);
954  }
955  } else {
956  for ( Index icha : m_ChannelLinePattern ) {
957  if ( icha > icha0 && icha < ran.last() ) {
958  man.addVerticalLine(icha, 1.0, 3);
959  }
960  }
961  for ( Index icha : m_ChannelLinePatternSolid ) {
962  if ( icha > icha0 && icha < ran.last() ) {
963  man.addVerticalLine(icha, 1.0, 1);
964  }
965  }
966  }
967  man.setRangeX(ran.begin, ran.end);
968  float mmin = getState().metricMin;
969  float mmax = getState().metricMax;
970  if ( mmax > mmin ) man.setRangeY(mmin, mmax);
971  //man.showGraphOverflow("BLTR", 2, statCols[0]);
972  man.setGridY();
973  man.print(ofpname);
974  }
975  if ( m_LogLevel > 1 ) {
976  cout << myname << "Created plot ";
977  cout << "for " << nfill << " channels in range " << ran.name << endl;
978  cout << myname << " Output file: " << ofpname << endl;
979  }
980  }
981  if ( ofrname.size() ) {
982  TFile* pfile = TFile::Open(ofrname.c_str(), "UPDATE");
983  ph->Write();
984  if ( m_LogLevel > 1 ) cout << myname << "Wrote " << ph->GetName() << " to " << ofrname << endl;
985  delete pfile;
986  }
987 }
988 
989 //**********************************************************************
990 
991 TH1* AdcChannelMetric::createHisto(const AdcChannelData& acd, const IndexRange& ran) const {
992  string hname = nameReplace( m_HistName, acd, ran);
993  string htitl = nameReplace( m_HistTitle, acd, ran);
994  string slabm = nameReplace( m_MetricLabel, acd, ran);
995  TH1* ph = nullptr;
997  if ( nbins == 0 ) {
998  ph = new TH1F(hname.c_str(), htitl.c_str(), ran.size(), ran.begin, ran.end);
999  ph->GetXaxis()->SetTitle("Channel");
1000  ph->GetYaxis()->SetTitle(slabm.c_str());
1001  } else {
1002  ph = new TH1F(hname.c_str(), htitl.c_str(), nbins, getState().metricMin, getState().metricMax);
1003  ph->GetXaxis()->SetTitle(slabm.c_str());
1004  ph->GetYaxis()->SetTitle("# channels");
1005  }
1006  ph->SetDirectory(nullptr);
1007  ph->SetLineWidth(2);
1008  ph->SetStats(0);
1009  return ph;
1010 }
1011 
1012 //**********************************************************************
1013 
1016  if ( icha >= stats.size() ) stats.resize(icha + 1, 0);
1017  Index& stat = stats[icha];
1018  if ( stat == 0 && m_pChannelStatusProvider != nullptr ) {
1019  if ( m_pChannelStatusProvider->IsBad(icha) ) stat = 2;
1020  else if ( m_pChannelStatusProvider->IsNoisy(icha) ) stat = 3;
1021  else stat = 1;
1022  }
1023  return stat;
1024 }
1025 
1026 //**********************************************************************
1027 
1029  const string myname = "AdcChannelMetric::evaluateFormulas: ";
1030  if ( m_prdtool != nullptr ) {
1031  Index run = getState().lastRun;
1032  RunData rdat = m_prdtool->runData(run);
1033  if ( ! rdat.isValid() ) {
1034  cout << myname << "WARNING: RunData not found for run " << run << "." << endl;
1035  } else {
1036  rdat.setFormulaPars(*m_MetricMin);
1037  rdat.setFormulaPars(*m_MetricMax);
1038  }
1039  }
1040  float mmin = 0.0;
1041  float mmax = 100.0;
1042  if ( m_MetricMin->ready() ) {
1043  mmin = m_MetricMin->eval();
1044  } else {
1045  cout << myname << "WARNING: Using default metric min " << mmin << endl;
1046  }
1047  getState().metricMin = mmin;
1048  if ( m_MetricMax->ready() ) {
1049  mmax = m_MetricMax->eval();
1050  } else {
1051  cout << myname << "WARNING: Using default metric max " << mmax << endl;
1052  }
1053  getState().metricMax = mmax;
1054 }
1055 
1056 //**********************************************************************
1057 
static QCString name
Definition: declinfo.cpp:673
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
void setValue(double a_value)
intermediate_table::iterator iterator
ParFormula * m_MetricMax
int setGridY(bool flag=true)
const FloatArrayTool * m_pPedestalReference
unsigned int Index
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
DataMap update(AdcChannelData &acd) const override
DataMap viewMapLocal(const AdcChannelDataMap &acds, MetricMap &mets) const
void setFloat(Name name, float val)
Definition: DataMap.h:133
static ColorType blue()
Definition: LineColors.h:26
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
unsigned int Index
DataMap & setStatus(int stat)
Definition: DataMap.h:130
std::string string
Definition: nybbler.cc:12
float AdcSignal
Definition: AdcTypes.h:21
Index begin
Definition: IndexRange.h:34
virtual double eval(const Values &vars) const =0
void evaluateFormulas() const
const AdcChannelStringTool * m_adcStringBuilder
virtual bool IsNoisy(raw::ChannelID_t channel) const =0
Returns whether the specified channel is noisy in the current run.
static ColorType red()
Definition: LineColors.h:27
Name nameReplace(Name name, const AdcChannelData &acd, const IndexRange &ran) const
virtual Name formulaString() const =0
virtual bool ready() const
Definition: ParFormula.h:56
struct vector vector
int replace(std::string substr, const T &xsub)
int setCanvasSize(int wx, int wy)
NameVector m_ChannelRanges
const lariov::ChannelStatusProvider * m_pChannelStatusProvider
std::vector< MetricSummary > MetricSummaryVector
void setHist(Name name, TH1 *ph, bool own=false)
Definition: DataMap.h:136
Index size() const
Definition: IndexRange.h:88
std::vector< Name > NameVector
intermediate_table::const_iterator const_iterator
unsigned int Index
bool isValid() const
Definition: IndexRange.h:94
Index end
Definition: IndexRange.h:35
time_t time() const
State & getState() const
DataMap view(const AdcChannelData &acd) const override
void processMetricsForOneRange(const IndexRange &ran, const MetricMap &mets, TH1 *ph, Name ofname, Name ofrname, bool useErrors) const
void setError(double a_error)
weight
Definition: test.py:257
int showOverflow(bool show=true)
Name name
Definition: IndexRange.h:32
bool isValid() const
Definition: RunData.h:48
static ColorType green()
Definition: LineColors.h:28
IndexRangeVector m_crs
static constexpr double ms
Definition: Units.h:96
Index fembID() const
void setIntVector(Name name, const IntVector &val)
Definition: DataMap.h:132
Index last() const
Definition: IndexRange.h:96
virtual Index npar() const
Definition: ParFormula.h:44
IndexVector m_ChannelCounts
AdcSignal pedestalRms
void setString(Name name, String val)
Definition: DataMap.h:135
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
bool hasMetadata(Name mname) const
std::vector< Index > IndexVector
Index fembChannel() const
bool update(Index run, Index event)
int showUnderflow(bool show=true)
AdcIndex run() const
Index channelStatus(Index icha) const
void setEventInfo(EventInfoPtr pevi)
std::vector< TGraphErrors * > TGraphErrorsVector
int addAxis(bool flag=true)
NameVector m_MetadataFlags
void setInt(Name name, int val)
Definition: DataMap.h:131
std::vector< TGraph * > TGraphVector
void initialize(bool force=false)
DataMap updateMap(AdcChannelDataMap &acds) const override
AdcChannelMetric(fhicl::ParameterSet const &ps)
virtual RunData runData(Index run, Index subRun=0) const =0
AdcIndex event() const
static int max(int a, int b)
static constexpr double ps
Definition: Units.h:99
Name label(Index ilab=0) const
Definition: IndexRange.h:106
AdcCountVector raw
virtual int getMetric(const AdcChannelData &acd, Name met, double &metricValue, Name &metricUnits, double &metricWeight) const
IndexVector m_ChannelLinePattern
unsigned int AdcIndex
Definition: AdcTypes.h:15
void err(const char *fmt,...)
Definition: message.cpp:226
int addVerticalModLines(double xmod, double xoff=0.0, double lenfrac=1.0, int isty=3)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
virtual Index offset() const
Channel channel() const
AdcSignal pedestal
AdcFilterVector signal
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Index first() const
Definition: IndexRange.h:95
virtual Index size() const
int setRangeX(double x1, double x2)
const AdcChannelData * viewEntry(Name vpnam, AdcIndex ient) const
double getValue(Name vnam) const
int addVerticalLine(double xoff=0.0, double lenfrac=1.0, int isty=1)
QTextStream & bin(QTextStream &s)
DataMap viewMapForOneRange(const AdcChannelDataMap &acds, const IndexRange &ran, MetricMap &mets) const
Interface for experiment-specific channel quality info provider.
void setMetadata(Name mname, float val)
size_t viewSize() const
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
RunDataTool * m_prdtool
virtual float value(Index ival) const
static bool isValueName(Name vnam)
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
Interface for experiment-specific service for channel quality info.
void setFloatVector(Name name, const FloatVector &val)
Definition: DataMap.h:134
DataMap viewMap(const AdcChannelDataMap &acds) const override
SetStat setFormulaPars(TFormula *form)
Definition: RunData.h:87
static Index badIndex()
int setRangeY(double y1, double y2)
TH1 * createHisto(const AdcChannelData &acd, const IndexRange &ran) const
static ColorType brown()
Definition: LineColors.h:29
int print(std::string fname, std::string spat="{,}")
static DuneToolManager * instance(std::string fclname="", int dbg=1)
AdcSignalVector samples
IndexVector m_ChannelLinePatternSolid
ParFormula * m_MetricMin
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)
Event finding and building.
std::map< Index, Metric > MetricMap
void add(double val, double weight)
virtual IndexRange get(Name nam) const =0