Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
AdcPedestalFitter Class Reference

#include <AdcPedestalFitter.h>

Inheritance diagram for AdcPedestalFitter:
TpcDataTool AdcChannelTool

Classes

class  State
 

Public Types

using Index = unsigned int
 
using IndexVector = std::vector< Index >
 
using IndexSet = std::set< Index >
 
- Public Types inherited from AdcChannelTool
using Index = unsigned int
 

Public Member Functions

 AdcPedestalFitter (fhicl::ParameterSet const &ps)
 
DataMap view (const AdcChannelData &acd) const override
 
DataMap update (AdcChannelData &acd) const override
 
DataMap updateMap (AdcChannelDataMap &acds) const override
 
DataMap beginEvent (const DuneEventInfo &) const override
 
- Public Member Functions inherited from TpcDataTool
virtual DataMap updateTpcData (TpcData &) const
 
virtual DataMap viewTpcData (const TpcData &) const
 
virtual int forwardTpcData () const
 
- Public Member Functions inherited from AdcChannelTool
virtual ~AdcChannelTool ()=default
 
virtual DataMap viewMap (const AdcChannelDataMap &acds) const
 
virtual bool updateWithView () const
 
virtual bool viewWithUpdate () const
 
virtual DataMap endEvent (const DuneEventInfo &) const
 
virtual DataMap close (const DataMap *dmin=nullptr)
 

Private Types

using Name = std::string
 
using NameVector = std::vector< Name >
 
using FormulaMap = std::map< Name, ParFormula * >
 
using NameSet = std::set< Name >
 
using NameSetMap = std::map< Name, NameSet >
 

Private Member Functions

Statestate () const
 
Name nameReplace (Name name, const AdcChannelData &acd, bool isTitle) const
 
DataMap getPedestal (const AdcChannelData &acd) const
 
int fillChannelPad (DataMap &dm, const AdcChannelData &acd, TPadManipulator *pman) const
 

Private Attributes

int m_LogLevel
 
Name m_AdcRange
 
Index m_FitOpt
 
float m_FitPrecision
 
IndexVector m_SkipFlags
 
Name m_AdcFitRange
 
Name m_FitRmsMin
 
Name m_FitRmsMax
 
bool m_RemoveStickyCode
 
Name m_HistName
 
Name m_HistTitle
 
Name m_PlotFileName
 
Name m_RootFileName
 
Index m_PlotSizeX
 
Index m_PlotSizeY
 
Index m_PlotShowFit
 
Index m_PlotSplitX
 
Index m_PlotSplitY
 
const AdcChannelStringToolm_adcStringBuilder
 
IndexSet m_skipFlags
 
NameVector m_fitOpts
 
FormulaMap m_tfs
 
NameSetMap m_tfpars
 
bool m_haveFormulaParams
 
const RunDataToolm_prdtool
 
std::unique_ptr< Statem_pstate
 

Additional Inherited Members

- Static Public Member Functions inherited from AdcChannelTool
static int interfaceNotImplemented ()
 

Detailed Description

Definition at line 103 of file AdcPedestalFitter.h.

Member Typedef Documentation

using AdcPedestalFitter::FormulaMap = std::map<Name, ParFormula*>
private

Definition at line 126 of file AdcPedestalFitter.h.

using AdcPedestalFitter::Index = unsigned int

Definition at line 108 of file AdcPedestalFitter.h.

Definition at line 110 of file AdcPedestalFitter.h.

Definition at line 109 of file AdcPedestalFitter.h.

Definition at line 124 of file AdcPedestalFitter.h.

using AdcPedestalFitter::NameSet = std::set<Name>
private

Definition at line 127 of file AdcPedestalFitter.h.

using AdcPedestalFitter::NameSetMap = std::map<Name, NameSet>
private

Definition at line 128 of file AdcPedestalFitter.h.

Definition at line 125 of file AdcPedestalFitter.h.

Constructor & Destructor Documentation

AdcPedestalFitter::AdcPedestalFitter ( fhicl::ParameterSet const &  ps)

Definition at line 69 of file AdcPedestalFitter_tool.cc.

