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

#include <AdcRoiViewer.h>

Inheritance diagram for AdcRoiViewer:
TpcDataTool

Classes

class  HistInfo
 
class  State
 

Public Types

using Index = unsigned int
 
using IndexVector = std::vector< Index >
 
using Name = std::string
 
using NameVector = std::vector< Name >
 
using HistVector = std::vector< TH1 * >
 
using HistMap = std::map< Name, TH1 * >
 
using HistVectorMap = std::map< Name, HistVector >
 
using NameMap = std::map< Name, Name >
 
using NameVectorMap = std::map< Name, NameVector >
 
using ChannelRange = IndexRange
 
using ChannelRangeMap = std::map< Name, ChannelRange >
 
using FloatMap = std::map< Name, float >
 
using IndexByIndexMap = std::map< Index, Index >
 
using IndexByNameMap = std::map< Name, Index >
 
using TpmPtr = std::unique_ptr< TPadManipulator >
 
using TpmMap = std::map< Index, TpmPtr >
 
using TpmNameMap = std::map< Index, Name >
 
using TpmCountMap = std::map< Index, Index >
 
using HistInfoMap = std::map< Name, HistInfo >
 
using StatePtr = std::shared_ptr< State >
 
using DataMapVector = std::vector< DataMap >
 

Public Member Functions

 AdcRoiViewer (fhicl::ParameterSet const &ps)
 
 ~AdcRoiViewer () override
 
DataMap view (const AdcChannelData &acd) const override
 
DataMap viewMap (const AdcChannelDataMap &acds) const override
 
bool updateWithView () const override
 
DataMap close (const DataMap *dmin) override
 
int doView (const AdcChannelData &acd, int dbg, DataMap &dm) const
 
void writeRoiHists (const DataMap &res, int dbg) const
 
void writeRoiHists (const DataMapVector &res, int dbg) const
 
void writeRoiPlots (const HistVector &hists, const AdcChannelData &acd) const
 
StategetState () const
 
void fillSumHists (const AdcChannelData &acd, const DataMap &dm) const
 
void fitSumHists () const
 
void fillChanSumHists () const
 
void writeSumHists () const
 
void writeSumPlots (const DataMap *pdmin) const
 
void writeChanSumHists () const
 
void writeChanSumPlots () const
 
void setPlotLabels (Name &sttl) const
 

Private Attributes

int m_LogLevel
 
float m_SigThresh
 
Index m_TickBorder
 
int m_RoiHistOpt
 
int m_FitOpt
 
Index m_RoiPlotOpt
 
int m_MaxRoiPlots
 
Index m_RoiPlotPadX
 
Index m_RoiPlotPadY
 
time_t m_StartTime
 
float m_PulserStepCharge
 
float m_PulserDacOffset
 
Name m_PulserChargeUnit
 
bool m_SumNegate
 
Index m_SumPlotPadX
 
Index m_SumPlotPadY
 
Index m_ChannelLineModulus
 
IndexVector m_ChannelLinePattern
 
Name m_RunDataTool
 
Name m_TickOffsetTool
 
Name m_ChannelRangeTool ="channelRanges"
 
Name m_RoiRootFileName
 
Name m_SumRootFileName
 
Name m_ChanSumRootFileName
 
NameVector m_ChannelRanges
 
NameVector m_PlotLabels
 
ChannelRangeMap m_crmap
 
NameMap m_plotLabelSubs
 
StatePtr m_state
 
const AdcChannelStringToolm_adcStringBuilder =nullptr
 
const RunDataToolm_pRunDataTool =nullptr
 
const TimeOffsetToolm_pTickOffsetTool =nullptr
 
const IndexRangeToolm_pChannelRangeTool =nullptr
 

Additional Inherited Members

- Private Types inherited from AdcChannelTool
using Index = unsigned int
 
- Private Member Functions inherited from TpcDataTool
virtual DataMap updateTpcData (TpcData &) const
 
virtual DataMap viewTpcData (const TpcData &) const
 
virtual int forwardTpcData () const
 
- Private Member Functions inherited from AdcChannelTool
virtual ~AdcChannelTool ()=default
 
virtual DataMap update (AdcChannelData &) const
 
virtual DataMap updateMap (AdcChannelDataMap &acds) const
 
virtual bool viewWithUpdate () const
 
virtual DataMap beginEvent (const DuneEventInfo &) const
 
virtual DataMap endEvent (const DuneEventInfo &) const
 
- Static Private Member Functions inherited from AdcChannelTool
static int interfaceNotImplemented ()
 

Detailed Description

Definition at line 185 of file AdcRoiViewer.h.

Member Typedef Documentation

Definition at line 198 of file AdcRoiViewer.h.

Definition at line 199 of file AdcRoiViewer.h.

Definition at line 292 of file AdcRoiViewer.h.

using AdcRoiViewer::FloatMap = std::map<Name, float>

Definition at line 200 of file AdcRoiViewer.h.

Definition at line 220 of file AdcRoiViewer.h.

using AdcRoiViewer::HistMap = std::map<Name, TH1*>

Definition at line 194 of file AdcRoiViewer.h.

Definition at line 193 of file AdcRoiViewer.h.

Definition at line 195 of file AdcRoiViewer.h.

using AdcRoiViewer::Index = unsigned int

Definition at line 189 of file AdcRoiViewer.h.

Definition at line 201 of file AdcRoiViewer.h.

Definition at line 202 of file AdcRoiViewer.h.

Definition at line 190 of file AdcRoiViewer.h.

Definition at line 191 of file AdcRoiViewer.h.

using AdcRoiViewer::NameMap = std::map<Name, Name>

Definition at line 196 of file AdcRoiViewer.h.

Definition at line 192 of file AdcRoiViewer.h.

Definition at line 197 of file AdcRoiViewer.h.

using AdcRoiViewer::StatePtr = std::shared_ptr<State>

Definition at line 277 of file AdcRoiViewer.h.

Definition at line 206 of file AdcRoiViewer.h.

using AdcRoiViewer::TpmMap = std::map<Index, TpmPtr>

Definition at line 204 of file AdcRoiViewer.h.

using AdcRoiViewer::TpmNameMap = std::map<Index, Name>

Definition at line 205 of file AdcRoiViewer.h.

using AdcRoiViewer::TpmPtr = std::unique_ptr<TPadManipulator>

Definition at line 203 of file AdcRoiViewer.h.

Constructor & Destructor Documentation

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

Definition at line 169 of file AdcRoiViewer_tool.cc.