70 : m_LogLevel(ps.get<int>("LogLevel")),
71  m_AdcRange(ps.get<Name>("AdcRange")),
72  m_FitOpt(ps.get<Index>("FitOpt")),
73  m_FitPrecision(ps.get<float>("FitPrecision")),
74  m_SkipFlags(ps.get<IndexVector>("SkipFlags")),
75  m_AdcFitRange(ps.get<Name>("AdcFitRange")),
76  m_FitRmsMin(ps.get<Name>("FitRmsMin")),
77  m_FitRmsMax(ps.get<Name>("FitRmsMax")),
78  m_RemoveStickyCode(ps.get<bool>("RemoveStickyCode")),
79  m_HistName(ps.get<string>("HistName")),
80  m_HistTitle(ps.get<string>("HistTitle")),
81  m_PlotFileName(ps.get<string>("PlotFileName")),
82  m_RootFileName(ps.get<string>("RootFileName")),
83  m_PlotSizeX(ps.get<Index>("PlotSizeX")),
84  m_PlotSizeY(ps.get<Index>("PlotSizeY")),
85  m_PlotShowFit(ps.get<Index>("PlotShowFit")),
86  m_PlotSplitX(ps.get<Index>("PlotSplitX")),
87  m_PlotSplitY(ps.get<Index>("PlotSplitY")),
88  m_prdtool(nullptr),
89  m_pstate(new State) {
90  const string myname = "AdcPedestalFitter::ctor: ";
92  string stringBuilder = "adcStringBuilder";
93  m_adcStringBuilder = ptm->getShared<AdcChannelStringTool>(stringBuilder);
94  if ( m_adcStringBuilder == nullptr ) {
95  cout << myname << "WARNING: AdcChannelStringTool not found: " << stringBuilder << endl;
96  }
97  for ( Index flg : m_SkipFlags ) m_skipFlags.insert(flg);
98  // Set the vector of fit options.
99  // These are tried in turn until one succeeds.
100  {
101  Name foptLsq = "WWB";
102  // Nov2018: Likelihood fit better handles pdsp run 5803 event 86 channel 7309.
103  Name foptLik = "LWB";
104  if ( m_FitOpt == 0 ) {
105  if ( m_LogLevel > 0 ) cout << myname << "Mean used in place of pedestal fit." << endl;
106  } else if ( m_FitOpt == 1 ) {
107  m_fitOpts.push_back(foptLsq);
108  if ( m_LogLevel > 0 ) cout << myname << "Chi-square fit used for pedestal." << endl;
109  } else if ( m_FitOpt == 2 ) {
110  m_fitOpts.push_back(foptLik);
111  if ( m_LogLevel > 0 ) cout << myname << "Likelihood fit used for pedestal." << endl;
112  } else if ( m_FitOpt == 3 ) {
113  if ( m_LogLevel > 0 ) cout << myname << "Chi-square/likelihood fit used for pedestal." << endl;
114  m_fitOpts.push_back(foptLsq);
115  m_fitOpts.push_back(foptLik);
116  } else if ( m_FitOpt != 0.0 ) {
117  cout << "WARNING: Invalid FitOpt: " << m_FitOpt << ". Not fit will be performed." << endl;
118  }
119  }
120  // Fetch the formula parameters.
121  m_tfs["AdcRange"] = new RootParFormula("adcRange", m_AdcRange);
122  m_tfs["AdcFitRange"] = new RootParFormula("adcFitRange", m_AdcFitRange);
123  m_tfs["FitRmsMin"] = new RootParFormula("fitRmsMin", m_FitRmsMin);
124  m_tfs["FitRmsMax"] = new RootParFormula("fitRmsMax", m_FitRmsMax);
125  m_haveFormulaParams = false;
126  for ( const auto& itf : m_tfs ) {
127  if ( itf.second->npar() > 0 ) m_haveFormulaParams = true;
128  }
129  if ( m_haveFormulaParams ) {
130  string stnam = "runDataTool";
131  m_prdtool = ptm->getShared<RunDataTool>(stnam);
132  if ( m_prdtool == nullptr ) {
133  cout << myname << "ERROR: RunDataTool " << stnam
134  << " not found. Formulas will not be evaluated." << endl;
135  } else {
136  cout << myname << "RunDataTool retrieved." << endl;
137  }
138  } else {
139  cout << myname << "No formula parameters. RunDataTool is not retrieved." << endl;
140  }
141  if ( m_LogLevel >= 1 ) {
142  cout << myname << "Configuration parameters:" << endl;
143  cout << myname << " LogLevel: " << m_LogLevel << endl;
144  cout << myname << " AdcRange: " << m_AdcRange << endl;
145  cout << myname << " FitOpt: " << m_FitOpt << endl;
146  cout << myname << " FitPrecision: " << m_FitPrecision << endl;
147  cout << myname << " SkipFlags: [";
148  bool first = true;
149  for ( Index flg : m_SkipFlags ) {
150  if ( first ) first = false;
151  else cout << ", ";
152  cout << flg;
153  }
154  cout << "]" << endl;
155  cout << myname << " AdcFitRange: " << m_AdcFitRange << endl;
156  cout << myname << " FitRmsMin: " << m_FitRmsMin << endl;
157  cout << myname << " FitRmsMax: " << m_FitRmsMax << endl;
158  cout << myname << " RemoveStickyCode: " << m_RemoveStickyCode << endl;
159  cout << myname << " HistName: " << m_HistName << endl;
160  cout << myname << " HistTitle: " << m_HistTitle << endl;
161  cout << myname << " PlotFileName: " << m_PlotFileName << endl;
162  cout << myname << " RootFileName: " << m_RootFileName << endl;
163  cout << myname << " PlotSizeX: " << m_PlotSizeX << endl;
164  cout << myname << " PlotSizeY: " << m_PlotSizeY << endl;
165  cout << myname << " PlotShowFit: " << m_PlotShowFit << endl;
166  cout << myname << " PlotSplitX: " << m_PlotSplitX << endl;
167  cout << myname << " PlotSplitY: " << m_PlotSplitY << endl;
168  }
169 }
std::vector< Index > IndexVector
ChannelGroupService::Name Name
unsigned int Index
const AdcChannelStringTool * m_adcStringBuilder
static constexpr double ps
Definition: Units.h:99
std::unique_ptr< State > m_pstate
static DuneToolManager * instance(std::string fclname="", int dbg=1)
const RunDataTool * m_prdtool
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)

Member Function Documentation

DataMap AdcPedestalFitter::beginEvent ( const DuneEventInfo evi) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 298 of file AdcPedestalFitter_tool.cc.