170 : m_LogLevel(ps.get<int>("LogLevel")),
171  m_SigThresh(ps.get<float>("SigThresh")),
172  m_TickBorder(ps.get<Index>("TickBorder")),
173  m_RoiHistOpt(ps.get<int>("RoiHistOpt")),
174  m_FitOpt(ps.get<int>("FitOpt")),
175  m_RoiPlotOpt(ps.get<Index>("RoiPlotOpt")),
176  m_MaxRoiPlots(ps.get<int>("MaxRoiPlots")),
177  m_RoiPlotPadX(ps.get<Index>("RoiPlotPadX")),
178  m_RoiPlotPadY(ps.get<Index>("RoiPlotPadY")),
179  m_StartTime(ps.get<time_t>("StartTime")),
180  m_PulserStepCharge(ps.get<float>("PulserStepCharge")),
181  m_PulserDacOffset(ps.get<float>("PulserDacOffset")),
182  m_PulserChargeUnit(ps.get<string>("PulserChargeUnit")),
183  m_SumNegate(ps.get<bool>("SumNegate")),
184  m_SumPlotPadX(ps.get<Index>("SumPlotPadX")),
185  m_SumPlotPadY(ps.get<Index>("SumPlotPadY")),
186  m_ChannelLineModulus(ps.get<Index>("ChannelLineModulus")),
187  m_ChannelLinePattern(ps.get<IndexVector>("ChannelLinePattern")),
188  m_RunDataTool(ps.get<string>("RunDataTool")),
189  m_TickOffsetTool(ps.get<string>("TickOffsetTool")),
190  m_RoiRootFileName(ps.get<string>("RoiRootFileName")),
191  m_SumRootFileName(ps.get<string>("SumRootFileName")),
192  m_ChanSumRootFileName(ps.get<string>("ChanSumRootFileName")),
193  m_ChannelRanges(ps.get<NameVector>("ChannelRanges")),
194  m_PlotLabels(ps.get<NameVector>("PlotLabels")),
196 {
197  const string myname = "AdcRoiViewer::ctor: ";
198  if ( m_LogLevel >=2 ) cout << myname << "Begin constructing tool." << endl;
199  string stringBuilder = "adcStringBuilder";
201  m_adcStringBuilder = ptm->getShared<AdcChannelStringTool>(stringBuilder);
202  if ( m_adcStringBuilder == nullptr ) {
203  cout << myname << "WARNING: AdcChannelStringTool not found: " << stringBuilder << endl;
204  }
205  if ( m_RunDataTool.size() ) {
207  if ( m_pRunDataTool == nullptr ) {
208  cout << myname << "WARNING: RunDataTool not found: " << m_RunDataTool << endl;
209  } else {
210  cout << myname << "Found run data tool." << endl;
211  }
212  }
213  if ( m_TickOffsetTool.size() ) {
215  if ( m_pTickOffsetTool == nullptr ) {
216  cout << myname << "WARNING: Tick offset tool not found: " << m_TickOffsetTool << endl;
217  } else {
218  cout << myname << "Found tick offset tool." << endl;
219  }
220  }
221  if ( m_ChannelRangeTool.size() ) {
223  if ( m_pChannelRangeTool == nullptr ) {
224  cout << myname << "WARNING: Index range tool not found: " << m_ChannelRangeTool << endl;
225  } else {
226  cout << myname << "Found channel range tool." << endl;
227  }
228  }
229  // Build the label substitutions.
230  for ( Index ilab=0; ilab<m_PlotLabels.size(); ++ilab ) {
231  Name stxt = "%LAB" + to_string(ilab) + "%";
232  m_plotLabelSubs[stxt] = m_PlotLabels[ilab];
233  }
234  // Build the summary template histograms.
235  // The summary histogram for each channel is created the first time it is encountered in th data.
236  ParameterSetVector pshists = ps.get<ParameterSetVector>("SumHists");
237  string stimepre = "Time since " + timeString(m_StartTime) + " ";
238  for ( const ParameterSet& psh : pshists ) {
239  Name hvarx = psh.get<Name>("var");
240  Name hvary;
241  if ( hvarx == "timingPhase_fitToffPulserMod10" ) {
242  hvarx = "fitToffPulserMod10";
243  hvary = "timingPhase";
244  }
245  if ( hvarx == "event_fitToffPulser" ) {
246  hvarx = "fitToffPulser";
247  hvary = "event";
248  }
249  Name hnam = psh.get<Name>("name");
250  setPlotLabels(hnam);
251  Name httl = psh.get<Name>("title");
252  setPlotLabels(httl);
253  if ( getState().sumHistTemplates.find(hnam) != getState().sumHistTemplates.end() ) {
254  cout << myname << "ERROR: Duplicate summary template name: " << hnam << endl;
255  continue;
256  }
257  int nbin = psh.get<int>("nbin");
258  float xmin = psh.get<float>("xmin");
259  float xmax = psh.get<float>("xmax");
260  Name sfit;
261  psh.get_if_present("fit", sfit);
262  Name plotName;
263  psh.get_if_present("plot", plotName);
264  float plotWidth = 0.0;
265  psh.get_if_present("pwid", plotWidth);
266  Name xlab = hvarx;
267  if ( hvarx == "fitHeight" ) xlab = "Fit height% [SUNIT]%";
268  else if ( hvarx == "fitHeightNeg" ) xlab = "-(Fit height)% [SUNIT]%";
269  else if ( hvarx == "fitHeightGain" ) {
270  xlab = "Fit height gain% [SUNIT]%";
271  Name sden = m_PulserChargeUnit;
272  if ( sden.size() ) {
273  if ( sden.find(" ") != string::npos ) sden = "(" + sden + ")";
274  xlab = "Fit height gain [%((SUNIT))%/" + sden + "]";
275  }
276  }
277  else if ( hvarx == "fitWidth" ) xlab = "Fit width [Tick]";
278  else if ( hvarx == "fitPos" ) xlab = "Fit position [Tick]";
279  else if ( hvarx == "fitPosRem" ) xlab = "Fit position tick remainder [Tick]";
280  else if ( hvarx == "fitPosPulser" )
281  xlab = "Fit position wrt pulser [Tick]";
282  else if ( hvarx == "fitToffPulser" )
283  xlab = "Offset fit position wrt pulser [Tick]";
284  else if ( hvarx == "fitToffPulserMod10" )
285  xlab = "mod_{10}(offset fit position wrt pulser) [Tick]";
286  else if ( hvarx == "fitChiSquare" ) xlab = "Fit #chi^{2}";
287  else if ( hvarx == "fitChiSquareDof" ) xlab = "Fit #chi^{2}/DOF";
288  else if ( hvarx == "fitCSNorm" ) xlab = "Normalized fit #chi^{2}";
289  else if ( hvarx == "fitCSNormDof" ) xlab = "Normalized fit #chi^{2}/DOF";
290  else if ( hvarx == "sigArea" ) xlab = "Area [%ASUNIT%]";
291  else if ( hvarx == "sigAreaNeg" ) xlab = "-Area [%ASUNIT%]";
292  else if ( hvarx == "sigWidth" ) xlab = "Width [Tick]";
293  else if ( hvarx == "timeSec" || hvarx == "procTimeSec" ) xlab = stimepre + " [sec]";
294  else if ( hvarx == "timeHour" || hvarx == "procTimeHour") xlab = stimepre + " [hour]";
295  else if ( hvarx == "timeDay" || hvarx == "procTimeDay" ) xlab = stimepre + " [day]";
296  else {
297  cout << myname << "WARNING: Unknown summary variable: " << hvarx << endl;
298  }
299  Name ylab;
300  if ( hvary.size() ) {
301  if ( hvary == "timingPhase" ) ylab = "Timing phase [Tick]";
302  if ( hvary == "event" ) ylab = "Event";
303  }
304  TH1* ph = nullptr;
305  if ( hvary == "" ) {
306  ph = new TH1F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax);
307  ph->GetYaxis()->SetTitle("# ROI");
308  ph->Sumw2(); // Needed for likelihood fit
309  } else {
310  int nbiny = psh.get<int>("nbiny");
311  float ymin = psh.get<float>("ymin");
312  float ymax = psh.get<float>("ymax");
313  ph = new TH2F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax, nbiny, ymin, ymax);
314  ph->GetYaxis()->SetTitle(ylab.c_str());
315  }
316  ph->SetDirectory(nullptr);
317  ph->SetLineWidth(2);
318  ph->GetXaxis()->SetTitle(xlab.c_str());
319  // Add fit to template so it will be used for each child histogram.
320  //if ( sfit.size() ) {
321  // if ( m_LogLevel >= 1 ) cout << myname << "Adding fitter " << sfit
322  // << " to hist template " << hnam << endl;
323  // TF1* pf = new TF1(sfit.c_str(), sfit.c_str());
324  // ph->GetListOfFunctions()->AddLast(pf);
325  // ph->GetListOfFunctions()->SetOwner(kTRUE);
326  //}
327  HistInfo& hin = getState().sumHistTemplates[hnam];
328  hin.ph = ph;
329  hin.varx = hvarx;
330  hin.vary = hvary;
331  hin.plotName = plotName;
332  hin.plotWidth = plotWidth;
333  hin.fitName = sfit;
334  }
335  // Build the channel summary histograms.
336  ParameterSetVector pcshists = ps.get<ParameterSetVector>("ChanSumHists");
337  for ( const ParameterSet& psh : pcshists ) {
338  Name hnam0 = psh.get<Name>("name"); // Name for this histogram
339  Name httl0 = psh.get<Name>("title"); // Title for this histogram
340  Name vhnam = psh.get<Name>("valHist"); // Name of the template for the histogram used to fill
341  Name valType = psh.get<Name>("valType"); // Type of variable extracted from histogram
342  Name etype = psh.get<Name>("errType"); // Type of variable extracted from histogram
343  Name crname0 = psh.get<Name>("cr"); // Name of the channel range for this histogram
344  Name plname = psh.get<Name>("plot"); // Name of the plot file for this histogram
345  Name spran = psh.get<Name>("pran"); // Plot range with format "ymin:ymax"
346  Index nbins = psh.get<Index>("nbins"); // # bins for #ROI vs var plot. 0 means var vs chan plot.;
347  if ( hnam0.size() == 0 ) {
348  cout << myname << "ERROR: Channel summary histogram name is missing." << endl;
349  continue;
350  }
351  if ( m_pChannelRangeTool == nullptr ) {
352  cout << myname << "ERROR: Channel range tool not found." << endl;
353  continue;
354  }
356  if ( ivh == getState().sumHistTemplates.end() || ivh->second.ph == nullptr ) {
357  cout << myname << "ERROR: Channel summary histogram value histogram not found: " << vhnam << endl;
358  continue;
359  }
360  const NameVector valTypes = {"entries", "count", "mean", "peak", "rms", "sum", "fitMean", "fitSigma"};
361  if ( std::find(valTypes.begin(), valTypes.end(), valType) == valTypes.end() ) {
362  cout << myname << "ERROR: Channel summary histogram has invalid variable type: " << valType << endl;
363  continue;
364  }
365  const NameVector errTypes = {"none", "zero", "rms", "meanError", "rmsError", "fitSigma"};
366  if ( std::find(errTypes.begin(), errTypes.end(), etype) == errTypes.end() ) {
367  cout << myname << "ERROR: Channel summary histogram has invalid error type: \"" << etype << '"' << endl;
368  continue;
369  }
370  TH1* phval = ivh->second.ph;
371  Name valLabel = phval->GetXaxis()->GetTitle();
372  Name yttl = "Unknown";
373  if ( valType == "mean" ) {
374  yttl = "Mean of " + valLabel;
375  } else if ( valType == "peak" ) {
376  yttl = "Peak of " + valLabel;
377  } else if ( valType == "rms" ) {
378  yttl = "Sum of " + valLabel;
379  } else if ( valType == "rms" ) {
380  yttl = "RMS of " + valLabel;
381  } else if ( valType == "fitMean" ) {
382  yttl = "Fit mean of " + valLabel;
383  } else if ( valType == "fitSigma" ) {
384  yttl = "Fit sigma of " + valLabel;
385  } else if ( valType == "entries" ) {
386  yttl = "# ROI";
387  } else if ( valType == "count" ) {
388  yttl = "# ROI";
389  }
390  // Find y-range for plot.
391  bool havePlotYMin = false;
392  bool havePlotYMax = false;
393  float plotYMin = 0;
394  float plotYMax = 0;
395  Name plotYOpt;
396  if ( spran.size() ) {
397  Name::size_type ipos = spran.find(":");
398  if ( ipos == Name::npos ) {
399  cout << myname << "WARNING: Channel summary range specifcation must include \":\"" << endl;
400  } else {
401  Name::size_type jpos = spran.find(":", ipos+1);
402  Name spmin = spran.substr(0, ipos);
403  if ( spmin.size() ) {
404  istringstream ssin(spmin);
405  ssin >> plotYMin;
406  havePlotYMin = true;
407  }
408  Name spmax = spran.substr(ipos+1, jpos-ipos);
409  if ( spmax.size() ) {
410  istringstream ssin(spmax);
411  ssin >> plotYMax;
412  havePlotYMax = true;
413  }
414  if ( jpos != Name::npos ) {
415  plotYOpt = spran.substr(jpos+1);
416  }
417  }
418  }
419  // Loop over channel ranges. Value "list" means all; otherwise just the one given.
420  NameVector crns;
421  if ( crname0 == "list" ) crns = m_ChannelRanges;
422  else crns.push_back(crname0);
423  if ( crns.size() == 0 ) crns.push_back("all");
424  for ( Name crname : crns ) {
425  if ( m_LogLevel >= 2 ) cout << myname << "Creating channel summary histograms for channel range "
426  << crname << endl;
428  if ( ! cr.isValid() ) {
429  cout << myname << "ERROR: Channel range " << crname << " not found." << endl;
430  continue;
431  }
432  StringManipulator smhnam(hnam0, false);
433  smhnam.replace("%CRNAME%", cr.name);
434  smhnam.replace("%CRLABEL%", cr.label());
435  smhnam.replace("%CRLABEL1%", cr.label(1));
436  smhnam.replace("%CRLABEL2%", cr.label(2));
437  Name hnam = smhnam.str();
438  if ( getState().chanSumHists.find(hnam) != getState().chanSumHists.end() ) {
439  cout << myname << "ERROR: Duplicate channel summary histogram name: " << hnam << endl;
440  continue;
441  }
442  setPlotLabels(hnam);
443  StringManipulator smttl(httl0, false);
444  smttl.replace("%CRNAME%", cr.name);
445  smttl.replace("%CRLABEL%", cr.label());
446  smttl.replace("%CRLABEL1%", cr.label(1));
447  smttl.replace("%CRLABEL2%", cr.label(2));
448  Name httl = smttl.str();
449  setPlotLabels(httl);
450  TH1* phf = nullptr;
451  if ( nbins == 0 ) {
452  phf = new TH1F(hnam.c_str(), httl.c_str(), cr.size(), cr.begin, cr.end);
453  phf->GetXaxis()->SetTitle("Channel");
454  phf->GetYaxis()->SetTitle(yttl.c_str());
455  } else {
456  phf = new TH1F(hnam.c_str(), httl.c_str(), nbins, plotYMin, plotYMax);
457  phf->GetXaxis()->SetTitle(yttl.c_str());
458  phf->GetYaxis()->SetTitle("# channels");
459  phf->SetLineWidth(2);
460  }
461  phf->SetDirectory(nullptr);
462  phf->SetStats(0);
463  if ( cr.size() < 400 ) phf->SetLineWidth(2);
464  if ( etype == "none" ) phf->SetMarkerStyle(2);
465  else phf->SetMarkerStyle(0); // Draw error bars instead of markers
466  StringManipulator smplt(plname, false);
467  smplt.replace("%HNAME%", hnam0);
468  smplt.replace("%CRNAME%", cr.name);
469  smplt.replace("%CRLABEL%", cr.label());
470  smplt.replace("%CRLABEL1%", cr.label(1));
471  smplt.replace("%CRLABEL2%", cr.label(2));
472  plname = smplt.str();
473  setPlotLabels(plname);
474  getState().chanSumHists[hnam] = phf;
475  getState().chanSumHistTemplateNames[hnam] = vhnam;
476  getState().chanSumHistTypes[hnam] = nbins > 0;
477  getState().chanSumHistVariableTypes[hnam] = valType;
478  getState().chanSumHistErrorTypes[hnam] = etype;
479  getState().chanSumPlotNames[hnam] = plname;
480  if ( havePlotYMin ) getState().chanSumPlotYMins[hnam] = plotYMin;
481  if ( havePlotYMax ) getState().chanSumPlotYMaxs[hnam] = plotYMax;
482  if ( havePlotYMin || havePlotYMax ) getState().chanSumPlotYOpts[hnam] = plotYOpt;
483  getState().chanSumChaBegin[hnam] = cr.begin;
484  getState().chanSumChaEnd[hnam] = cr.end;
485  if ( m_LogLevel >= 3 ) {
486  cout << myname << " Histogram name: " << hnam << endl;
487  cout << myname << " Value type: " << valType << endl;
488  cout << myname << " Error type: " << etype << endl;
489  cout << myname << " Histogram name: " << hnam << endl;
490  cout << myname << " Histogram name: " << hnam << endl;
491  cout << myname << " Plot name: " << plname << endl;
492  cout << myname << " Plot ymin: ";
493  if ( havePlotYMin ) cout << plotYMin;
494  cout << endl;
495  cout << myname << " Plot ymax: ";
496  if ( havePlotYMax ) cout << plotYMax;
497  cout << endl;
498  cout << " Plot yopt: " << plotYOpt << endl;
499  }
500  } // End loop over channel ranges
501  } // End loop over channel summmary histogram configurations
502  // Display the configuration.
503  if ( m_LogLevel>= 1 ) {
504  cout << myname << " LogLevel: " << m_LogLevel << endl;
505  cout << myname << " RoiHistOpt: " << m_RoiHistOpt << endl;
506  cout << myname << " SigThresh: " << m_SigThresh << endl;
507  cout << myname << " TickBorder: " << m_TickBorder << endl;
508  cout << myname << " FitOpt: " << m_FitOpt << endl;
509  cout << myname << " StartTime: " << m_StartTime
510  << " (" << timeString(m_StartTime) << ")" << endl;
511  cout << myname << " PulserStepCharge: " << m_PulserStepCharge << endl;
512  cout << myname << " PulserDacOffset: " << m_PulserDacOffset << endl;
513  cout << myname << " PulserChargeUnit: " << m_PulserChargeUnit << endl;
514  cout << myname << " RoiPlotOpt: " << m_RoiPlotOpt << endl;
515  cout << myname << " MaxRoiPlots: " << m_MaxRoiPlots << endl;
516  cout << myname << " RoiPlotPadX: " << m_RoiPlotPadX << endl;
517  cout << myname << " RoiPlotPadY: " << m_RoiPlotPadY << endl;
518  cout << myname << " SumNegate: " << (m_SumNegate ? "true" : "false") << endl;
519  cout << myname << " SumPlotPadX: " << m_SumPlotPadX << endl;
520  cout << myname << " SumPlotPadY: " << m_SumPlotPadY << endl;
521  cout << myname << " ChannelRanges: [";
522  bool first = true;
523  for ( string crn : m_ChannelRanges ) {
524  if ( first ) first = false;
525  else cout << ", ";
526  cout << crn;
527  }
528  cout << "]" << endl;
529  cout << myname << " ChannelLineModulus: " << m_ChannelLineModulus << endl;
530  cout << myname << " ChannelLinePattern: {";
531  first = true;
532  for ( Index icha : m_ChannelLinePattern ) {
533  if ( ! first ) cout << ", ";
534  first = false;
535  cout << icha;
536  }
537  cout << "}" << endl;
538  cout << myname << " RoiRootFileName: " << m_RoiRootFileName << endl;
539  cout << myname << " SumRootFileName: " << m_SumRootFileName << endl;
540  cout << myname << " ChanSumRootFileName: " << m_ChanSumRootFileName << endl;
541  if ( getState().sumHistTemplates.size() == 0 ) {
542  cout << myname << " No summary histograms" << endl;
543  } else {
544  cout << myname << " SumHists:" << endl;
545  for ( const HistInfoMap::value_type& ish : getState().sumHistTemplates ) {
546  const HistInfo& hin = ish.second;
547  cout << myname << " ";
548  cout << hin.ph->GetName() << "(" << hin.varx;
549  if ( hin.vary.size() ) cout << "," << hin.vary;
550  cout << ")";
551  if ( hin.fitName.size() ) cout << " fit=" << hin.fitName;
552  if ( hin.plotName.size() ) cout << " plot=" << hin.plotName;
553  cout << endl;
554  }
555  }
556  if ( getState().chanSumHists.size() == 0 ) {
557  cout << myname << " No channel summary histograms" << endl;
558  } else {
559  cout << myname << " ChanSumHists:" << endl;
560  for ( HistMap::value_type ihst : getState().chanSumHists ) {
561  TH1* ph = ihst.second;
562  cout << myname << " " << ph->GetName() << endl;
563  }
564  }
565  cout << myname << " PlotLabels: [";
566  first = true;
567  for ( Name slab : m_PlotLabels ) {
568  if ( first ) first = false;
569  else cout << ", ";
570  cout << slab;
571  }
572  cout << "]" << endl;
573  cout << myname << " RunDataTool: \"" << m_RunDataTool << "\" @ "
574  << m_pRunDataTool << endl;
575  cout << myname << " TickOffsetTool: \"" << m_TickOffsetTool << "\" @ "
576  << m_pTickOffsetTool << endl;
577  }
578  if ( m_LogLevel >=2 ) cout << myname << "End constructing tool." << endl;
579 }
Index m_TickBorder
Definition: AdcRoiViewer.h:330
Index m_SumPlotPadX
Definition: AdcRoiViewer.h:342
const TimeOffsetTool * m_pTickOffsetTool
Definition: AdcRoiViewer.h:365
const AdcChannelStringTool * m_adcStringBuilder
Definition: AdcRoiViewer.h:363
std::vector< Index > IndexVector
HistInfoMap sumHistTemplates
Definition: AdcRoiViewer.h:231
Index m_ChannelLineModulus
Definition: AdcRoiViewer.h:344
const RunDataTool * m_pRunDataTool
Definition: AdcRoiViewer.h:364
std::vector< ParameterSet > ParameterSetVector
StatePtr m_state
Definition: AdcRoiViewer.h:360
IndexVector m_ChannelLinePattern
Definition: AdcRoiViewer.h:345
Index begin
Definition: IndexRange.h:34
Name m_RoiRootFileName
Definition: AdcRoiViewer.h:349
IndexByNameMap chanSumChaBegin
Definition: AdcRoiViewer.h:250
ChannelGroupService::Name Name
NameVector m_PlotLabels
Definition: AdcRoiViewer.h:353
float m_SigThresh
Definition: AdcRoiViewer.h:329
Index size() const
Definition: IndexRange.h:88
FloatMap chanSumPlotYMins
Definition: AdcRoiViewer.h:247
intermediate_table::const_iterator const_iterator
Name m_PulserChargeUnit
Definition: AdcRoiViewer.h:340
unsigned int Index
bool isValid() const
Definition: IndexRange.h:94
Index end
Definition: IndexRange.h:35
NameVector m_ChannelRanges
Definition: AdcRoiViewer.h:352
NameMap chanSumHistErrorTypes
Definition: AdcRoiViewer.h:244
Name name
Definition: IndexRange.h:32
Index m_RoiPlotOpt
Definition: AdcRoiViewer.h:333
Name m_ChanSumRootFileName
Definition: AdcRoiViewer.h:351
NameMap chanSumHistTemplateNames
Definition: AdcRoiViewer.h:242
FloatMap chanSumPlotYMaxs
Definition: AdcRoiViewer.h:248
float m_PulserDacOffset
Definition: AdcRoiViewer.h:339
Index m_SumPlotPadY
Definition: AdcRoiViewer.h:343
IndexByNameMap chanSumHistTypes
Definition: AdcRoiViewer.h:245
static constexpr double ps
Definition: Units.h:99
Name label(Index ilab=0) const
Definition: IndexRange.h:106
IndexByNameMap chanSumChaEnd
Definition: AdcRoiViewer.h:251
Index m_RoiPlotPadX
Definition: AdcRoiViewer.h:335
NameMap m_plotLabelSubs
Definition: AdcRoiViewer.h:357
time_t m_StartTime
Definition: AdcRoiViewer.h:337
State & getState() const
Definition: AdcRoiViewer.h:304
void setPlotLabels(Name &sttl) const
std::vector< string > NameVector
Name m_RunDataTool
Definition: AdcRoiViewer.h:346
NameMap chanSumHistVariableTypes
Definition: AdcRoiViewer.h:243
Index m_RoiPlotPadY
Definition: AdcRoiViewer.h:336
float m_PulserStepCharge
Definition: AdcRoiViewer.h:338
if(!yymsg) yymsg
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
const IndexRangeTool * m_pChannelRangeTool
Definition: AdcRoiViewer.h:366
static DuneToolManager * instance(std::string fclname="", int dbg=1)
Name m_SumRootFileName
Definition: AdcRoiViewer.h:350
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)
Name m_ChannelRangeTool
Definition: AdcRoiViewer.h:348
virtual IndexRange get(Name nam) const =0
Name m_TickOffsetTool
Definition: AdcRoiViewer.h:347
AdcRoiViewer::~AdcRoiViewer ( )
override