298  {
299  const string myname = "AdcPedestalFitter::beginEvent: ";
300  DataMap res;
301  ++state().nevt;
302  if ( evi.run == state().run ) return res;
303  if ( m_LogLevel >= 2 ) {
304  cout << myname << "Setting run " << evi.run << endl;
305  }
306  state().run = evi.run;
307  string msg;
308  if ( m_haveFormulaParams ) {
309  RunData rdat;
310  if ( m_prdtool == nullptr ) {
311  msg = "WARNING: RunData tool not found. Using default parameters.";
312  } else {
313  rdat = m_prdtool->runData(evi.run);
314  }
315  if ( msg.size() == 0 && ! rdat.isValid() ) {
316  msg = "WARNING: RunData not found. Using default parameters.";
317  }
318  if ( msg.size() ) {
319  cout << myname << msg << endl;
320  rdat.setGain(14.0);
321  rdat.setShaping(2.0);
322  }
323  for ( auto& itr : m_tfs ) {
324  ParFormula& form = *itr.second;
325  form.unsetParValues();
326  rdat.setFormulaPars(form);
327  if ( form.unsetPars().size() ) {
328  cout << "ERROR: Formula " << form.name() << " has unset parameters: [";
329  bool first = true;
330  for ( string spar : form.unsetPars() ) {
331  if ( first ) first = false;
332  else cout << ", ";
333  cout << spar;
334  }
335  cout << "]" << endl;
336  }
337  if ( form.resetPars().size() ) {
338  cout << "WARNING: Formula " << form.name() << " has reset parameters" << endl;
339  }
340  }
341  }
342  return res;
343 }
void msg(const char *fmt,...)
Definition: message.cpp:107
void setGain(float val)
Definition: RunData.h:67
virtual Names unsetPars() const =0
bool isValid() const
Definition: RunData.h:48
State & state() const
virtual RunData runData(Index run, Index subRun=0) const =0
virtual Names resetPars() const =0
virtual int unsetParValues()=0
virtual Name name() const
Definition: ParFormula.h:32
void setShaping(float val)
Definition: RunData.h:68
SetStat setFormulaPars(TFormula *form)
Definition: RunData.h:87
const RunDataTool * m_prdtool
QTextStream & endl(QTextStream &s)
int AdcPedestalFitter::fillChannelPad ( DataMap dm,
const AdcChannelData acd,
TPadManipulator pman 
) const
private

Definition at line 672 of file AdcPedestalFitter_tool.cc.

672  {
673  if ( pman == nullptr ) return 1;
674  TH1* phf = dm.getHist("pedestal");
675  pman->add(phf, "hist");
676  if ( m_PlotShowFit > 1 ) pman->addHistFun(1);
677  if ( m_PlotShowFit ) pman->addHistFun(0);
678  pman->addVerticalModLines(64);
679  pman->showUnderflow();
680  pman->showOverflow();
681  pman->addAxis();
682  Index istat = acd.channelStatus();
683  string sstat = istat == 0 ? "Good" : istat == 1 ? "Bad" : istat == 2 ? "Noisy" : "No-status";
684  NameVector slabs(3);
685  slabs[0] = sstat + " channel";
686  slabs[1] = "# skipped bins: " + std::to_string(dm.getInt("fitNSkip"));
687  slabs[2] = "# dropped bins: " + std::to_string(dm.getInt("fitNBinsRemoved"));
688  float xlab = 0.13;
689  float ylab = 0.86;
690  float dylab = 0.06;
691  for ( Name slab : slabs ) {
692  TLatex* ptxt = new TLatex(xlab, ylab, slab.c_str());
693  ptxt->SetNDC();
694  ptxt->SetTextFont(42);
695  pman->add(ptxt);
696  ylab -= dylab;
697  }
698  slabs.clear();
699  ostringstream sslab;
700  sslab << "Pedestal: " << std::fixed << std::setprecision(1) << dm.getFloat("fitPedestal");
701  slabs.push_back(sslab.str());
702  sslab.str("");
703  sslab << "Ped RMS: " << std::fixed << std::setprecision(1) << dm.getFloat("fitPedestalRms");
704  slabs.push_back(sslab.str());
705  sslab.str("");
706  //sslab << "Fit #chi^{2}: " << std::fixed << std::setprecision(1) << dm.getFloat("fitChiSquare");
707  //slabs.push_back(sslab.str());
708  //sslab.str("");
709  sslab << "#chi^{2}/DOF: " << std::fixed << std::setprecision(1) << dm.getFloat("fitReducedChiSquare");
710  slabs.push_back(sslab.str());
711  sslab.str("");
712  float frac = dm.getFloat("fitFractionLow");
713  int prec = frac > 0 ? int(-log10(frac)) + 3 : 0;
714  sslab << "f_{lo}: " << std::fixed << std::setprecision(prec) << frac;
715  slabs.push_back(sslab.str());
716  sslab.str("");
717  frac = dm.getFloat("fitFractionHigh");
718  prec = frac > 0 ? int(-log10(frac)) + 3 : 0;
719  sslab << "f_{hi}: " << std::fixed << std::setprecision(prec) << frac;
720  slabs.push_back(sslab.str());
721  xlab = 0.94;
722  ylab = 0.86;
723  for ( Name slab : slabs ) {
724  TLatex* ptxt = new TLatex(xlab, ylab, slab.c_str());
725  ptxt->SetNDC();
726  ptxt->SetTextFont(42);
727  ptxt->SetTextAlign(31);
728  pman->add(ptxt);
729  ylab -= dylab;
730  }
731  return 0;
732 }
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
ChannelGroupService::Name Name
unsigned int Index
int showOverflow(bool show=true)
Q_EXPORT QTSManip setprecision(int p)
Definition: qtextstream.h:343
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
int addVerticalModLines(double xmod, double xoff=0.0, double lenfrac=1.0, int isty=3)
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
Index channelStatus() const
int addHistFun(unsigned int ifun=0)
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
std::vector< string > NameVector
TH1 * getHist(Name name, TH1 *def=nullptr) const
Definition: DataMap.h:223
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
DataMap AdcPedestalFitter::getPedestal ( const AdcChannelData acd) const
private

Definition at line 358 of file AdcPedestalFitter_tool.cc.