Definition at line 583 of file AdcRoiViewer_tool.cc.

583  {
584  const string myname = "AdcRoiViewer::dtor: ";
585  close(nullptr);
586 }
DataMap close(const DataMap *dmin) override

Member Function Documentation

DataMap AdcRoiViewer::close ( const DataMap dmin)
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 649 of file AdcRoiViewer_tool.cc.

649  {
650  const string myname = "AdcRoiViewer::close: ";
651  DataMap ret;
652  if ( getState().closeCount ) return ret.setStatus(1);
653  ++getState().closeCount;
654  if ( m_LogLevel >= 1 ) {
655  cout << myname << "Closing." << endl;
656  cout << myname << " Event count: " << getState().eventCallCount.size() << endl;
657  cout << myname << " Call count: " << getState().callCount << endl;
658  cout << myname << " Sample unit: " << getState().cachedSampleUnit << endl;
659  }
660  if ( m_RoiPlotOpt == 2 ) {
661  Index ntpm = getState().roiPads.size();
662  if ( m_LogLevel >= 2 ) cout << myname << "Printing " << ntpm << " ROI pad"
663  << (ntpm == 1 ? "" : "s") << endl;
664  for ( TpmMap::value_type& itpm : getState().roiPads ) {
665  Index icha = itpm.first;
666  TpmPtr& pmantop = itpm.second;
667  if ( pmantop ) {
668  Name plotFileName = getState().roiPadNames[icha];
669  if ( m_LogLevel >=3 ) cout << myname << "Writing " << plotFileName << endl;
670  pmantop->print(plotFileName);
671  pmantop.reset(nullptr);
672  }
673  }
674  }
675  if ( getState().sumHists.size() ) {
676  fitSumHists();
677  writeSumHists();
678  writeSumPlots(pdmin);
679  }
680  if ( getState().chanSumHists.size() ) {
684  }
685  return ret;
686 }
void writeChanSumPlots() const
void writeSumPlots(const DataMap *pdmin) const
void writeSumHists() const
void fitSumHists() const
DataMap & setStatus(int stat)
Definition: DataMap.h:130
ChannelGroupService::Name Name
TpmNameMap roiPadNames
Definition: AdcRoiViewer.h:228
void fillChanSumHists() const
unsigned int Index
Index m_RoiPlotOpt
Definition: AdcRoiViewer.h:333
State & getState() const
Definition: AdcRoiViewer.h:304
std::unique_ptr< TPadManipulator > TpmPtr
Definition: AdcRoiViewer.h:203
void writeChanSumHists() const
IndexByIndexMap eventCallCount
Definition: AdcRoiViewer.h:273
QTextStream & endl(QTextStream &s)
int AdcRoiViewer::doView ( const AdcChannelData acd,
int  dbg,
DataMap dm 
) const

Definition at line 690 of file AdcRoiViewer_tool.cc.

690  {
691  const string myname = "AdcRoiViewer::doView: ";
692  unsigned int ievt = acd.event();
693  ++getState().callCount;
694  if ( getState().eventCallCount.find(ievt) == getState().eventCallCount.end() ) {
695  getState().eventCallCount[ievt] = 0;
696  } else {
697  ++getState().eventCallCount[ievt];
698  }
699  unsigned int nraw = acd.raw.size();
700  unsigned int nsam = acd.samples.size();
701  unsigned int ntickChannel = nsam > nraw ? nsam : nraw;
702  unsigned int nroiRaw = acd.rois.size();
703  bool doHist = m_RoiHistOpt != 0;
704  bool histRelativeTick = false;
705  int histType = 0;
706  if ( doHist ) {
707  if ( m_RoiHistOpt == 1 ) {
708  histType = 1;
709  } else if ( m_RoiHistOpt == 2 ) {
710  histType = 2;
711  } else if ( m_RoiHistOpt == 11 ) {
712  histType = 1;
713  histRelativeTick = true;
714  } else if ( m_RoiHistOpt == 12 ) {
715  histType = 2;
716  histRelativeTick = true;
717  } else {
718  cout << myname << "Invalid value for RoiHistOpt: " << m_RoiHistOpt << endl;
719  return res.setStatus(1).status();
720  }
721  }
722  if ( dbg >=2 ) cout << myname << "Processing channel " << acd.channel() << "."
723  << " Input ROI count is " << nroiRaw << endl;
724  DataMap::HistVector roiHists;
725  DataMap::FloatVector roiSigMins;
726  DataMap::FloatVector roiSigMaxs;
727  DataMap::FloatVector roiSigAreas;
728  DataMap::FloatVector roiFitHeights;
729  DataMap::FloatVector roiFitWidths;
730  DataMap::FloatVector roiFitPositions;
731  DataMap::FloatVector roiFitChiSquares;
732  DataMap::FloatVector roiFitChiSquareDofs;
733  DataMap::IntVector roiTickMins;
734  DataMap::IntVector roiTickMaxs;
735  DataMap::IntVector roiTimes;
736  DataMap::IntVector roiNUnderflows;
737  DataMap::IntVector roiNOverflows;
738  DataMap::IntVector tick1;
739  DataMap::IntVector ntick;
740  DataMap::IntVector roiFitStats;
741  Index nroi = 0;
742  for ( unsigned int iroiRaw=0; iroiRaw<nroiRaw; ++iroiRaw ) {
743  AdcRoi roi = acd.rois[iroiRaw];
744  if ( dbg >=3 ) cout << myname << " ROI " << nroi << "(raw " << iroiRaw << "): ["
745  << roi.first << ", " << roi.second << "]" << endl;
746  ostringstream sshnam;
747  sshnam << "hroi_run_%0RUN%_evt%0EVENT%_chan%0CHAN%_roi";
748  if ( nroi < 100 ) sshnam << "0";
749  if ( nroi < 10 ) sshnam << "0";
750  sshnam << nroi;
751  string hnam = AdcChannelStringTool::AdcChannelStringTool::build(m_adcStringBuilder, acd, sshnam.str());
752  ostringstream sshttl;
753  sshttl << "Run %RUN% event %EVENT% channel %CHAN% ROI " << nroi;
754  sshttl << " ;Tick ;";
755  if ( histType == 1 ) sshttl << "Signal% [SUNIT]%";
756  if ( histType == 2 ) sshttl << "ADC count";
757  string httl = AdcChannelStringTool::build(m_adcStringBuilder, acd, sshttl.str());
758  unsigned int isam1 = roi.first;
759  unsigned int isam2 = roi.second + 1;
760  // Check position if this a ROI to keep.
761  if ( m_TickBorder > 0 ) {
762  if ( isam1 < m_TickBorder ) continue;
763  if ( isam2 + m_TickBorder > nsam ) continue;
764  }
765  float x1 = histRelativeTick ? 0.0 : isam1;
766  float x2 = histRelativeTick ? isam2 - isam1 : isam2;
767  TH1* ph = new TH1F(hnam.c_str(), httl.c_str(), isam2-isam1, x1, x2);
768  ph->SetDirectory(nullptr);
769  //ph->Sumw2(); // Likelihood fit needs weights.
770  ph->SetStats(0);
771  ph->SetLineWidth(2);
772  unsigned int ibin = 0;
773  float sigmin = 0.0;
774  float sigmax = 0.0;
775  float sigarea = 0.0;
776  int roiTickMin = 0;
777  int roiTickMax = 0;
778  Index nunder = 0;
779  Index nover = 0;
780  for ( unsigned int isam=isam1; isam<isam2; ++isam ) {
781  float sig = 0.0;
782  if ( histType == 1 && isam<nsam ) sig = acd.samples[isam];
783  if ( histType == 2 && isam<nraw ) sig = isam<nraw ? acd.raw[isam] : 0.0;
784  if ( ibin == 0 ) {
785  sigmin = sig;
786  sigmax = sig;
787  } else {
788  if ( sig < sigmin ) {
789  sigmin = sig;
790  roiTickMin = ibin;
791  }
792  if ( sig > sigmax ) {
793  sigmax = sig;
794  roiTickMax = ibin;
795  }
796  }
797  sigarea += sig;
798  ph->SetBinContent(++ibin, sig);
799  AdcFlag flag = acd.flags.size() > isam ? acd.flags[isam] : 0;
800  if ( flag == AdcUnderflow ) ++nunder;
801  if ( flag == AdcOverflow ) ++nover;
802  }
803  // Check height if this a ROI to keep.
804  if ( m_SigThresh < 0.0 && sigmin > m_SigThresh ) continue;
805  if ( m_SigThresh > 0.0 && sigmax < m_SigThresh ) continue;
806  ++nroi;
807  roiHists.push_back(ph);
808  roiTickMins.push_back(roiTickMin);
809  roiNUnderflows.push_back(nunder);
810  roiNOverflows.push_back(nover);
811  roiTickMaxs.push_back(roiTickMax);
812  roiTimes.push_back(int(acd.time()) - int(m_StartTime));
813  roiSigMins.push_back(sigmin);
814  roiSigMaxs.push_back(sigmax);
815  roiSigAreas.push_back(sigarea);
816  tick1.push_back(isam1);
817  ntick.push_back(isam2 - isam1);
818  if ( m_FitOpt == 1 ) {
819  if ( dbg >= 3 ) cout << " Fitting with coldelecResponse" << endl;
820  bool isNeg = fabs(sigmin) > sigmax;
821  double h = isNeg ? sigmin : sigmax;
822  //double shap = 2.5*ph->GetRMS(); // No! Negative entries break RMS calculation.
823  double shap = 0.8*fabs(sigarea)/fabs(h);
824  double t0 = x1 + (isNeg ? roiTickMin : roiTickMax) - shap;
825  TF1* pf = coldelecResponseTF1(h, shap, t0, "coldelec");
826  TF1* pfinit = coldelecResponseTF1(h, shap, t0, "coldelec");
827  // The following was very slow when function was written to a file.
828  //TF1* pfinit = dynamic_cast<TF1*>(pf->Clone("coldelec0"));
829  pfinit->SetLineColor(3);
830  pfinit->SetLineStyle(2);
831  string fopt = "0";
832  fopt = "WWB";
833  //fopt = "LWB"; // Use likelihood fit to include empty bins. Do we want this here?
834  if ( dbg < 3 ) fopt += "Q";
835  // Do shifted fit to avoid numerical issues if t0 is large.
836  double xshift = 0.0;
837  if ( t0 > 500.0 ) {
838  xshift = 500*(long(t0)/500);
839  }
840  int fstat = shiftHistFit(ph, pf, fopt.c_str(), 2, xshift);
841  ph->GetListOfFunctions()->AddLast(pfinit, "0");
842  ph->GetListOfFunctions()->Last()->SetBit(TF1::kNotDraw, true);
843  ph->GetListOfFunctions()->SetOwner(kTRUE); // So the histogram owns pfinit
844  roiFitHeights.push_back(pf->GetParameter(0));
845  roiFitWidths.push_back(pf->GetParameter(1));
846  roiFitPositions.push_back(pf->GetParameter(2));
847  roiFitStats.push_back(fstat);
848  float cs = pf->GetChisquare();
849  int ndf = pf->GetNDF();
850  float csn = ndf > 0 ? cs/float(ndf) : -1.0;
851  roiFitChiSquares.push_back(cs);
852  roiFitChiSquareDofs.push_back(csn);
853  delete pf;
854  //delete pfinit; This give error: list accessing deleted object
855  }
856  }
857  writeRoiPlots(roiHists, acd);
858  res.setInt("roiEvent", acd.event());
859  res.setInt("roiRun", acd.run());
860  res.setInt("roiSubRun", acd.subRun());
861  res.setInt("roiChannel", acd.channel());
862  res.setInt("roiCount", nroi);
863  res.setInt("roiRawCount", nroiRaw);
864  res.setInt("roiNTickChannel", ntickChannel);
865  res.setIntVector("roiTick0s", tick1);
866  res.setIntVector("roiNTicks", ntick);
867  res.setIntVector("roiNUnderflows", roiNUnderflows);
868  res.setIntVector("roiNOverflows", roiNOverflows);
869  res.setIntVector("roiTickMins", roiTickMins);
870  res.setIntVector("roiTickMaxs", roiTickMaxs);
871  res.setIntVector("roiTimes", roiTimes);
872  res.setFloatVector("roiSigMins", roiSigMins);
873  res.setFloatVector("roiSigMaxs", roiSigMaxs);
874  res.setFloatVector("roiSigAreas", roiSigAreas);
875  res.setHistVector("roiHists", roiHists, true);
876  if ( roiFitHeights.size() ) {
877  res.setFloatVector("roiFitHeights", roiFitHeights);
878  res.setFloatVector("roiFitWidths", roiFitWidths);
879  res.setFloatVector("roiFitPositions", roiFitPositions);
880  res.setIntVector("roiFitStats", roiFitStats);
881  res.setFloatVector("roiFitChiSquares", roiFitChiSquares);
882  res.setFloatVector("roiFitChiSquareDofs", roiFitChiSquareDofs);
883  }
884  fillSumHists(acd, res);
885  if ( acd.run() != AdcChannelData::badIndex() ) {
886  if ( getState().cachedRunCount == 0 ) {
887  getState().cachedRun = acd.run();
888  getState().cachedRunCount = 1;
889  } else {
890  if ( acd.run() != getState().cachedRun ) {
891  getState().cachedRun = acd.run();
893  }
894  }
895  }
896  if ( getState().cachedSampleUnit.size() == 0 ) {
898  }
900  return res.status();
901 }
Index m_TickBorder
Definition: AdcRoiViewer.h:330
code to link reconstructed objects back to the MC truth information
std::vector< float > FloatVector
Definition: DataMap.h:54
const AdcChannelStringTool * m_adcStringBuilder
Definition: AdcRoiViewer.h:363
IndexByIndexMap channelStatuses
Definition: AdcRoiViewer.h:268
void writeRoiPlots(const HistVector &hists, const AdcChannelData &acd) const
short AdcFlag
Definition: AdcTypes.h:29
AdcIndex subRun() const
bool dbg
std::pair< AdcIndex, AdcIndex > AdcRoi
Definition: AdcTypes.h:54
float m_SigThresh
Definition: AdcRoiViewer.h:329
const AdcFlag AdcUnderflow
Definition: AdcTypes.h:33
int shiftHistFit(TH1 *ph, TF1 *pf, std::string fopt, int ipar, double xshift)
unsigned int Index
time_t time() const
std::vector< int > IntVector
Definition: DataMap.h:50
const AdcFlag AdcOverflow
Definition: AdcTypes.h:34
AdcRoiVector rois
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
AdcIndex run() const
AdcIndex event() const
AdcCountVector raw
time_t m_StartTime
Definition: AdcRoiViewer.h:337
State & getState() const
Definition: AdcRoiViewer.h:304
Index channelStatus() const
Channel channel() const
TF1 * coldelecResponseTF1(double gainIn, double shapingIn, double t0, std::string fname="ceresp")
const char * cs
void fillSumHists(const AdcChannelData &acd, const DataMap &dm) const
std::vector< TH1 * > HistVector
Definition: DataMap.h:57
static Index badIndex()
IndexByIndexMap eventCallCount
Definition: AdcRoiViewer.h:273
AdcSignalVector samples
QTextStream & endl(QTextStream &s)
AdcFlagVector flags
void AdcRoiViewer::fillChanSumHists ( ) const

Definition at line 1677 of file AdcRoiViewer_tool.cc.

1677  {
1678  const string myname = "AdcRoiViewer::fillChanSumHists: ";
1679  if ( getState().chanSumHists.size() == 0 ) {
1680  cout << myname << "No channel summary histograms found." << endl;
1681  return;
1682  }
1683  Name ofrname = m_ChanSumRootFileName;
1684  if ( m_LogLevel >= 1 ) cout << myname << "Filling channel summary histograms. Count is "
1685  << getState().chanSumHists.size() << "." << endl;
1686  for ( HistMap::value_type ihst : getState().chanSumHists ) {
1687  TH1* ph = ihst.second;
1688  Name hnam = ph->GetName();
1689  Name hnamTemplate = getState().getChanSumHistTemplateName(hnam);
1690  if ( hnamTemplate.size() == 0 ) {
1691  cout << myname << "ERROR: Summary template histogram name not found for channel summary " << hnam << endl;
1692  continue;
1693  }
1694  Name vartype = getState().getChanSumHistVariableType(hnam);
1695  Name errtype = getState().getChanSumHistErrorType(hnam);
1696  double errmin = 0.0;
1697  if ( errtype.substr(0,3) == "rms" && errtype.size() > 3 ) {
1698  string serrmin = errtype.substr(3);
1699  istringstream ssermin(serrmin);
1700  ssermin >> errmin;
1701  errtype = "rms";
1702  }
1703  bool isDist = getState().chanSumHistTypes[hnam];
1704  if ( vartype.size() == 0 ) {
1705  cout << myname << "ERROR: Variable type name not found for " << hnam << endl;
1706  continue;
1707  }
1708  AdcChannelData acd;
1709  acd.setEventInfo(getState().cachedRun, 0);
1711  Index ncha = 0;
1712  Index nchaGood = 0;
1713  int logthresh = 3;
1714  Index icha1 = getState().chanSumChaBegin[hnam];
1715  Index icha2 = getState().chanSumChaEnd[hnam];
1716  //for ( int ibin=1; ibin<=ph->GetNbinsX(); ++ibin ) {
1717  // Index icha = ph->GetBinCenter(ibin);
1718  for ( Index icha=icha1; icha<icha2; ++icha ) {
1719  Index ichaBin = icha + 1 - icha1;
1720  acd.setChannelInfo(icha);
1721  Name hnam = AdcChannelStringTool::build(m_adcStringBuilder, acd, hnamTemplate);
1722  //Index chanStat = getState().getChannelStatus(hnam);
1723  //if ( chanStat ) continue;
1724  ++ncha;
1725  TH1* phvar = getState().getSumHist(hnam);
1726  if ( phvar == nullptr ) {
1727  if ( m_LogLevel >= logthresh )
1728  cout << myname << "Unable to find sum hist " << hnam << endl;
1729  continue;
1730  }
1731  float val = 0.0;
1732  if ( vartype == "mean" ) {
1733  val = phvar->GetMean();
1734  } else if ( vartype == "peak" ) {
1735  int ibin = phvar->GetMaximumBin();
1736  val = phvar->GetBinCenter(ibin);
1737  } else if ( vartype == "rms" ) {
1738  val = phvar->GetRMS();
1739  } else if ( vartype == "entries" ) {
1740  val = phvar->GetEntries();
1741  } else if ( vartype == "count" ) {
1742  val = phvar->Integral();
1743  } else if ( vartype == "sum" ) {
1744  val = phvar->Integral()*phvar->GetMean();
1745  } else if ( vartype.substr(0,3) == "fit" ) {
1746  Index nfun = phvar->GetListOfFunctions()->GetEntries();
1747  TF1* pf = nfun ? dynamic_cast<TF1*>(phvar->GetListOfFunctions()->At(0)) : nullptr;
1748  if ( pf == nullptr ) {
1749  if ( m_LogLevel >= logthresh )
1750  cout << myname << "Unable to find find fit for sum hist " << hnam << endl;
1751  continue;
1752  }
1753  bool doRat = vartype.substr(3,3) == "rat";
1754  string::size_type ipos = doRat ? 6 : 3;
1755  Name spar = vartype.substr(ipos);
1756  int ipar = pf->GetParNumber(spar.c_str());
1757  if ( ipar < 0 ) {
1758  if ( m_LogLevel >= logthresh )
1759  cout << myname << "ERROR: Invalid fit parameter name: " << spar << endl;
1760  continue;
1761  }
1762  val = pf->GetParameter(ipar);
1763  if ( doRat ) {
1764  double mean = pf->GetParameter("Mean");
1765  val *= (mean == 0.0 ? 0.0 : 1.0/mean);
1766  }
1767  } else {
1768  cout << myname << "Invalid variable type " << vartype << " for " << hnam << endl;
1769  break;
1770  }
1771  float dval = 0.0;
1772  bool haveErr = true;
1773  if ( errtype == "none" ) {
1774  haveErr = false;
1775  } else if ( errtype == "zero" ) {
1776  dval = 0.0;
1777  } else if ( errtype.substr(0,3) == "rms" ) {
1778  dval = phvar->GetRMS();
1779  if ( dval < errmin ) dval = errmin;
1780  } else if ( errtype == "meanError" ) {
1781  dval = phvar->GetMeanError();
1782  if ( dval < errmin ) dval = errmin;
1783  } else if ( errtype == "rmsError" ) {
1784  dval = phvar->GetRMSError();
1785  if ( dval < errmin ) dval = errmin;
1786  } else if ( errtype.substr(0,3) == "fit" ) {
1787  Index nfun = phvar->GetListOfFunctions()->GetEntries();
1788  TF1* pf = nfun ? dynamic_cast<TF1*>(phvar->GetListOfFunctions()->At(0)) : nullptr;
1789  if ( phvar == nullptr ) {
1790  if ( m_LogLevel >= logthresh )
1791  cout << myname << "Unable to find find fit for sum hist " << hnam << endl;
1792  continue;
1793  }
1794  Name spar = errtype.substr(3);
1795  int ipar = pf->GetParNumber(spar.c_str());
1796  if ( ipar < 0 ) {
1797  cout << myname << "ERROR: Invalid fit parameter name: " << spar << endl;
1798  } else {
1799  dval = pf->GetParameter(ipar);
1800  }
1801  } else {
1802  cout << myname << "Invalid error type: " << errtype << endl;
1803  abort();
1804  }
1805  if ( ph->GetEntries() == 0 ) {
1806  TAxis* paxis = isDist ? ph->GetXaxis() : ph->GetYaxis();
1807  Name vlabOld = paxis->GetTitle();
1808  Name vlabNew = AdcChannelStringTool::build(m_adcStringBuilder, acd, vlabOld);
1809  if ( vlabNew != vlabOld ) {
1810  if ( m_LogLevel >= 3 ) cout << myname << "Setting variable label for " << hnam
1811  << " to \"" << vlabNew << "\"." << endl;
1812  paxis->SetTitle(vlabNew.c_str());
1813  }
1814  Name httlOld = ph->GetTitle();
1815  Name httlNew = AdcChannelStringTool::build(m_adcStringBuilder, acd, httlOld);
1816  if ( httlNew != httlOld ) {
1817  if ( m_LogLevel >= 3 ) cout << myname << "Setting title for " << hnam << " to \""
1818  << httlNew << "\"." << endl;
1819  ph->SetTitle(httlNew.c_str());
1820  }
1821  }
1822  if ( isDist ) {
1823  ph->Fill(val);
1824  } else {
1825  ph->SetBinContent(ichaBin, val);
1826  if ( haveErr ) ph->SetBinError(ichaBin, dval);
1827  }
1828  ++nchaGood;
1829  }
1830  if ( nchaGood < ncha ) {
1831  cout << myname << "WARNING: Only filled " << nchaGood << " of " << ncha
1832  << " channels for channel summary histogram " << hnam << endl;
1833  }
1834  }
1835 }
const AdcChannelStringTool * m_adcStringBuilder
Definition: AdcRoiViewer.h:363
IndexByNameMap chanSumChaBegin
Definition: AdcRoiViewer.h:250
ChannelGroupService::Name Name
TH1 * getSumHist(Name hnam)
unsigned int Index
void setChannelInfo(ChannelInfoPtr pchi)
Name m_ChanSumRootFileName
Definition: AdcRoiViewer.h:351
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
Name getChanSumHistVariableType(Name hnam) const
void setEventInfo(EventInfoPtr pevi)
IndexByNameMap chanSumHistTypes
Definition: AdcRoiViewer.h:245
Name getChanSumHistErrorType(Name hnam) const
IndexByNameMap chanSumChaEnd
Definition: AdcRoiViewer.h:251
Name getChanSumHistTemplateName(Name hnam) const
State & getState() const
Definition: AdcRoiViewer.h:304
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::fillSumHists ( const AdcChannelData acd,
const DataMap dm 
) const

Definition at line 1067 of file AdcRoiViewer_tool.cc.