358  {
359  const string myname = "AdcPedestalFitter::getPedestal: ";
360  DataMap res;
361  if ( m_LogLevel >= 2 ) cout << myname << "Fitting pedestal for channel " << acd.channel() << endl;
362  string hnameBase = m_HistName;
363  string htitlBase = m_HistTitle;
364  Index nsam = acd.raw.size();
365  if ( nsam == 0 ) {
366  if ( m_LogLevel >= 2 ) cout << myname << "WARNING: Raw data is empty." << endl;
367  return res.setStatus(1);
368  }
369  // If we need RunData parameters and Make sure that beginEvent has been called to
370  // evaluate formulas.
371  if ( m_haveFormulaParams && state().nevt == 0 ) {
372  cout << myname << "WARNING: Calling beginEvent to evaluate formulas." << endl;
373  beginEvent(acd.getEventInfo());
374  }
375  // Flag samples to keep in pedestal fit.
376  //return res;
377  vector<bool> keep(nsam, true);
378  Index nkeep = 0;
379  Index nskip = 0;
380  for ( Index isam=0; isam<nsam; ++isam ) {
381  if ( isam >= acd.flags.size() ) {
382  if ( m_LogLevel >= 2 ) cout << myname << "WARNING: flags are missing." << endl;
383  nkeep += nsam - isam; // 2021-04-30: Keep unflagged samples
384  break;
385  }
386  Index flg = acd.flags[isam];
387  if ( m_skipFlags.count(flg) ) {
388  keep[isam] = false;
389  ++nskip;
390  } else {
391  ++nkeep;
392  }
393  }
394  if ( nkeep == 0 ) {
395  if ( m_LogLevel >= 2 ) cout << myname << "WARNING: No raw data is selected." << endl;
396  return res.setStatus(2);
397  }
398  string hname = nameReplace(hnameBase, acd, false);
399  string htitl = nameReplace(htitlBase, acd, true);
400  htitl += "; ADC count; # samples";
401  Index adcRange = m_tfs.at("AdcRange")->eval();
402  if ( state().pfitter == nullptr || adcRange != state().adcRange ) {
403  cout << myname << "New ADC range is " << adcRange << endl;
404  state().pfitter = new TF1("pedgaus", "gaus", 0, adcRange, TF1::EAddToList::kNo);
405  }
406  state().adcRange = adcRange;
407  unsigned int nadc = adcRange;
408  unsigned int rebin = 10;
409  unsigned int nbin = (nadc + rebin - 0.01)/rebin;
410  double xmax = rebin*nbin;
411  string hnamr = hname + "_rebin";
412  TH1* phr = new TH1F(hnamr.c_str(), htitl.c_str(), nbin, 0, xmax);
413  phr->SetDirectory(0);
414  IndexVector rcounts(nbin, 0);
415  for ( Index isam=0; isam<nsam; ++isam ) {
416  if ( keep[isam] ) {
417  Index iadc = acd.raw[isam];
418  Index ibin = iadc/10;
419  if ( ibin >= nbin ) cout << myname << "ERROR: Too many ADC counts for channel " << acd.channel()
420  << " sample " << isam << ": " << iadc << endl;
421  else ++rcounts[ibin];
422  }
423  }
424  for ( Index ibin=0; ibin<nbin; ++ibin ) {
425  phr->SetBinContent(ibin+1, rcounts[ibin]);
426  }
427  double wadc = m_tfs.at("AdcFitRange")->eval();
428  if ( wadc < 10 ) {
429  cout << myname << "INFO: Invalid fit range: " << wadc << " < 10 ADC counts" << endl;
430  return res.setStatus(3);
431  }
432  if ( m_LogLevel >= 4 ) cout << myname << "INFO: Width = " << wadc << " ADC counts" << endl;
433  int rbinmax1 = phr->GetMaximumBin();
434  double adcmax = phr->GetBinCenter(rbinmax1);
435  double adc1 = adcmax - 0.5*wadc;
436  double adc2 = adc1 + wadc;
437  if ( m_RemoveStickyCode ) {
438  double radcmax1 = phr->GetBinCenter(rbinmax1);
439  double radcmean = phr->GetMean();
440  double radcsum1 = phr->Integral();
441  // Max may be due to a sticky code. Reduce it and find the next maximum.
442  double tmpval = 0.5*(phr->GetBinContent(rbinmax1-1)+phr->GetBinContent(rbinmax1+1));
443  phr->SetBinContent(rbinmax1, tmpval);
444  int rbinmax2 = phr->GetMaximumBin();
445  double radcsum2 = phr->Integral();
446  // Evaluate the histogram mean and peak position.
447  // If the peak removal has not removed too much data, these values are
448  // re-evaluated using the peak-removed histogram.
449  double adcmean = radcmean; // Mean position.
450  int rbinmax = rbinmax1; // Peak position.
451  if ( radcsum2 > 0.01*radcsum1 ) {
452  // Define the max to be the first value if the two maxima are close or the
453  // average if they are far part.
454  if ( abs(rbinmax2-rbinmax1) > 1 ) {
455  rbinmax = (rbinmax1 + rbinmax2)/2;
456  adcmean = phr->GetMean();
457  }
458  }
459  adcmax = phr->GetBinCenter(rbinmax);
460  // Make sure the peak bin stays in range.
461  if ( abs(adcmax-radcmax1) > 0.45*wadc ) adcmax = radcmax1;
462  adc1 = adcmax - 0.5*wadc;
463  adc1 = 10*int(adc1/10);
464  if ( adcmean > adcmax + 10) adc1 += 10;
465  adc2 = adc1 + wadc;
466  if ( radcmax1 < adc1 || radcmax1+1.0 > adc2 ) {
467  cout << myname << "WARNING: Histogram range (" << adc1 << ", " << adc2
468  << ") does not include peak at " << radcmax1 << "." << endl;
469  }
470  }
471  delete phr;
472  TH1* phf = new TH1F(hname.c_str(), htitl.c_str(), wadc, adc1, adc2);
473  phf->SetDirectory(0);
474  //phf->Sumw2();
475  Index countLo = 0;
476  Index countHi = 0;
477  Index count = 0;
478  IndexVector fcounts(wadc, 0);
479  for ( Index isam=0; isam<nsam; ++isam ) {
480  AdcIndex val = acd.raw[isam];
481  ++count;
482  if ( val < adc1 ) {
483  ++countLo;
484  } else if ( val >= adc2 ) {
485  ++countHi;
486  } else {
487  if ( keep[isam] ) ++fcounts[val-adc1];
488  }
489  }
490  for ( Index iadc=0; iadc<wadc; ++iadc ) {
491  phf->SetBinContent(iadc+1, fcounts[iadc]);
492  //float err = sqrt(fcounts[iadc]);
493  //if ( err <= 0.0 ) err = 1.0;
494  //phf->SetBinError(iadc+1, err);
495  }
496  float fracLo = count > 0 ? float(countLo)/count : 0.0;
497  float fracHi = count > 0 ? float(countHi)/count : 0.0;
498  phf->SetStats(0);
499  phf->SetLineWidth(2);
500  // Fetch the peak bin and suppress it for the fit if more than 20% (but not
501  // all) the data is in it.
502  // May 2021: We expect the peak bin to hold 20% of the samples if the RMS is near
503  // or below 2.0. Don't drop bin for low RMS and log a warning if bin is dropped
504  // and fit sigm < 2.5.
505  int binmax = phf->GetMaximumBin();
506  double valmax = phf->GetBinContent(binmax);
507  float peakFrac = valmax/phf->Integral();
508  double xcomax = phf->GetBinLowEdge(binmax);
509  double rangeIntegral = phf->Integral(1, phf->GetNbinsX());
510  double peakBinFraction = (rangeIntegral > 0) ? valmax/rangeIntegral : 1.0;
511  bool allBin = peakBinFraction > 0.99;
512  float rawRms = phf->GetRMS();
513  bool isNarrow = rawRms < 2.5;
514  bool dropBin = m_RemoveStickyCode && peakFrac > 0.2 && !allBin && !isNarrow;
515  int nbinsRemoved = 0;
516  if ( dropBin ) {
517  double tmpval = 0.5*(phf->GetBinContent(binmax-1)+phf->GetBinContent(binmax+1));
518  phf->SetBinContent(binmax, tmpval);
519  rangeIntegral = phf->Integral(1, phf->GetNbinsX());
520  ++nbinsRemoved;
521  }
522  double amean = phf->GetMean() + 0.5;
523  double arms = phf->GetRMS();
524  double fitRmsMin = m_tfs.at("FitRmsMin")->eval();
525  double fitRmsMax = m_tfs.at("FitRmsMax")->eval();
526  double ameanWin = fitRmsMax > fitRmsMin ? fitRmsMax : 0.0;
527  bool doFit = peakBinFraction < 0.99 && m_fitOpts.size() > 0;
528  float pedestal = phf->GetMean();
529  //float pedestalRms = 1.0/sqrt(12.0);
530  float pedestalRms = arms;
531  if ( fitRmsMax > fitRmsMin ) {
532  if ( arms < fitRmsMin ) arms = fitRmsMin;
533  if ( arms > fitRmsMax ) arms = fitRmsMax;
534  }
535  float fitChiSquare = 0.0;
536  float fitReducedChiSquare = 0.0;
537  float peakBinExcess = 0.0;
538  if ( doFit ) {
539  // Block Root info message for new Canvas produced in fit.
540  int levelSave = gErrorIgnoreLevel;
541  gErrorIgnoreLevel = 1001;
542  gErrorIgnoreLevel = 2001; // Block warning in Fit
543  // Block non-default (e.g. art) from handling the Root "error".
544  // We switch to the Root default handler while making the call to Print.
545  ErrorHandlerFunc_t pehSave = nullptr;
546  ErrorHandlerFunc_t pehDefault = DefaultErrorHandler;
547  //pehDefault = handleRootError;
548  if ( GetErrorHandler() != pehDefault ) {
549  pehSave = SetErrorHandler(pehDefault);
550  }
551  // Set fit precision. Least-squares only?
552  float fprec = TFitter::GetPrecision();
553  if ( m_FitPrecision > 0.0 ) TFitter::SetPrecision(m_FitPrecision);
554  int fitStat = 99;
555  TF1* pfinit = nullptr;
556  //TF1 fitter("pedgaus", "gaus", adc1, adc2, TF1::EAddToList::kNo);
557  TF1& fitter = *state().pfitter;
558  for ( Name fopt : m_fitOpts ) {
559  fitter.SetParameters(0.1*rangeIntegral, amean, pedestalRms);
560  fitter.SetParLimits(0, 0.01*rangeIntegral, rangeIntegral);
561  if ( ameanWin > 0.0 ) fitter.SetParLimits(1, amean - ameanWin, amean + ameanWin);
562  if ( allBin ) fitter.FixParameter(1, amean); // Fix posn.
563  if ( fitRmsMin < fitRmsMax ) {
564  fitter.SetParLimits(2, fitRmsMin, fitRmsMax);
565  }
566  fitter.SetParError(0, 0.0);
567  if ( m_PlotShowFit >= 2 ) {
568  pfinit = dynamic_cast<TF1*>(fitter.Clone("pedgaus0"));
569  pfinit->SetLineColor(3);
570  pfinit->SetLineStyle(2);
571  }
572  if ( m_LogLevel < 3 ) fopt += "Q";
573  // Root calls error handler but returns 0 if the histo has no data in range
574  // so we check that before calling fitter.
575  fitStat = (phf->Integral() == 0.0) ? 999 : int(phf->Fit(&fitter, fopt.c_str(), "", adc1, adc2));
576  //fopt += " S"; // So we can retrieve fit status
577  //TFitResultPtr pfres = phf->Fit(&fitter, fopt.c_str());
578  //bool haveFitStatus = pfres.Get();
579  //int fitStat = haveFitStatus ? pfres->Status() : 999;
580  if ( fitStat == 0 ) break;
581  }
582  if ( m_FitPrecision > 0.0 ) TFitter::SetPrecision(fprec);
583  if ( pehSave != nullptr ) SetErrorHandler(pehSave);
584  gErrorIgnoreLevel = levelSave;
585  if ( pfinit != nullptr ) {
586  phf->GetListOfFunctions()->AddLast(pfinit, "0");
587  phf->GetListOfFunctions()->Last()->SetBit(TF1::kNotDraw, true);
588  }
589  if ( fitStat ) {
590  Index istat = acd.channelStatus();
591  string sstat = istat == 0 ? "good" : istat == 1 ? "bad" : istat == 2 ? "noisy" : "unknown";
592  cout << myname << "WARNING: Fit status is " << fitStat << " for " << sstat << " channel "
593  << acd.channel() << endl;
594  cout << myname << " Errors[0]: " << fitter.GetParErrors()[0] << endl;
595  //cout << myname << " radcmax1 = " << radcmax1 << endl;
596  //cout << myname << " radcmean = " << radcmean << endl;
597  //cout << myname << " adcmean = " << adcmean << endl;
598  cout << myname << " adcmax = " << adcmax << endl;
599  //cout << myname << " rbinmax1,2: " << rbinmax1 << ", " << rbinmax2 << endl;
600  cout << myname << " peakBinFraction = " << valmax << "/" << rangeIntegral
601  << " = " << peakBinFraction << endl;
602  cout << myname << " allBin = " << allBin << endl;
603  cout << myname << " dropBin = " << dropBin << endl;
604  cout << myname << " amean = " << amean << " +/- " << ameanWin << endl;
605  } else {
606  double valEval = fitter.Eval(xcomax);
607  peakBinExcess = (valmax - valEval)/rangeIntegral;
608  pedestal = fitter.GetParameter(1) - 0.5;
609  pedestalRms = fitter.GetParameter(2);
610  // Chi-square from the fitter.
611  fitChiSquare = fitter.GetChisquare();
612  // Estimate of chi-square/DOF
613  float ibin1 = int(pedestal - 3.0*pedestalRms) - adc1;
614  if ( ibin1 < 1 ) ibin1 = 1;
615  float ibin2 = int(pedestal + 3.0*pedestalRms + 2.0) - adc1;
616  if ( ibin2 > wadc ) ibin2 = wadc;
617  int nbin = 0;
618  double sumsq = 0.0;
619  for ( int ibin=ibin1; ibin<=ibin2; ++ibin ) {
620  float xfun = adc1 + ibin - 0.5;
621  float yfun = fitter.Eval(xfun);
622  if ( yfun < 1.0 ) continue;
623  float yhst = phf->GetBinContent(ibin);
624  float dely = yhst - yfun;
625  float vary = yfun > 1.0 ? yfun : 1.0;
626  sumsq += dely*dely/vary;
627  ++nbin;
628  }
629  float estndof = nbin > 4 ? nbin - 3 : 1;
630  fitReducedChiSquare = sumsq/estndof;
631  // Warn if bin was dropped for a too-narrow distribution.
632  if ( dropBin && pedestalRms < 2.5 ) {
633  int precSave = cout.precision();
634  cout.precision(2);
635  cout << myname << "WARNING: Bin was dropped for channel " << acd.channel()
636  << " with fit sigma=" << fixed << pedestalRms
637  << ", raw RMS=" << fixed << rawRms
638  << " and peak fraction=" << fixed << peakFrac << endl;
639  cout.precision(precSave);
640  }
641  }
642  }
643  if ( dropBin ) phf->SetBinContent(binmax, valmax);
644  res.setHist("pedestal", phf, true);
645  res.setFloat("fitFractionLow", fracLo);
646  res.setFloat("fitFractionHigh", fracHi);
647  res.setFloat("fitPedestal", pedestal);
648  res.setFloat("fitPedestalRms", pedestalRms);
649  res.setFloat("fitChiSquare", fitChiSquare);
650  res.setFloat("fitPeakBinFraction", peakBinFraction);
651  res.setFloat("fitPeakBinExcess", peakBinExcess);
652  res.setFloat("fitChiSquare", fitChiSquare);
653  res.setFloat("fitReducedChiSquare", fitReducedChiSquare);
654  res.setInt("fitChannel", acd.channel());
655  res.setInt("fitNSkip", nskip);
656  res.setInt("fitNBinsRemoved", nbinsRemoved);
657  string rfname = nameReplace(m_RootFileName, acd, false);
658  if ( rfname.size() ) {
659  if ( m_LogLevel >=2 ) cout << myname << "Write histogram " << phf->GetName() << " to " << rfname << endl;
660  TFile* pf = TFile::Open(rfname.c_str(), "UPDATE");
661  TH1* phfCopy = (TH1*) phf->Clone();
662  phfCopy->GetListOfFunctions()->Clear();
663  phfCopy->Write();
664  delete pf;
665  }
666  if ( m_LogLevel >= 3 ) cout << myname << "Exiting..." << endl;
667  return res;
668 }
std::vector< Index > IndexVector
const DuneEventInfo & getEventInfo() const
void setFloat(Name name, float val)
Definition: DataMap.h:133
DataMap & setStatus(int stat)
Definition: DataMap.h:130
DataMap beginEvent(const DuneEventInfo &) const override
ChannelGroupService::Name Name
void setHist(Name name, TH1 *ph, bool own=false)
Definition: DataMap.h:136
unsigned int Index
Name nameReplace(Name name, const AdcChannelData &acd, bool isTitle) const
T abs(T value)
int precision() const
Definition: qtextstream.h:259
void setInt(Name name, int val)
Definition: DataMap.h:131
State & state() const
AdcCountVector raw
unsigned int AdcIndex
Definition: AdcTypes.h:15
Index channelStatus() const
Channel channel() const
def rebin(a, args)
Definition: arrays.py:2
QTextStream & endl(QTextStream &s)
AdcFlagVector flags
string AdcPedestalFitter::nameReplace ( Name  name,
const AdcChannelData acd,
bool  isTitle 
) const
private