1067  {
1068  const string myname = "AdcRoiViewer::fillSumHists: ";
1069  // Fetch the run data.
1070  RunData rdat;
1071  if ( m_pRunDataTool != nullptr ) {
1072  rdat = m_pRunDataTool->runData(acd.run(), acd.subRun());
1073  RunData& rdatOld = getState().runData;
1074  if ( rdat.isValid() && ! rdatOld.isValid() ) {
1075  if ( m_LogLevel >= 2 ) cout << myname << "Setting run data." << endl;
1076  rdatOld = rdat;
1077  } else if ( rdat.isValid() && rdatOld.isValid() ) {
1078  if ( rdat.run() != rdatOld.run() ) {
1079  cout << myname << "Ignoring unexpected change in run number: " << rdatOld.run()
1080  << " --> " << rdat.run();
1081  }
1082  } else if ( ! rdat.isValid() ) {
1083  if ( m_LogLevel >= 3 ) cout << myname << "Run data not found." << endl;
1084  }
1085  }
1086  float pulserQin = 0.0;
1087  bool havePulserAmplitude = rdat.havePulserAmplitude() && rdat.havePulserSource();
1088  bool havePulserPeriod = rdat.havePulserPeriod();
1089  bool haveQin = false;
1090  if ( havePulserAmplitude ) {
1091  int qfac = rdat.pulserAmplitude();
1092  //if ( rdat.pulserSource() == 2 && qfac > 0 ) --qfac; // Should we do this??
1093  pulserQin = (qfac - m_PulserDacOffset)*m_PulserStepCharge;
1094  haveQin = pulserQin != 0.0;
1095  if ( ! haveQin ) {
1096  cout << myname << "WARNING: Pulser charge evaluates to zero." << endl;
1097  }
1098  }
1099  Index pulserPeriod = 0;
1100  if ( havePulserPeriod ) {
1101  pulserPeriod = rdat.pulserPeriod();
1102  if ( pulserPeriod == 0 ) {
1103  havePulserPeriod = false;
1104  cout << myname << "WARNING: Pulser period is zero." << endl;
1105  }
1106  }
1107  // Fetch the tick offset.
1108  TimeOffsetTool::Data tdat;
1109  bool haveTickOffset = false;
1110  long tickOffset = 0;
1111  bool haveTickOffsetPulserMod = false;
1112  Index tickOffsetPulserMod = 0; // Tick offset modulus the pulser period [0, pulserPeriod).
1113  double timingPhase = 0.0; // Phase of the timing clock (0,1]
1114  if ( m_pTickOffsetTool != nullptr ) {
1115  tdat.run = acd.run();
1116  tdat.subrun = acd.subRun();
1117  tdat.event = acd.event();
1118  tdat.channel = acd.channel();
1119  tdat.fembID = acd.fembID();
1120  tdat.triggerClock = acd.triggerClock();
1122  if ( off.isValid() ) {
1123  haveTickOffset = true;
1124  tickOffset = off.value;
1125  timingPhase = off.rem;
1126  } else {
1127  cout << myname << "Unable to retrieve tick offset for run " << tdat.run << "-" << tdat.subrun
1128  << " event " << tdat.event << " channel " << tdat.channel << endl;
1129  }
1130  if ( haveTickOffset && havePulserPeriod ) {
1131  long toff = tickOffset;
1132  long period = pulserPeriod;
1133  toff = toff % period;
1134  if ( toff < 0 ) toff += period;
1135  tickOffsetPulserMod = toff;
1136  haveTickOffsetPulserMod = true;
1137  }
1138  }
1139  // Loop over summary histogram templates.
1140  Index nhst = 0;
1141  Index nhstGood = 0;
1142  for ( const HistInfoMap::value_type ish : getState().sumHistTemplates ) {
1143  const HistInfo& hin0 = ish.second;
1144  ++nhst;
1145  Name varx = hin0.varx;
1146  if ( m_SumNegate ) {
1147  if ( varx == "fitHeight" ) varx = "fitHeightNeg";
1148  if ( varx == "sigArea" ) varx = "sigAreaNeg";
1149  }
1150  Name vary = hin0.vary;
1151  TH1* ph0 = hin0.ph;
1152  Name fitName = hin0.fitName;
1153  Name plotNameTemplate = hin0.plotName;
1154  FloatVector vals;
1155  IntVector ivals;
1156  if ( varx == "sigArea" ) vals = dm.getFloatVector("roiSigAreas");
1157  else if ( varx == "sigAreaNeg" ) vals = dm.getFloatVector("roiSigAreas");
1158  else if ( varx == "sigWidth" ) ivals = dm.getIntVector("roiNTicks");
1159  else if ( varx == "sigTick0" ) ivals = dm.getIntVector("roiTick0s");
1160  else if ( varx == "sigTick0Pulser" ) ivals = dm.getIntVector("roiTick0s");
1161  else if ( varx == "sigTickMax" ) ivals = dm.getIntVector("roiTickMaxs");
1162  else if ( varx == "sigTickMaxPulser" ) ivals = dm.getIntVector("roiTickMaxs");
1163  else if ( varx == "fitHeight" ) vals = dm.getFloatVector("roiFitHeights");
1164  else if ( varx == "fitHeightNeg" ) vals = dm.getFloatVector("roiFitHeights");
1165  else if ( varx == "fitHeightGain" ) vals = dm.getFloatVector("roiFitHeights");
1166  else if ( varx == "fitWidth" ) vals = dm.getFloatVector("roiFitWidths");
1167  else if ( varx == "fitPos" ) vals = dm.getFloatVector("roiFitPositions");
1168  else if ( varx == "fitPosRem" ) vals = dm.getFloatVector("roiFitPositions");
1169  else if ( varx == "fitPosPulser" ) vals = dm.getFloatVector("roiFitPositions");
1170  else if ( varx == "fitToffPulser" ) vals = dm.getFloatVector("roiFitPositions");
1171  else if ( varx == "fitToffPulserMod10" ) vals = dm.getFloatVector("roiFitPositions");
1172  else if ( varx == "fitStat" ) ivals = dm.getIntVector("roiFitStats");
1173  else if ( varx == "fitChiSquare" ) vals = dm.getFloatVector("roiFitChiSquares");
1174  else if ( varx == "fitChiSquareDof" ) vals = dm.getFloatVector("roiFitChiSquareDofs");
1175  else if ( varx == "fitCSNorm" ) vals = dm.getFloatVector("roiFitChiSquares");
1176  else if ( varx == "fitCSNormDof" ) vals = dm.getFloatVector("roiFitChiSquareDofs");
1177  else if ( varx == "timeSec" ) ivals = dm.getIntVector("roiTimes");
1178  else if ( varx == "timeHour" ) ivals = dm.getIntVector("roiTimes");
1179  else if ( varx == "timeDay" ) ivals = dm.getIntVector("roiTimes");
1180  else if ( varx == "procEvent" ) ivals.push_back(acd.event());
1181  else if ( varx == "procTimeSec" ) ivals.push_back(int(acd.time()) - int(m_StartTime));
1182  else if ( varx == "procTimeHour" ) ivals.push_back(int(acd.time()) - int(m_StartTime));
1183  else if ( varx == "procTimeDay" ) ivals.push_back(int(acd.time()) - int(m_StartTime));
1184  else {
1185  if ( m_LogLevel >= 2 ) {
1186  cout << myname << "ERROR: Invalid variable name: " << varx << endl;
1187  continue;
1188  }
1189  }
1190  Name hnam0 = ph0->GetName();
1192  Name xlab = AdcChannelStringTool::build(m_adcStringBuilder, acd, ph0->GetXaxis()->GetTitle());
1193  Name ylab = ph0->GetYaxis()->GetTitle();
1194  TH1* ph = getState().getSumHist(hnam);
1195  if ( ivals.size() && !vals.size() ) for ( int ival : ivals ) vals.push_back(ival);
1196  if ( varx == "fitPosRem" ) for ( float& val : vals ) val = std::remainder(val,1);
1197  if ( varx == "fitPosPulser" ) {
1198  if ( ! havePulserPeriod ) {
1199  cout << myname << "WARNING: Cannot evaluate " << varx << " without pulser period" << endl;
1200  continue;
1201  }
1202  for ( float& val : vals ) val = fmod(val, pulserPeriod);
1203  }
1204  if ( varx == "fitToffPulser" || varx == "fitToffPulserMod10" ||
1205  varx == "sigTick0Pulser" || varx == "sigTickMaxPulser" ) {
1206  if ( ! haveTickOffsetPulserMod ) {
1207  cout << myname << "WARNING: Cannot evaluate " << varx << " without timing offset and pulser period" << endl;
1208  continue;
1209  }
1210  for ( float& val : vals ) val = fmod(val + pulserPeriod + tickOffsetPulserMod, pulserPeriod);
1211  if ( varx == "fitToffPulserMod10" ) {
1212  for ( float& val : vals ) val = fmod(val, 10.0);
1213  }
1214  }
1215  float varfac = 1.0;
1216  if ( varx == "fitHeightNeg" ) varfac = -1.0;
1217  if ( varx == "sigAreaNeg" ) varfac = -1.0;
1218  if ( varx == "fitCSNorm" || varx == "fitCSNormDof" ) {
1219  float pedrms = acd.pedestalRms;
1220  if ( pedrms > 0.0 ) varfac = 1.0/(pedrms*pedrms);
1221  else varfac = 0.0;
1222  }
1223  if ( varx == "fitHeightGain" ) {
1224  if ( ! haveQin ) {
1225  cout << myname << "WARNING: Cannot evaluate " << varx << " without Qin" << endl;
1226  continue;
1227  }
1228  varfac = 1.0/pulserQin;
1229  }
1230  if ( varx == "timeHour" || varx == "procTimeHour" ) varfac = 1/3600.0;
1231  if ( varx == "timeDay" || varx == "procTimeDay" ) varfac = 1/(24*3600.0);
1232  if ( varfac != 1.0 ) for ( float& val : vals ) val *= varfac;
1233  // Create histogram if it does not yet exist or is empty and we have data here.
1234  //if ( ph == nullptr && vals.size() ) {
1235  //if ( ph == nullptr ) {
1236  if ( (ph == nullptr) || (ph->GetEntries() == 0 && vals.size()) ) {
1237  bool replacingHistogram = ph != nullptr;
1238  // Fetch the vector that lists the summary histograms to be plotted for the current template.
1239  // Find or make a place to record this histogram.
1240  HistVector empty;
1241  bool havePlot = plotNameTemplate.size();
1242  HistVector& plotHists = havePlot ? getState().sumPlotHists[plotNameTemplate] : empty;
1243  HistVector::iterator iplotHist = plotHists.end();
1244  if ( replacingHistogram ) {
1245  if ( havePlot ) {
1246  iplotHist = find(plotHists.begin(), plotHists.end(), ph);
1247  if ( iplotHist == plotHists.end() ) {
1248  cout << myname << "ERROR: Unable to find histogram in plot name list." << endl;
1249  plotHists.clear();
1250  iplotHist = plotHists.end();
1251  }
1252  *iplotHist = nullptr;
1253  }
1254  delete ph;
1255  ph = nullptr;
1256  if ( m_LogLevel >= 2 ) cout << myname << "Replacing histogram " << hnam << endl;
1257  } else {
1258  if ( havePlot ) {
1259  plotHists.push_back(nullptr);
1260  iplotHist = plotHists.end();
1261  --iplotHist;
1262  }
1263  if ( m_LogLevel >= 2 ) cout << myname << "Creating histogram " << hnam << endl;
1264  }
1265  Name httl0 = ph0->GetTitle();
1267  int nbin = ph0->GetNbinsX();
1268  float xmin = ph0->GetXaxis()->GetXmin();
1269  float xmax = ph0->GetXaxis()->GetXmax();
1270  // If xmin > xmax and xmin > 0, then we center histogram on median and use width = xmin.
1271  // If also xmax >0, then we round the first bin edge to that value.
1272  if ( vals.size() && xmin > xmax && xmin > 0.0 ) {
1273  FloatVector tmpvals = vals;
1274  std::sort(tmpvals.begin(), tmpvals.end());
1275  Index nval = tmpvals.size();
1276  if ( m_LogLevel >= 3 ) cout << myname << " Centering histogram on median of "
1277  << nval << " value" << (nval==1 ? "" : "s") << endl;
1278  float xmed = 0.5*(tmpvals[(nval-1)/2] + tmpvals[nval/2]);
1279  float width = xmin;
1280  xmin = xmed - 0.5*width;
1281  bool roundXmin = xmax > 0.0;
1282  if ( roundXmin ) {
1283  //float rexp = log10(width/50.0);
1284  //rexp = rexp > 0 ? int(rexp) : int(rexp-1);
1285  //float rfac = pow(10, rexp);
1286  float rfac = xmax;
1287  xmin = rfac*int(xmin/rfac + (xmin > 0.0 ? 0.5 : -0.5));
1288  }
1289  xmax = xmin + width;
1290  // Make sure we have xmax > xmin so Root won't complain when we plot.
1291  } else if ( xmin >= xmax ) {
1292  if ( xmin > 0.0 ) {
1293  xmax = xmin;
1294  xmin = 0;
1295  } else if ( xmin < 0.0 ) {
1296  xmax = 0.0;
1297  } else {
1298  xmin = 0.0;
1299  xmax = 1.0;
1300  }
1301  }
1302  if ( m_LogLevel >= 3 ) {
1303  cout << myname << " Name: " << hnam << endl;
1304  cout << myname << " Title: " << httl << endl;
1305  cout << myname << " nbin: " << nbin << endl;
1306  cout << myname << " xmin: " << xmin << endl;
1307  cout << myname << " xmax: " << xmax << endl;
1308  cout << myname << " fit: " << fitName << endl;
1309  }
1310  bool isTH2 = dynamic_cast<TH2*>(ph0);
1311  if ( ! isTH2 ) {
1312  ph = new TH1F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax);
1313  } else {
1314  int nbiny = ph0->GetNbinsY();
1315  float ymin = ph0->GetYaxis()->GetXmin();
1316  float ymax = ph0->GetYaxis()->GetXmax();
1317  ph = new TH2F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax, nbiny, ymin, ymax);
1318  }
1319  ph->SetDirectory(nullptr);
1320  ph->SetStats(0);
1321  ph->Sumw2(); // Needed for likelihood fit.
1322  ph->SetLineWidth(2);
1323  ph->GetXaxis()->SetTitle(xlab.c_str());
1324  ph->GetYaxis()->SetTitle(ylab.c_str());
1325  if ( ph0->GetListOfFunctions()->GetEntries() ) {
1326  TF1* pf = dynamic_cast<TF1*>(ph0->GetListOfFunctions()->At(0)->Clone());
1327  ph->GetListOfFunctions()->AddLast(pf);
1328  ph->GetListOfFunctions()->SetOwner(kTRUE);
1329  }
1330  getState().sumHistChannels[hnam] = acd.channel();
1331  getState().sumHists[hnam] = ph;
1332  getState().sumFitNames[hnam] = fitName;
1333  if ( plotNameTemplate.size() ) {
1334  Name plotNameHist = AdcChannelStringTool::build(m_adcStringBuilder, acd, plotNameTemplate);
1335  if ( havePlot ) *iplotHist = ph;
1336  if ( ! replacingHistogram ) {
1337  getState().sumPlotNames[hnam] = plotNameHist;
1338  getState().sumPlotWidths[hnam] = hin0.plotWidth;
1339  }
1340  }
1341  }
1342  if ( m_LogLevel >= 3 ) cout << myname << "Filling summary histogram " << hnam
1343  << ". Fill count is " << vals.size() << endl;
1344  FloatVector csds = dm.getFloatVector("roiFitChiSquareDofs");
1345  IntVector fstats = dm.getIntVector("roiFitStats");
1346  bool checkFit = varx.substr(0,3) == "fit";
1347  if ( csds.size() == 0 || fstats.size() == 0 ) checkFit = false;
1348  double chiSquareDofMax = 0.0; // was 1000; should be config param?
1349  if ( checkFit ) {
1350  if ( csds.size() != vals.size() ) {
1351  cout << "ERROR: Variable and chi-square/DF vectors have different sizes." << endl;
1352  checkFit = false;
1353  }
1354  if ( fstats.size() != vals.size() ) {
1355  cout << "ERROR: Variable and fit status vectors have different sizes: "
1356  << vals.size() << " != " << fstats.size() << endl;
1357  checkFit = false;
1358  }
1359  }
1360  Index nval = 0;
1361  Index nvalSkip = 0;
1362  bool logerr = m_LogLevel >= 3 && nhstGood == 0;
1363  for ( Index ival=0; ival<vals.size(); ++ival ) {
1364  ++nval;
1365  if ( checkFit ) {
1366  int fstat = fstats[ival];
1367  float csd = csds[ival];
1368  if ( fstat ) {
1369  if ( logerr) cout << myname << "WARNING: Skipping entry with fit status " << fstat
1370  << " (chi-square/DOF = " << csd << ")" << endl;
1371  ++nvalSkip;
1372  continue;
1373  } else if ( chiSquareDofMax > 0.0 && csd > chiSquareDofMax ) {
1374  if ( logerr) cout << myname << "WARNING: Skipping entry with chi-square/DOF = " << csd << endl;
1375  ++nvalSkip;
1376  continue;
1377  }
1378  }
1379  float val = vals[ival];
1380  double valy = 0.0;
1381  if ( vary == "timingPhase" ) valy = timingPhase;
1382  if ( vary == "event" ) valy = acd.event();
1383  if ( vary == "" ) {
1384  ph->Fill(val);
1385  } else {
1386  ph->Fill(val, valy);
1387  }
1388  }
1389  // Show skips for the first histogram only.
1390  if ( nvalSkip ) {
1391  cout << myname << "WARNING: Skipped " << nvalSkip << " of " << nval
1392  << " entries due to bad fit for histogram " << hnam << "." << endl;
1393  }
1394  ++nhstGood;
1395  }
1396  if ( nhstGood != nhst ) {
1397  cout << myname << "WARNING: Only filled " << nhstGood << " of " << nhst << " histograms." << endl;
1398  }
1399 }
const TimeOffsetTool * m_pTickOffsetTool
Definition: AdcRoiViewer.h:365
intermediate_table::iterator iterator
bool havePulserPeriod() const
Definition: RunData.h:59
const AdcChannelStringTool * m_adcStringBuilder
Definition: AdcRoiViewer.h:363
HistInfoMap sumHistTemplates
Definition: AdcRoiViewer.h:231
Index pulserAmplitude() const
Definition: RunData.h:41
bool havePulserSource() const
Definition: RunData.h:58
const RunDataTool * m_pRunDataTool
Definition: AdcRoiViewer.h:364
AdcIndex subRun() const
IndexByNameMap sumHistChannels
Definition: AdcRoiViewer.h:239
ChannelGroupService::Name Name
Index run() const
Definition: RunData.h:33
const IntVector & getIntVector(Name name) const
Definition: DataMap.h:219
const FloatVector & getFloatVector(Name name) const
Definition: DataMap.h:221
TH1 * getSumHist(Name hnam)
std::vector< TH1 * > HistVector
Definition: AdcRoiViewer.h:193
unsigned int Index
time_t time() const
bool isValid() const
Definition: RunData.h:48
Index fembID() const
virtual Offset offset(const Data &dat) const =0
AdcSignal pedestalRms
Index pulserPeriod() const
Definition: RunData.h:43
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
float m_PulserDacOffset
Definition: AdcRoiViewer.h:339
AdcIndex run() const
virtual RunData runData(Index run, Index subRun=0) const =0
AdcIndex event() const
HistVectorMap sumPlotHists
Definition: AdcRoiViewer.h:234
time_t m_StartTime
Definition: AdcRoiViewer.h:337
std::vector< int > IntVector
Definition: fcldump.cxx:26
State & getState() const
Definition: AdcRoiViewer.h:304
Channel channel() const
float m_PulserStepCharge
Definition: AdcRoiViewer.h:338
Dft::FloatVector FloatVector
AdcLongIndex triggerClock() const
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
QTextStream & endl(QTextStream &s)
bool havePulserAmplitude() const
Definition: RunData.h:57
void AdcRoiViewer::fitSumHists ( ) const

Definition at line 1403 of file AdcRoiViewer_tool.cc.

1403  {
1404  const string myname = "AdcRoiViewer::fitSumHists: ";
1405  if ( getState().sumHists.size() == 0 ) {
1406  cout << myname << "No summary histograms found." << endl;
1407  return;
1408  }
1409  if ( m_LogLevel >= 1 ) cout << myname << "Fitting summary histograms. Count is "
1410  << getState().sumHists.size() << "." << endl;
1411  for ( HistMap::value_type ihst : getState().sumHists ) {
1412  TH1* ph = ihst.second;
1413  string hnam = ph->GetName();
1414  string fitName = getState().getSumFitName(hnam);
1415  bool fitDone = false;
1416  if ( m_LogLevel >= 3 ) cout << myname << "Fitting hist " << ph->GetName() << " with " << fitName << endl;
1417  if ( fitName.size() ) {
1418  TF1* pf = nullptr;
1419  int binMax = ph->GetMaximumBin();
1420  double mean0 = ph->GetBinLowEdge(binMax);
1421  double sigma0 = ph->GetRMS();
1422  double height0 = ph->GetMaximum();
1423  // Use gaus step fit.
1424  if ( fitName.substr(0,5) == "sgaus" ) {
1425  if ( m_LogLevel >= 4 ) cout << myname << " Doing gaus step fit." << endl;
1426  if ( fitName.size() > 5 ) {
1427  istringstream ssin(fitName.substr(5));
1428  ssin >> sigma0;
1429  }
1430  GausStepFitter gsf(mean0, sigma0, height0, fitName, "WWS");
1431  fitDone = gsf.fit(ph) == 0;
1432  // Use gaus from RMS.
1433  } else if ( fitName.substr(0,5) == "rgaus" ) {
1434  if ( m_LogLevel >= 4 ) cout << myname << " Doing fixed rms fit." << endl;
1435  double sigma0 = 0.0;
1436  double nsigma = 4.0;
1437  Name spar1 = fitName.substr(5);
1438  Name spar2;
1439  if ( spar1.size() ) {
1440  if ( spar1[0] == '_' ) spar1 = spar1.substr(1);
1441  string::size_type ipos = spar1.find("_");
1442  if ( ipos != string::npos ) {
1443  spar2 = spar1.substr(ipos+1);
1444  spar1 = spar1.substr(0, ipos);
1445  istringstream ssin2(spar2);
1446  ssin2 >> nsigma;
1447  }
1448  istringstream ssin1(spar1);
1449  ssin1 >> sigma0;
1450  }
1451  GausRmsFitter grf(sigma0, nsigma, fitName);
1452  if ( m_LogLevel >=4 ) grf.setLogLevel(m_LogLevel - 3);
1453  if ( grf.fit(ph, mean0) == 0 ) {
1454  fitDone = true;
1455  } else {
1456  pf = new TF1("mygaus", "gaus");
1457  }
1458  } else {
1459  pf = new TF1(fitName.c_str(), fitName.c_str());
1460  }
1461  if ( m_LogLevel >= 4 && pf != nullptr ) {
1462  cout << myname << " Created function " << pf->GetName() << " at " << std::hex << pf << endl;
1463  }
1464  if ( ! fitDone ) {
1465  if ( m_LogLevel >= 4 ) cout << myname << " Doing unconstrained fit" << endl;
1466  string fopt = "LWWS";
1467  if ( m_LogLevel < 4 ) fopt += "Q";
1468  int fstat = quietHistFit(ph, pf, fopt.c_str());
1469  if ( fstat != 0 ) {
1470  cout << myname << " WARNING: Fit " << pf->GetName() << " of " << ph->GetName() << " returned " << fstat << endl;
1471  ph->GetListOfFunctions()->Clear(); // Otherwise we may get a crash when we try to view saved copy of histo
1472  } else {
1473  if ( m_LogLevel >=4 ) cout << myname << " Fit succeeded." << endl;
1474  }
1475  ph->GetListOfFunctions()->SetOwner(kTRUE); // So the histogram owns pf
1476  }
1477  delete pf;
1478  }
1479  }
1480 }
ChannelGroupService::Name Name
QTextStream & hex(QTextStream &s)
int quietHistFit(TH1 *ph, std::string fname, std::string fopt)
Name getSumFitName(Name hnam) const
State & getState() const
Definition: AdcRoiViewer.h:304
QTextStream & endl(QTextStream &s)
State& AdcRoiViewer::getState ( ) const
inline

Definition at line 304 of file AdcRoiViewer.h.

304 { return *m_state; }
StatePtr m_state
Definition: AdcRoiViewer.h:360
void AdcRoiViewer::setPlotLabels ( Name sttl) const

Definition at line 1990 of file AdcRoiViewer_tool.cc.

1990  {
1991  StringManipulator sman(sttl, false);
1992  for ( NameMap::value_type isub : m_plotLabelSubs ) {
1993  sman.replace(isub.first, isub.second);
1994  }
1995  sttl = sman.str();
1996 }
NameMap m_plotLabelSubs
Definition: AdcRoiViewer.h:357
bool AdcRoiViewer::updateWithView ( ) const
inlineoverridevirtual

Reimplemented from AdcChannelTool.

Definition at line 286 of file AdcRoiViewer.h.

286 { return true; }
DataMap AdcRoiViewer::view ( const AdcChannelData acd) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 590 of file AdcRoiViewer_tool.cc.

590  {
591  DataMap res;
592  doView(acd, m_LogLevel, res);
593  if ( m_RoiRootFileName.size() ) {
595  }
596  return res;
597 }
Name m_RoiRootFileName
Definition: AdcRoiViewer.h:349
void writeRoiHists(const DataMap &res, int dbg) const
int doView(const AdcChannelData &acd, int dbg, DataMap &dm) const
DataMap AdcRoiViewer::viewMap ( const AdcChannelDataMap acds) const
overridevirtual

Reimplemented from AdcChannelTool.

Definition at line 601 of file AdcRoiViewer_tool.cc.

601  {
602  const string myname = "AdcRoiViewer::viewMap: ";
603  DataMap ret;
604  Index ncha = 0;
605  Index nroi = 0;
606  Index nfail = 0;
607  DataMap::IntVector failedChannels;
608  bool save = m_RoiRootFileName.size();
609  Index ndm = save ? acds.size() : 1;
610  int dbg = m_LogLevel > 3 ? m_LogLevel - 2 : 0;
611  Index nacd = acds.size();
612  DataMapVector dms; // Cache to hold results from doView
613  dms.reserve(ndm);
614  Index nroiLimit = save ? 1000 : 1000; // Clear cache after we get this many ROIs.
615  Index nroiCached = 0;
616  for ( const AdcChannelDataMap::value_type& iacd : acds ) {
617  const AdcChannelData& acd = iacd.second;
618  if ( m_LogLevel >= 3 ) {
619  cout << myname << "Processing channel " << acd.channel()
620  << " (" << ncha << "/" << nacd << ")" << endl;
621  }
622  dms.emplace_back();
623  DataMap& dm = dms.back();
624  doView(acd, dbg, dm);
625  if ( dm.status() ) {
626  ++nfail;
627  failedChannels.push_back(acd.channel());
628  }
629  ++ncha;
630  nroi += dm.getInt("roiCount");
631  nroiCached += dm.getInt("roiCount");
632  if ( nroiCached > nroiLimit ) {
633  if ( m_LogLevel >= 3 ) cout << myname << " Clearing result cache." << endl;
634  if ( save && dms.size() ) writeRoiHists(dms, dbg);
635  dms.clear();
636  nroiCached = 0;
637  }
638  }
639  if ( save && dms.size() ) writeRoiHists(dms, dbg);
640  ret.setInt("roiChannelCount", ncha);
641  ret.setInt("roiFailedChannelCount", nfail);
642  ret.setIntVector("roiFailedChannels", failedChannels);
643  ret.setInt("roiCount", nroi);
644  return ret;
645 }
bool dbg
Name m_RoiRootFileName
Definition: AdcRoiViewer.h:349
void writeRoiHists(const DataMap &res, int dbg) const
std::vector< DataMap > DataMapVector
Definition: AdcRoiViewer.h:292
unsigned int Index
std::vector< int > IntVector
Definition: DataMap.h:50
int status() const
Definition: DataMap.h:202
void setIntVector(Name name, const IntVector &val)
Definition: DataMap.h:132
void setInt(Name name, int val)
Definition: DataMap.h:131
int doView(const AdcChannelData &acd, int dbg, DataMap &dm) const
def save(obj, fname)
Definition: root.py:19
Channel channel() const
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::writeChanSumHists ( ) const

Definition at line 1839 of file AdcRoiViewer_tool.cc.

1839  {
1840  const string myname = "AdcRoiViewer::writeChanSumHists: ";
1841  if ( m_ChanSumRootFileName.size() == 0 ) return;
1842  if ( getState().chanSumHists.size() == 0 ) {
1843  cout << myname << "No channel summary histograms found." << endl;
1844  return;
1845  }
1846  Name ofrname = m_ChanSumRootFileName;
1847  TDirectory* savdir = gDirectory;
1848  TFile* pfile = TFile::Open(ofrname.c_str(), "UPDATE");
1849  if ( m_LogLevel >= 1 ) cout << myname << "Writing channel summary histograms. Count is "
1850  << getState().chanSumHists.size() << "." << endl;
1851  for ( HistMap::value_type ihst : getState().chanSumHists ) {
1852  TH1* ph = ihst.second;
1853  TH1* phnew = dynamic_cast<TH1*>(ph->Clone());
1854  phnew->Write();
1855  if ( m_LogLevel >= 2 ) cout << myname << " Wrote " << phnew->GetName() << endl;
1856  }
1857  if ( pfile != nullptr ) pfile->Close();
1858  delete pfile;
1859  if ( m_LogLevel >= 1 ) cout << myname << "Closed summary histogram file " << ofrname << endl;
1860  savdir->cd();
1861 }
ChannelGroupService::Name Name
Name m_ChanSumRootFileName
Definition: AdcRoiViewer.h:351
State & getState() const
Definition: AdcRoiViewer.h:304
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::writeChanSumPlots ( ) const

Definition at line 1865 of file AdcRoiViewer_tool.cc.