Definition at line 348 of file AdcPedestalFitter_tool.cc.

348  {
350  if ( pnbl == nullptr ) return name;
351  DataMap dm;
352  return pnbl->build(acd, dm, name);
353 }
static QCString name
Definition: declinfo.cpp:673
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
const AdcChannelStringTool * m_adcStringBuilder
State& AdcPedestalFitter::state ( ) const
inlineprivate

Definition at line 172 of file AdcPedestalFitter.h.

172 { return *m_pstate; }
std::unique_ptr< State > m_pstate
DataMap AdcPedestalFitter::update ( AdcChannelData acd) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 197 of file AdcPedestalFitter_tool.cc.

197  {
198  const string myname = "AdcPedestalFitter::update: ";
199  DataMap res = view(acd);
200  if ( res.status() != 0 ) return res;
201  if ( m_LogLevel >= 3 ) cout << myname << "Old pedestal: " << acd.pedestal << endl;
202  acd.pedestal = res.getFloat("fitPedestal");
203  acd.pedestalRms = res.getFloat("fitPedestalRms");
204  copyMetadata(res, acd);
205  if ( m_LogLevel >= 3 ) cout << myname << "New pedestal: " << acd.pedestal << endl;
206  return res;
207 }
int status() const
Definition: DataMap.h:202
AdcSignal pedestalRms
DataMap view(const AdcChannelData &acd) const override
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
AdcSignal pedestal
QTextStream & endl(QTextStream &s)
DataMap AdcPedestalFitter::updateMap ( AdcChannelDataMap acds) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 211 of file AdcPedestalFitter_tool.cc.