1865  {
1866  const string myname = "AdcRoiViewer::writeChanSumPlots: ";
1867  for ( HistMap::value_type ihst : getState().chanSumHists ) {
1868  TH1* ph = ihst.second;
1869  Name hnam = ph->GetName();
1870  Name pnam = getState().getChanSumPlotName(hnam);
1871  if ( pnam.size() == 0 ) continue;
1872  if ( m_LogLevel >= 2 ) cout << myname << "Hist:Plot name: " << hnam << ":" << pnam << endl;
1873  bool isDist = getState().chanSumHistTypes[hnam];
1874  Index wpadx = isDist ? 700 : 1400;
1875  Index wpady = 500;
1876  TPadManipulator* pman = new TPadManipulator(wpadx, wpady);
1877  Name plotOpt = isDist ? "hist" : "p";
1878  pman->add(ph, plotOpt, false);
1879  pman->addAxis();
1880  pman->showUnderflow();
1881  pman->showOverflow();
1882  if ( ! isDist ) {
1883  bool doRange = false;
1884  float ymin = ph->GetMinimum();
1885  float ymax = ph->GetMaximum();
1886  Name yopt;
1887  if ( getState().chanSumPlotYMins.find(hnam) != getState().chanSumPlotYMins.end() ) {
1888  ymin = getState().chanSumPlotYMins[hnam];
1889  doRange = true;
1890  }
1891  if ( getState().chanSumPlotYMaxs.find(hnam) != getState().chanSumPlotYMaxs.end() ) {
1892  ymax = getState().chanSumPlotYMaxs[hnam];
1893  doRange = true;
1894  }
1895  if ( doRange ) {
1896  Name yopt = getState().chanSumPlotYOpts[hnam];
1897  double yfac = 0.0;
1898  if ( yopt == "pamp") {
1899  const RunData& rdat = getState().runData;
1900  if ( rdat.havePulserAmplitude() ) {
1901  yfac = rdat.pulserAmplitude();
1902  } else {
1903  yfac = 10.0;
1904  cout << myname << "WARNING: Scaling option pamp requested without run data." << endl;
1905  }
1906  } else if ( yopt == "pampg14") {
1907  const RunData& rdat = getState().runData;
1908  if ( rdat.havePulserAmplitude() && rdat.haveGain() ) {
1909  yfac = rdat.pulserAmplitude()*rdat.gain()/14.0;
1910  } else {
1911  yfac = 10.0;
1912  cout << myname << "WARNING: Scaling option pampg14 requested without run data." << endl;
1913  }
1914  } else if ( yopt == "nevt") {
1915  yfac = getState().eventCallCount.size();
1916  }
1917  if ( yfac != 0.0 ) {
1918  ymin *= yfac;
1919  ymax *= yfac;
1920  }
1921  // If ymin > ymax and ymin > 0, then we center histogram on median and use width = ymin.
1922  if ( ymin > ymax && ymin > 0.0 ) {
1923  int nval = ph->GetNbinsX();
1924  FloatVector tmpvals(nval);
1925  for ( int ival=0; ival<nval; ++ival ) tmpvals[ival] = ph->GetBinContent(ival+1);
1926  std::sort(tmpvals.begin(), tmpvals.end());
1927  float ymed = 0.5*(tmpvals[(nval-1)/2] + tmpvals[nval/2]);
1928  float width = ymin;
1929  ymin = ymed - 0.5*width;
1930  ymax = ymin + width;
1931  }
1932  if ( ymax > ymin ) {
1933  if ( m_LogLevel >= 2 ) cout << myname << "Setting plot range to (" << ymin << ", " << ymax << ")" << endl;
1934  pman->setRangeY(ymin, ymax);
1935  TH1* php = pman->hist();
1936  double del = 1.e-4*(ymax -ymin);
1937  // Put points on the page.
1938  for ( int ibin=1; ibin<php->GetNbinsX(); ++ibin ) {
1939  if ( php->GetBinContent(ibin) > ymax ) php->SetBinContent(ibin, ymax-del);
1940  if ( php->GetBinContent(ibin) < ymin ) php->SetBinContent(ibin, ymin+del);
1941  }
1942  }
1943  }
1944  }
1945  bool highlightBadChannels = ! isDist;
1946  if ( highlightBadChannels ) {
1947  TH1* php = pman->hist();
1948  LineColors cols;
1949  TGraph* pgb = new TGraph;
1950  TGraph* pgn = new TGraph;
1951  pgb->SetMarkerStyle(4);
1952  pgb->SetMarkerColor(cols.red());
1953  pgn->SetMarkerStyle(4);
1954  pgn->SetMarkerColor(cols.brown());
1955  Index icha0 = php->GetBinLowEdge(1);
1956  Index nbad = 0;
1957  Index nnoi = 0;
1958  for ( int ibin=1; ibin<php->GetNbinsX(); ++ibin ) {
1959  Index icha = icha0 + Index(ibin) - 1;
1960  Index chanStat = getState().getChannelStatus(icha);
1961  if ( chanStat == AdcChannelStatusBad ) {
1962  pgb->SetPoint(nbad++, icha+0.5, php->GetBinContent(ibin));
1963  }
1964  if ( chanStat == AdcChannelStatusNoisy ) {
1965  pgn->SetPoint(nnoi++, icha+0.5, php->GetBinContent(ibin));
1966  }
1967  }
1968  if ( nnoi ) pman->add(pgn, "P");
1969  if ( nbad ) pman->add(pgb, "P");
1970  delete pgb;
1971  delete pgn;
1972  }
1973  if ( m_ChannelLineModulus ) {
1974  for ( Index icha : m_ChannelLinePattern ) {
1976  }
1977  } else {
1978  for ( Index icha : m_ChannelLinePattern ) {
1979  pman->addVerticalLine(icha, 1.0, 3);
1980  }
1981  }
1982  if ( m_LogLevel >= 1 ) cout << myname << "Plotting channel summary " << pnam << endl;
1983  pman->print(pnam);
1984  delete pman;
1985  }
1986 }
Index pulserAmplitude() const
Definition: RunData.h:41
Index m_ChannelLineModulus
Definition: AdcRoiViewer.h:344
const AdcIndex AdcChannelStatusNoisy
Definition: AdcTypes.h:48
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
IndexVector m_ChannelLinePattern
Definition: AdcRoiViewer.h:345
static ColorType red()
Definition: LineColors.h:27
ChannelGroupService::Name Name
FloatMap chanSumPlotYMins
Definition: AdcRoiViewer.h:247
unsigned int Index
TH1 * hist() const
int showOverflow(bool show=true)
float gain() const
Definition: RunData.h:36
FloatMap chanSumPlotYMaxs
Definition: AdcRoiViewer.h:248
Index getChannelStatus(Index icha) const
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
IndexByNameMap chanSumHistTypes
Definition: AdcRoiViewer.h:245
unsigned int Index
Definition: AdcRoiViewer.h:189
int addVerticalModLines(double xmod, double xoff=0.0, double lenfrac=1.0, int isty=3)
State & getState() const
Definition: AdcRoiViewer.h:304
Name getChanSumPlotName(Name hnam) const
bool haveGain() const
Definition: RunData.h:52
int addVerticalLine(double xoff=0.0, double lenfrac=1.0, int isty=1)
const AdcIndex AdcChannelStatusBad
Definition: AdcTypes.h:47
Dft::FloatVector FloatVector
int setRangeY(double y1, double y2)
IndexByIndexMap eventCallCount
Definition: AdcRoiViewer.h:273
static ColorType brown()
Definition: LineColors.h:29
int print(std::string fname, std::string spat="{,}")
QTextStream & endl(QTextStream &s)
bool havePulserAmplitude() const
Definition: RunData.h:57
void AdcRoiViewer::writeRoiHists ( const DataMap res,
int  dbg 
) const

Definition at line 905 of file AdcRoiViewer_tool.cc.

905  {
906  DataMapVector dms(1, dm);
907  writeRoiHists(dms, dbg);
908 }
bool dbg
void writeRoiHists(const DataMap &res, int dbg) const
std::vector< DataMap > DataMapVector
Definition: AdcRoiViewer.h:292
void AdcRoiViewer::writeRoiHists ( const DataMapVector res,
int  dbg 
) const

Definition at line 912 of file AdcRoiViewer_tool.cc.

912  {
913  const string myname = "AdcRoiViewer::writeRoiHists: ";
914  if ( m_RoiRootFileName.size() == 0 ) return;
915  TDirectory* savdir = gDirectory;
916  string ofrnameOld = "";
917  TFile* pfile = nullptr;
918  for ( const DataMap& dm : dms ) {
919  AdcChannelData acd;
920  acd.setEventInfo(
921  dm.getInt("roiRun"),
922  dm.getInt("roiEvent"),
923  dm.getInt("roiSubRun")
924  );
925  acd.setChannelInfo(dm.getInt("roiChannel"));
927  if ( ofrname != ofrnameOld ) {
928  if ( pfile != nullptr ) pfile->Close();
929  delete pfile;
930  if ( m_LogLevel >= 2 ) cout << myname << "Writing histograms to " << ofrname << endl;
931  pfile = TFile::Open(ofrname.c_str(), "UPDATE");
932  ofrnameOld = ofrname;
933  }
934  const DataMap::HistVector& roiHists = dm.getHistVector("roiHists");
935  for ( TH1* ph : roiHists ) {
936  TH1* phnew = dynamic_cast<TH1*>(ph->Clone());
937  phnew->GetListOfFunctions()->SetOwner(kTRUE); // So the histogram owns pfinit
938  phnew->Write();
939  if ( dbg >= 3 ) cout << myname << " Wrote " << phnew->GetName() << endl;
940  }
941  }
942  if ( pfile != nullptr ) pfile->Close();
943  delete pfile;
944  savdir->cd();
945 }
const AdcChannelStringTool * m_adcStringBuilder
Definition: AdcRoiViewer.h:363
bool dbg
Name m_RoiRootFileName
Definition: AdcRoiViewer.h:349
void setChannelInfo(ChannelInfoPtr pchi)
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
void setEventInfo(EventInfoPtr pevi)
std::vector< TH1 * > HistVector
Definition: DataMap.h:57
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::writeRoiPlots ( const HistVector hists,
const AdcChannelData acd 
) const

Definition at line 949 of file AdcRoiViewer_tool.cc.

949  {
950  const string myname = "AdcRoiViewer::writeRoiPlots: ";
951  if ( m_MaxRoiPlots >=0 && getState().nRoiPlot >= Index(m_MaxRoiPlots) ) return;
952  Index npadx = m_RoiPlotPadX;
953  Index npady = m_RoiPlotPadY;
954  Index npad = npadx*npady;
955  if ( npad == 0 ) return;
956  Index wpadx = 1400;
957  Index wpady = 1000;
958  TpmPtr pmantopLocal;
959  TpmPtr& pmantop = m_RoiPlotOpt == 2 ? getState().roiPads[acd.channel()] : pmantopLocal;
960  Name plotFileName;
961  Index ipad = 0;
962  if ( m_RoiPlotOpt == 2 ) {
963  // Fetch the print name.
964  plotFileName = getState().roiPadNames[acd.channel()];
965  // Find the first empty sub pad.
966  if ( pmantop && npad > 1 ) {
967  for ( ipad=0; ipad<npad; ++ipad ) {
968  if ( pmantop->man(ipad)->hist() == nullptr ) break;
969  }
970  if ( ipad >= npad ) {
971  cout << myname << "FATAL: ROI pad is full." << endl;
972  abort();
973  }
974  }
975  }
976  Index ihst = 0;
977  for ( TH1* ph : hsts ) {
978  if ( ph == nullptr ) continue;
979  Name hnam = ph->GetName();
980  if ( ! pmantop ) {
981  plotFileName = hnam.substr(1) + ".png"; // Strip leading h from histogram name.
982  if ( m_RoiPlotOpt == 2 ) {
983  ostringstream sscha;
984  sscha << acd.channel();
985  string scha = sscha.str();
986  while ( scha.size() < 6 ) scha = "0" + scha;
987  ostringstream sspag;
988  sspag << getState().roiPadCounts[acd.channel()];
989  string spag = sspag.str();
990  while ( spag.size() < 3 ) spag = "0" + spag;
991  plotFileName = "roi_chan" + scha + "_" + spag + ".png";
992  getState().roiPadNames[acd.channel()] = plotFileName;
993  }
994  ipad = 0;
995  pmantop.reset(new TPadManipulator);
996  pmantop->setCanvasSize(wpadx, wpady);
997  if ( npad > 1 ) pmantop->split(npadx, npady);
998  if ( m_LogLevel >= 3 ) cout << myname << " Creating plots for " << plotFileName << endl;
999  if ( m_LogLevel >= 4 ) cout << myname << " Plotting " << ph->GetName() << endl;
1000  }
1001  TPadManipulator* pman = pmantop->man(ipad);
1002  pman->add(ph, "hist", false);
1003  pman->addHistFun(0);
1004  TF1* pfit = ph->GetFunction("coldelec");
1005  if ( true ) {
1006  NameVector labs;
1007  double area = ph->Integral();
1008  ostringstream ssout;
1009  ssout.precision(3);
1010  ssout.setf(std::ios_base::fixed);
1011  ssout << "Area: " << area;
1012  labs.push_back(ssout.str());
1013  if ( pfit != nullptr ) {
1014  double height = pfit->GetParameter("Height");
1015  double shaping = pfit->GetParameter("Shaping");
1016  double t0 = pfit->GetParameter("T0");
1017  ssout.str("");
1018  ssout << "Height: " << height;
1019  labs.push_back(ssout.str());
1020  ssout.str("");
1021  ssout << "Shaping: " << shaping << " tick";
1022  labs.push_back(ssout.str());
1023  ssout.str("");
1024  ssout.precision(2);
1025  ssout << "Position: " << t0 << " tick";
1026  labs.push_back(ssout.str());
1027  ssout.str("");
1028  ssout.precision(1);
1029  ssout << "#chi^{2}: " << pfit->GetChisquare();
1030  labs.push_back(ssout.str());
1031  Index chanStat = acd.channelStatus();
1032  if ( chanStat == AdcChannelStatusBad ) labs.push_back("Bad channel");
1033  if ( chanStat == AdcChannelStatusNoisy ) labs.push_back("Noisy channel");
1034  }
1035  double xlab = 0.70;
1036  double ylab = 0.80;
1037  double dylab = 0.04;
1038  for ( Name lab : labs ) {
1039  TLatex* pptl = nullptr;
1040  pptl = new TLatex(xlab, ylab, lab.c_str());
1041  pptl->SetNDC();
1042  pptl->SetTextFont(42);
1043  pptl->SetTextSize(dylab);
1044  pman->add(pptl);
1045  ylab -= 1.2*dylab;
1046  }
1047  }
1048  pman->addAxis();
1049  pman->addHorizontalLine(0.0);
1050  pman->showUnderflow();
1051  pman->showOverflow();
1052  ++ipad;
1053  if ( ipad >= npad || (++ihst >= hsts.size() && m_RoiPlotOpt != 2) ) {
1054  if ( m_LogLevel >= 3 ) cout << myname << " Writing " << plotFileName << endl;
1055  pmantop->print(plotFileName);
1056  pmantop.reset(nullptr);
1057  ++getState().roiPadCounts[acd.channel()];
1058  ipad = 0;
1059  ++getState().nRoiPlot;
1060  if ( m_MaxRoiPlots >=0 && getState().nRoiPlot >= Index(m_MaxRoiPlots) ) return;
1061  }
1062  }
1063 }
code to link reconstructed objects back to the MC truth information
const AdcIndex AdcChannelStatusNoisy
Definition: AdcTypes.h:48
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
ChannelGroupService::Name Name
TpmNameMap roiPadNames
Definition: AdcRoiViewer.h:228
unsigned int Index
int showOverflow(bool show=true)
int addHorizontalLine(double yoff=0.0, double lenfrac=1.0, int isty=1)
Index m_RoiPlotOpt
Definition: AdcRoiViewer.h:333
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
unsigned int Index
Definition: AdcRoiViewer.h:189
TPadManipulator * man(unsigned int ipad=0)
Index m_RoiPlotPadX
Definition: AdcRoiViewer.h:335
State & getState() const
Definition: AdcRoiViewer.h:304
Index channelStatus() const
Channel channel() const
int addHistFun(unsigned int ifun=0)
std::vector< string > NameVector
std::unique_ptr< TPadManipulator > TpmPtr
Definition: AdcRoiViewer.h:203
Index m_RoiPlotPadY
Definition: AdcRoiViewer.h:336
const AdcIndex AdcChannelStatusBad
Definition: AdcTypes.h:47
TpmCountMap roiPadCounts
Definition: AdcRoiViewer.h:229
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::writeSumHists ( ) const