211  {
212  const string myname = "AdcPedestalFitter::updateMap: ";
213  DataMap ret;
214  Index nPedFitGood = 0;
215  Index nPedFitFail = 0;
216  if ( m_LogLevel >= 2 ) cout << myname << "Fitting " << acds.size() << " channels." << endl;
217  Index npad = 0;
218  Index npadx = 0;
219  Index npady = 0;
220  bool doPlot = m_PlotFileName.size() && m_PlotSplitX > 0;
221  if ( doPlot ) {
222  npadx = m_PlotSplitX;
224  npad = npadx*npady;
225  }
226  if ( m_LogLevel >= 2 ) {
227  cout << myname << "Pad count is " << npad << " (" << npady << " x " << npadx << ")" << endl;
228  }
229  TPadManipulator* pmantop = nullptr;
230  // Loop over channels.
231  Index nacd = acds.size();
232  Index iacd = 0;
233  vector<int> fitStats(nacd, 999);
234  vector<float> fitPedestals(nacd, 0.0);
235  vector<float> fitPedestalRmss(nacd, 0.0);
236  string plotFileName = "";
237  for ( auto& acdPair : acds ) {
238  const AdcChannelData& acd = acdPair.second;
239  AdcChannelData& acdMutable = acdPair.second;
240  if ( m_LogLevel >= 3 ) cout << myname << " " << iacd << ": Processing channel " << acd.channel() << endl;
241  // If needed, create a new canvas.
242  if ( npad > 0 && pmantop == nullptr ) {
243  if ( m_LogLevel >= 3 ) cout << myname << " Creating canvas." << endl;
244  pmantop = new TPadManipulator;
246  if ( npad > 1 ) pmantop->split(npady, npady);
247  plotFileName = nameReplace(m_PlotFileName, acd, false);
248  }
249  Index ipad = npad == 0 ? 0 : iacd % npad;
250  TPadManipulator* pman = pmantop == nullptr ? nullptr : pmantop->man(ipad);
251  DataMap tmpres = getPedestal(acd);
252  fillChannelPad(tmpres, acd, pman);
253  fitStats[iacd] = tmpres.status();
254  float fitPedestal = 0.0;
255  float fitPedestalRms = 0.0;
256  if ( tmpres.status() == 0 ) {
257  ++nPedFitGood;
258  fitPedestal = tmpres.getFloat("fitPedestal");
259  fitPedestalRms = tmpres.getFloat("fitPedestalRms");
260  copyMetadata(tmpres, acdMutable);
261  } else {
262  ++nPedFitFail;
263  }
264  fitPedestals[iacd] = fitPedestal;
265  fitPedestalRmss[iacd] = fitPedestalRms;
266  // If needed, print and delete the canvas.
267  ++iacd;
268  bool lastpad = (++ipad == npad) || (iacd == nacd);
269  if ( lastpad && pmantop != nullptr ) {
270  if ( m_LogLevel >= 3 ) cout << myname << " Creating plot " << plotFileName << endl;
271  pmantop->print(plotFileName);
272  delete pmantop;
273  pmantop = nullptr;
274  }
275  }
276  iacd = 0;
277  for ( auto& acdPair : acds ) {
278  AdcChannelData& acd = acdPair.second;
279  acd.pedestal = fitPedestals[iacd];
280  acd.pedestalRms = fitPedestalRmss[iacd];
281  ++iacd;
282  }
283  if ( m_LogLevel >= 2 ) {
284  cout << myname << " # good pedestal fits: " << nPedFitGood << endl;
285  cout << myname << " # fail pedestal fits: " << nPedFitFail << endl;
286  }
287  ret.setInt("nPedFitGood", nPedFitGood);
288  ret.setInt("nPedFitFail", nPedFitFail);
289  ret.setIntVector("fitStats", fitStats);
290  ret.setIntVector("fitStats", fitStats);
291  ret.setFloatVector("fitPedestals", fitPedestals);
292  ret.setFloatVector("fitPedestalRmss", fitPedestalRmss);
293  return ret;
294 }
int fillChannelPad(DataMap &dm, const AdcChannelData &acd, TPadManipulator *pman) const
int setCanvasSize(int wx, int wy)
int split(Index nx, Index ny)
DataMap getPedestal(const AdcChannelData &acd) const
unsigned int Index
int status() const
Definition: DataMap.h:202
void setIntVector(Name name, const IntVector &val)
Definition: DataMap.h:132
Name nameReplace(Name name, const AdcChannelData &acd, bool isTitle) const
AdcSignal pedestalRms
void setInt(Name name, int val)
Definition: DataMap.h:131
TPadManipulator * man(unsigned int ipad=0)
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
Channel channel() const
AdcSignal pedestal
void setFloatVector(Name name, const FloatVector &val)
Definition: DataMap.h:134
int print(std::string fname, std::string spat="{,}")
QTextStream & endl(QTextStream &s)
DataMap AdcPedestalFitter::view ( const AdcChannelData acd) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 173 of file AdcPedestalFitter_tool.cc.