Definition at line 1484 of file AdcRoiViewer_tool.cc.

1484  {
1485  const string myname = "AdcRoiViewer::writeSumHists: ";
1486  bool saveHist = m_SumRootFileName.size();
1487  if ( ! saveHist ) return;
1488  if ( getState().sumHists.size() == 0 ) {
1489  cout << myname << "No summary histograms found." << endl;
1490  return;
1491  }
1492  TDirectory* savdir = gDirectory;
1493  Name ofrname = m_SumRootFileName;
1494  TFile* pfile = TFile::Open(ofrname.c_str(), "UPDATE");
1495  saveHist = pfile != nullptr && pfile->IsOpen();
1496  if ( ! saveHist ) {
1497  cout << myname << "ERROR: Unable to open output file " << ofrname << endl;
1498  return;
1499  }
1500  if ( m_LogLevel >= 1 ) cout << myname << "Writing summary histograms. Count is "
1501  << getState().sumHists.size() << "." << endl;
1502  for ( HistMap::value_type ihst : getState().sumHists ) {
1503  TH1* ph = ihst.second;
1504  TH1* phnew = dynamic_cast<TH1*>(ph->Clone());
1505  if ( saveHist ) phnew->Write();
1506  if ( m_LogLevel >= 2 ) cout << myname << " Wrote " << phnew->GetName() << endl;
1507  }
1508  pfile->Close();
1509  if ( m_LogLevel >= 1 ) cout << myname << "Closed summary histogram file " << ofrname << endl;
1510  savdir->cd();
1511  delete pfile;
1512 }
ChannelGroupService::Name Name
State & getState() const
Definition: AdcRoiViewer.h:304
Name m_SumRootFileName
Definition: AdcRoiViewer.h:350
QTextStream & endl(QTextStream &s)
void AdcRoiViewer::writeSumPlots ( const DataMap pdmin) const

Definition at line 1516 of file AdcRoiViewer_tool.cc.

1516  {
1517  const string myname = "AdcRoiViewer::writeSumPlots: ";
1518  int dbgin = pdmin == nullptr ? 0 : pdmin->getInt("dbg", 0);
1519  Index npad = 0;
1520  Index npadx = m_SumPlotPadX;
1521  Index npady = m_SumPlotPadY;
1522  Index wpadx = 1400;
1523  Index wpady = 1000;
1524  npad = npadx*npady;
1525  Index nvec = getState().sumPlotHists.size();
1526  if ( npad == 0 ) return;
1527  if ( m_LogLevel >= 1 ) cout << myname << "Plotting " << nvec << " set"
1528  << (nvec == 1 ? "" : "s") << " of summary histograms " << endl;
1529  for ( const HistVectorMap::value_type ihv : getState().sumPlotHists ) {
1530  Name plotNameTemplate = ihv.first;
1531  const HistVector& hsts = ihv.second;
1532  TPadManipulator* pmantop = nullptr;
1533  Index ipad = 0;
1534  Name plotFileName;
1535  for ( Index ihst=0; ihst<hsts.size(); ++ihst ) {
1536  TH1* ph = hsts[ihst];
1537  if ( ph == nullptr ) {
1538  cout << myname << "WARNING: Histogram " << ihst << " not found for template " << plotNameTemplate << endl;
1539  } else {
1540  Name hnam = ph->GetName();
1541  bool haveExpectedValue = pdmin != nullptr && pdmin->haveFloat(hnam);
1542  float expValue = haveExpectedValue ? pdmin->getFloat(hnam) : 0.0;
1543  if ( dbgin ) {
1544  cout << myname << " Processing histogram " << hnam << endl;
1545  if ( haveExpectedValue ) cout << myname << " Expected value: " << expValue << endl;
1546  else cout << myname << " No expected value." << endl;
1547  }
1548  if ( pmantop == nullptr ) {
1549  plotFileName = getState().getSumPlotName(hnam);
1550  if ( plotFileName.size() == 0 ) {
1551  cout << myname << "ERROR: Plot file name is not assigned for " << hnam << endl;
1552  break;
1553  }
1554  ipad = 0;
1555  pmantop = new TPadManipulator;
1556  if ( npadx && npady ) pmantop->setCanvasSize(wpadx, wpady);
1557  if ( npad > 1 ) pmantop->split(npadx, npady);
1558  if ( m_LogLevel >= 2 ) cout << myname << " Creating plots for " << plotFileName << endl;
1559  }
1560  if ( m_LogLevel >= 3 ) cout << myname << " Plotting " << ph->GetName() << endl;
1561  TPadManipulator* pman = pmantop->man(ipad);
1562  pman->add(ph, "hist", false);
1563  if ( ph->GetListOfFunctions()->GetEntries() ) {
1564  //dynamic_cast<TF1*>(pman->hist()->GetListOfFunctions()->At(0))->SetNpx(2000);
1565  pman->addHistFun(0);
1566  }
1567  pman->addAxis();
1568  pman->showUnderflow();
1569  pman->showOverflow();
1570  float plotWidth = getState().getSumPlotWidth(hnam);
1571  if ( plotWidth > 0.0 ) {
1572  int binMax = ph->GetMaximumBin();
1573  if ( binMax && binMax <= ph->GetNbinsX() ) {
1574  float xCen = ph->GetBinLowEdge(binMax);
1575  float xmin = xCen - 0.5*plotWidth;
1576  float xmax = xCen + 0.5*plotWidth;
1577  pman->setRangeX(xmin, xmax);
1578  }
1579  }
1580  NameVector labs;
1581  bool showMean = true;
1582  if ( showMean ) {
1583  double mean = ph->GetMean();
1584  double sigm = ph->GetRMS();
1585  float meanDen = haveExpectedValue ? expValue : mean;
1586  ostringstream ssout;
1587  ssout.precision(3);
1588  ssout.setf(std::ios_base::fixed);
1589  ssout.str("");
1590  ssout << "# ROI: " << int(ph->GetEntries() + 0.1);
1591  labs.push_back(ssout.str());
1592  ssout.str("");
1593  ssout << "Hist mean: " << mean;
1594  labs.push_back(ssout.str());
1595  ssout.str("");
1596  ssout << "Hist RMS: " << sigm;
1597  ssout.precision(1);
1598  if ( meanDen != 0.0 ) ssout << " [" << 100*sigm/meanDen << "%]";
1599  ssout.precision(3);
1600  labs.push_back(ssout.str());
1601  if ( haveExpectedValue ) {
1602  ssout.str("");
1603  float bias = mean - expValue;
1604  ssout << "Hist bias: " << bias;
1605  ssout.precision(1);
1606  if ( expValue != 0.0 ) ssout << " [" << 100*bias/expValue << "%]";
1607  ssout.precision(3);
1608  labs.push_back(ssout.str());
1609  }
1610  }
1611  TF1* pffit = dynamic_cast<TF1*>(ph->GetListOfFunctions()->Last());
1612  if ( pffit != nullptr ) {
1613  string fnam = pffit->GetName();
1614  double mean = pffit->GetParameter("Mean");
1615  double sigm = pffit->GetParameter("Sigma");
1616  float meanDen = haveExpectedValue ? expValue : mean;
1617  labs.push_back("Fitter: " + fnam);
1618  ostringstream ssout;
1619  ssout.precision(3);
1620  ssout.setf(std::ios_base::fixed);
1621  ssout << "Fit mean: " << mean;
1622  labs.push_back(ssout.str());
1623  ssout.str("");
1624  ssout << "Fit sigma: " << sigm;
1625  ssout.precision(1);
1626  if ( meanDen != 0.0 ) ssout << " [" << 100*sigm/meanDen << "%]";
1627  ssout.precision(3);
1628  labs.push_back(ssout.str());
1629  if ( haveExpectedValue ) {
1630  ssout.str("");
1631  float bias = mean - expValue;
1632  ssout << "Fit bias: " << bias;
1633  ssout.precision(1);
1634  if ( expValue != 0.0 ) ssout << " [" << 100*bias/expValue << "%]";
1635  ssout.precision(3);
1636  labs.push_back(ssout.str());
1637  }
1638  }
1639  {
1640  ostringstream ssout;
1641  ssout.str("");
1642  Index chanStat = getState().getChannelStatus(ph->GetName());
1643  if ( chanStat == AdcChannelStatusBad ) labs.push_back("Bad channel");
1644  if ( chanStat == AdcChannelStatusNoisy ) labs.push_back("Noisy channel");
1645  }
1646  double xlab = 0.65;
1647  double ylab = 0.80;
1648  double dylab = 0.04;
1649  for ( Name lab : labs ) {
1650  TLatex* pptl = nullptr;
1651  pptl = new TLatex(xlab, ylab, lab.c_str());
1652  pptl->SetNDC();
1653  pptl->SetTextFont(42);
1654  pptl->SetTextSize(dylab);
1655  pman->add(pptl);
1656  ylab -= 1.2*dylab;
1657  }
1658  }
1659  ++ipad;
1660  if ( ipad >= npad || ihst+1 >= hsts.size() ) {
1661  if ( pmantop == nullptr ) {
1662  if ( m_LogLevel >= 2 ) cout << myname << " Not writing empty plot" << endl;
1663  } else {
1664  if ( m_LogLevel >= 2 ) cout << myname << " Writing " << plotFileName << endl;
1665  pmantop->print(plotFileName);
1666  delete pmantop;
1667  pmantop = nullptr;
1668  }
1669  ipad = 0;
1670  }
1671  }
1672  }
1673 }
Index m_SumPlotPadX
Definition: AdcRoiViewer.h:342
float getSumPlotWidth(Name hnam) const
const AdcIndex AdcChannelStatusNoisy
Definition: AdcTypes.h:48
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
ChannelGroupService::Name Name
int setCanvasSize(int wx, int wy)
int split(Index nx, Index ny)
std::vector< TH1 * > HistVector
Definition: AdcRoiViewer.h:193
unsigned int Index
int showOverflow(bool show=true)
Index getChannelStatus(Index icha) const
Index m_SumPlotPadY
Definition: AdcRoiViewer.h:343
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
Name getSumPlotName(Name hnam) const
HistVectorMap sumPlotHists
Definition: AdcRoiViewer.h:234
TPadManipulator * man(unsigned int ipad=0)
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
State & getState() const
Definition: AdcRoiViewer.h:304
int addHistFun(unsigned int ifun=0)
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
std::vector< string > NameVector
bool haveFloat(Name name) const
Definition: DataMap.h:209
int setRangeX(double x1, double x2)
const AdcIndex AdcChannelStatusBad
Definition: AdcTypes.h:47
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
int print(std::string fname, std::string spat="{,}")
QTextStream & endl(QTextStream &s)

Member Data Documentation

const AdcChannelStringTool* AdcRoiViewer::m_adcStringBuilder =nullptr
private

Definition at line 363 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_ChannelLineModulus
private

Definition at line 344 of file AdcRoiViewer.h.

IndexVector AdcRoiViewer::m_ChannelLinePattern
private

Definition at line 345 of file AdcRoiViewer.h.

NameVector AdcRoiViewer::m_ChannelRanges
private

Definition at line 352 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_ChannelRangeTool ="channelRanges"
private

Definition at line 348 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_ChanSumRootFileName
private

Definition at line 351 of file AdcRoiViewer.h.

ChannelRangeMap AdcRoiViewer::m_crmap
private

Definition at line 356 of file AdcRoiViewer.h.

int AdcRoiViewer::m_FitOpt
private

Definition at line 332 of file AdcRoiViewer.h.

int AdcRoiViewer::m_LogLevel
private

Definition at line 328 of file AdcRoiViewer.h.

int AdcRoiViewer::m_MaxRoiPlots
private

Definition at line 334 of file AdcRoiViewer.h.

const IndexRangeTool* AdcRoiViewer::m_pChannelRangeTool =nullptr
private

Definition at line 366 of file AdcRoiViewer.h.

NameVector AdcRoiViewer::m_PlotLabels
private

Definition at line 353 of file AdcRoiViewer.h.

NameMap AdcRoiViewer::m_plotLabelSubs
private

Definition at line 357 of file AdcRoiViewer.h.

const RunDataTool* AdcRoiViewer::m_pRunDataTool =nullptr
private

Definition at line 364 of file AdcRoiViewer.h.

const TimeOffsetTool* AdcRoiViewer::m_pTickOffsetTool =nullptr
private

Definition at line 365 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_PulserChargeUnit
private

Definition at line 340 of file AdcRoiViewer.h.

float AdcRoiViewer::m_PulserDacOffset
private

Definition at line 339 of file AdcRoiViewer.h.

float AdcRoiViewer::m_PulserStepCharge
private

Definition at line 338 of file AdcRoiViewer.h.

int AdcRoiViewer::m_RoiHistOpt
private

Definition at line 331 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_RoiPlotOpt
private

Definition at line 333 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_RoiPlotPadX
private

Definition at line 335 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_RoiPlotPadY
private

Definition at line 336 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_RoiRootFileName
private

Definition at line 349 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_RunDataTool
private

Definition at line 346 of file AdcRoiViewer.h.

float AdcRoiViewer::m_SigThresh
private

Definition at line 329 of file AdcRoiViewer.h.

time_t AdcRoiViewer::m_StartTime
private

Definition at line 337 of file AdcRoiViewer.h.

StatePtr AdcRoiViewer::m_state
private

Definition at line 360 of file AdcRoiViewer.h.

bool AdcRoiViewer::m_SumNegate
private

Definition at line 341 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_SumPlotPadX
private

Definition at line 342 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_SumPlotPadY
private

Definition at line 343 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_SumRootFileName
private

Definition at line 350 of file AdcRoiViewer.h.

Index AdcRoiViewer::m_TickBorder
private

Definition at line 330 of file AdcRoiViewer.h.

Name AdcRoiViewer::m_TickOffsetTool
private

Definition at line 347 of file AdcRoiViewer.h.


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