173  {
174  const string myname = "AdcPedestalFitter::view: ";
175  if ( m_LogLevel >= 3 ) cout << myname << "Calling " << endl;
176  TPadManipulator* pman = nullptr;
177  if ( m_PlotFileName.size() ) {
178  pman = new TPadManipulator;
180  }
181  DataMap res = getPedestal(acd);
182  fillChannelPad(res, acd, pman);
183  if ( pman != nullptr ) {
184  string pfname = nameReplace(m_PlotFileName, acd, false);
185  if ( m_LogLevel >= 3 ) cout << myname << "Creating plot " << pfname << endl;
186  pman->print(pfname);
187  delete pman;
188  }
189  if ( m_LogLevel >= 3 ) cout << myname << "Called " << endl;
190  //TH1* phped = res.getHist("pedestal");
191  //if ( res.haveHist("pedestal") ) res.setHist("pedestal", phped, true);
192  return res;
193 }
int fillChannelPad(DataMap &dm, const AdcChannelData &acd, TPadManipulator *pman) const
int setCanvasSize(int wx, int wy)
DataMap getPedestal(const AdcChannelData &acd) const
Name nameReplace(Name name, const AdcChannelData &acd, bool isTitle) const
int print(std::string fname, std::string spat="{,}")
QTextStream & endl(QTextStream &s)

Member Data Documentation

Name AdcPedestalFitter::m_AdcFitRange
private

Definition at line 136 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_AdcRange
private

Definition at line 132 of file AdcPedestalFitter.h.

const AdcChannelStringTool* AdcPedestalFitter::m_adcStringBuilder
private

Definition at line 151 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_FitOpt
private

Definition at line 133 of file AdcPedestalFitter.h.

NameVector AdcPedestalFitter::m_fitOpts
private

Definition at line 155 of file AdcPedestalFitter.h.

float AdcPedestalFitter::m_FitPrecision
private

Definition at line 134 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_FitRmsMax
private

Definition at line 138 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_FitRmsMin
private

Definition at line 137 of file AdcPedestalFitter.h.

bool AdcPedestalFitter::m_haveFormulaParams
private

Definition at line 158 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_HistName
private

Definition at line 140 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_HistTitle
private

Definition at line 141 of file AdcPedestalFitter.h.

int AdcPedestalFitter::m_LogLevel
private

Definition at line 131 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_PlotFileName
private

Definition at line 142 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_PlotShowFit
private

Definition at line 146 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_PlotSizeX
private

Definition at line 144 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_PlotSizeY
private

Definition at line 145 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_PlotSplitX
private

Definition at line 147 of file AdcPedestalFitter.h.

Index AdcPedestalFitter::m_PlotSplitY
private

Definition at line 148 of file AdcPedestalFitter.h.

const RunDataTool* AdcPedestalFitter::m_prdtool
private

Definition at line 159 of file AdcPedestalFitter.h.

std::unique_ptr<State> AdcPedestalFitter::m_pstate
private

Definition at line 171 of file AdcPedestalFitter.h.

bool AdcPedestalFitter::m_RemoveStickyCode
private

Definition at line 139 of file AdcPedestalFitter.h.

Name AdcPedestalFitter::m_RootFileName
private

Definition at line 143 of file AdcPedestalFitter.h.

IndexVector AdcPedestalFitter::m_SkipFlags
private

Definition at line 135 of file AdcPedestalFitter.h.

IndexSet AdcPedestalFitter::m_skipFlags
private

Definition at line 154 of file AdcPedestalFitter.h.

NameSetMap AdcPedestalFitter::m_tfpars
private

Definition at line 157 of file AdcPedestalFitter.h.

FormulaMap AdcPedestalFitter::m_tfs
private

Definition at line 156 of file AdcPedestalFitter.h.


The documentation for this class was generated from the following files: