14 #include "TDirectory.h" 28 using std::ostringstream;
60 if ( adc < adcMin ) adcMin =
adc;
61 if ( adc > adcMax ) adcMax =
adc;
68 if ( dbg ) cout <<
"... " << adc <<
" (" << adcMin <<
", " << adcMax <<
")" <<
endl;
73 return double(adcSum)/double(data.size());
84 : m_LogLevel(ps.
get<
int>(
"LogLevel")),
85 m_TickModPeriod(ps.
get<
Index>(
"TickModPeriod")),
86 m_TimeOffsetTool(ps.
get<
Name>(
"TimeOffsetTool")),
87 m_FitSigmaMin(ps.
get<
float>(
"FitSigmaMin")),
88 m_FitSigmaMax(ps.
get<
float>(
"FitSigmaMax")),
91 m_HistChannelCount(ps.
get<
Index>(
"HistChannelCount")),
92 m_AllPlotFileName(ps.
get<
string>(
"AllPlotFileName")),
93 m_MinPlotFileName(ps.
get<
string>(
"MinPlotFileName")),
94 m_MaxPlotFileName(ps.
get<
string>(
"MaxPlotFileName")),
95 m_PhasePlotFileName(ps.
get<
string>(
"PhasePlotFileName")),
96 m_PhaseVariable(ps.
get<
string>(
"PhaseVariable")),
97 m_RootFileName(ps.
get<
string>(
"RootFileName")),
98 m_TreeFileName(ps.
get<
string>(
"TreeFileName")),
100 m_PlotSizeX(ps.
get<
Index>(
"PlotSizeX")),
101 m_PlotSizeY(ps.
get<
Index>(
"PlotSizeY")),
102 m_PlotShowFit(ps.
get<
Index>(
"PlotShowFit")),
103 m_PlotSplitX(ps.
get<
Index>(
"PlotSplitX")),
104 m_PlotSplitY(ps.
get<
Index>(
"PlotSplitY")),
105 m_PlotFrequency(ps.
get<
Index>(
"PlotFrequency")),
106 m_PhaseGrouping(ps.
get<
Name>(
"PhaseGrouping")),
107 m_PhasePlotSizeX(ps.
get<
Index>(
"PhasePlotSizeX")),
108 m_PhasePlotSizeY(ps.
get<
Index>(
"PhasePlotSizeY")),
109 m_PhasePlotSplitX(ps.
get<
Index>(
"PhasePlotSplitX")),
110 m_PhasePlotSplitY(ps.
get<
Index>(
"PhasePlotSplitY")),
111 m_tickOffsetTool(nullptr),
112 m_varPhase(m_PhaseVariable ==
"phase"),
113 m_varEvent(m_PhaseVariable ==
"event"),
114 m_varTick0(m_PhaseVariable ==
"tick0"),
115 m_varNchan(m_PhaseVariable ==
"nchan"),
116 m_plotAll(m_AllPlotFileName.
size()),
117 m_plotMin(m_MinPlotFileName.
size()),
118 m_plotMax(m_MaxPlotFileName.
size()),
119 m_plotAny(m_plotAll || m_plotMin || m_plotMax),
120 m_plotPhase(m_PhasePlotFileName.
size()),
121 m_makeTree(m_TreeFileName.
size()),
122 m_groupByChannel(m_PhaseGrouping ==
"channel"),
123 m_groupByFemb(m_PhaseGrouping ==
"femb"),
126 const string myname =
"AdcTickModViewer::ctor: ";
128 string stringBuilder =
"adcStringBuilder";
131 cout << myname <<
"WARNING: AdcChannelStringTool not found: " << stringBuilder <<
endl;
134 if ( tname.size() ) {
137 cout << myname <<
"WARNING: Requested TimeOffsetTool not found: " << tname <<
endl;
151 cout << myname <<
"Configuration parameters:" <<
endl;
168 cout << myname <<
" PlotChannels: [";
171 if ( !first ) cout <<
", ";
189 cout << myname <<
"INFO: Checking state." <<
endl;
198 const string myname =
"AdcTickModViewer::dtor: ";
202 if (
m_LogLevel >= 1 ) cout << myname <<
"Plot count: " << nplot <<
endl;
205 if (
m_LogLevel >= 1 ) cout << myname <<
"Plot count: " << nplot <<
endl;
212 if ( acds.size() == 0 )
return ret.
setStatus(0);
223 const string myname =
"AdcTickModViewer::view: ";
226 if (
m_LogLevel >= 3 ) cout << myname <<
"Processing channel " << icha <<
endl;
230 if ( tmhsFull.size() == 0 ) tmhsFull.resize(ntkm,
nullptr);
237 cout << myname <<
"WARNING: Metadata not found in ADC data: " <<
"digi" <<
endl;
242 Index timingPhase = 0;
252 cout << myname <<
"Error finding tick offset: " << off.
status <<
endl;
255 if ( off.
unit !=
"tick" ) {
256 cout << myname <<
"Time offset has wrong unit: " << off.
unit <<
endl;
259 long toff = off.
value;
260 if ( !
state().haveTick0Job ) {
267 if (
m_LogLevel >= 3 ) cout << myname <<
" Tick0: " << tick0 <<
endl;
268 if (
m_LogLevel >= 3 ) cout << myname <<
" Tickmod0: " << itkm0 <<
endl;
273 if (
m_LogLevel >= 3 ) cout << myname <<
" Timing phase: " << timingPhase <<
endl;
281 if (
m_LogLevel >= 3 ) cout << myname <<
"Creating event entry: EventID=" << eventID
282 <<
", ndigi=" << ndigi <<
", tick0=" << std::fixed << tick0 <<
endl;
287 float sigMax = -1.e20;
289 for (
Index itkm=0; itkm<ntkm; ++itkm ) {
290 float& sig = sigMeans[itkm];
292 if ( sig > sigMax || itkm == 0 ) {
301 Index ivar = timingPhase;
306 if ( mtmsForAllPhases.size() < ivar+1 ) mtmsForAllPhases.resize(ivar+1);
309 float ym = itkmMax > 0 ? sigMeans[itkmMax-1] : sigMeans[ntkm-1];
310 float y0 = sigMeans[itkmMax];
311 float yp = itkmMax+1 < ntkm ? sigMeans[itkmMax+1] : sigMeans[0];
312 float den = 2.0*y0 - yp - ym;
314 cout << myname <<
"WARNING: " <<
"Peak not found for channel " << icha <<
endl;
315 cout << myname <<
"itkmMax: " << itkmMax <<
endl;
316 cout << myname <<
"sigs: " << ym <<
", " << y0 <<
", " << yp <<
endl;
318 float xrem = 0.5*(yp - ym)/den;
319 float itkmPeak = itkmMax + xrem;
321 mtms.push_back(itkmPeak);
329 if ( ctmprocs.find(icha) == ctmprocs.end() ) {
337 res.
setInt(
"tmCount", ntkm);
344 const string myname =
"AdcTickModViewer::setChannelData: ";
347 cout << myname <<
"WARNING: Invalid channel index." <<
endl;
363 cout << myname <<
"Adding ADC channel state for channel " << icha <<
endl;
366 copyAcd(acd, newacd);
375 const string myname =
"AdcTickModViewer::setChannel: ";
377 cout << myname <<
"ERROR: Invalid channel index." <<
endl;
381 cout << myname <<
"ERROR: There is no description for channel " << icha <<
endl;
384 copyAcd(
state().acdMap[icha],
state().currentAcd);
393 const string myname =
"AdcTickModViewer::getChannelIndex: ";
401 const string myname =
"AdcTickModViewer::getChannelIndex: ";
404 cout << myname <<
"ERROR: Channel index requested before being set." <<
endl;
413 const string myname =
"AdcTickModViewer::nameReplace: ";
419 while ( stkm0.size() < stkm0Len ) stkm0 =
"0" + stkm0;
421 sman.
replace(
"%TICKMOD%", stkm);
422 sman.
replace(
"%0TICKMOD%", stkm0);
430 const string myname =
"AdcTickModViewer::processChannelTickMod: ";
436 if (
m_LogLevel >= 2 ) cout << myname <<
"WARNING: Raw data is empty." <<
endl;
442 Index isam0 = (itkm + period - itkm0) % period;
443 for (
Index isam=isam0; isam<nsam; isam+=period ) adcData.add(acd.
raw[isam]);
449 bool needHist = ! haveHist;
451 AdcCount hstMin = ph->GetXaxis()->GetXmin() + 0.001;
452 AdcCount hstMax = ph->GetXaxis()->GetXmax() + -0.999;
453 needHist |= adcData.min() < hstMin;
454 needHist |= adcData.max() > hstMax;
460 htitl +=
"; ADC count; # samples";
461 AdcCount adcMin = adcData.min() < 2*border ? 0.0 : adcData.min() - border;
462 AdcCount adcMax = (adcData.max() + 2*border > adcLim) ? adcLim : (adcData.max() + border);
464 AdcCount hstMin = ph->GetXaxis()->GetXmin() + 0.001;
465 AdcCount hstMax = ph->GetXaxis()->GetXmax() + -0.999;
466 if ( hstMin < adcMin ) adcMin = hstMin;
467 if ( hstMax > adcMax ) adcMax = hstMax;
470 float xmax = adcMax + 1.0;
471 int nbin = xmax - xmin + 0.001;
473 if (
m_LogLevel >= 4 ) cout << myname << (haveHist ?
"Re-c" :
"C")
474 <<
"reating histogram " << hname
475 <<
" for channel " << acd.
channel()
476 <<
" tickmod " << itkm
477 <<
": " << nbin <<
": [" << xmin <<
", " << xmax <<
")" <<
endl;
479 cout << myname <<
" adcData.min(): " << adcData.min() <<
endl;
480 cout << myname <<
" adcData.max(): " << adcData.max() <<
endl;
481 cout << myname <<
" adcMin: " << adcMin <<
endl;
482 cout << myname <<
" adcMax: " << adcMax <<
endl;
485 ph.reset(
new TH1F(hname.c_str(), htitl.c_str(), nbin, xmin, xmax));
488 for (
int ibin=1; ibin<=phold->GetNbinsX(); ++ibin ) {
489 int adc = phold->GetXaxis()->GetXmin() - 0.999 + ibin;
490 for (
int icnt=0; icnt<phold->GetBinContent(ibin); ++icnt ) {
494 if (
m_LogLevel > 4 ) cout << myname <<
"Check new hist: " << phold->GetMean() <<
" ?= " << ph->GetMean() <<
endl;
502 sigMean = adcData.mean();
515 const string myname =
"AdcTickModViewer::processAccumulatedChannel: ";
521 Index ntkm = tmhsFull.size();
523 cout << myname <<
"Tickmod hist count: " << ntkm <<
endl;
525 if ( tmhsProc.size() == 0 ) tmhsProc.resize(ntkm,
nullptr);
530 if ( ptree !=
nullptr ) {
539 for (
Index itkm=0; itkm<ntkm; ++itkm ) {
540 const HistPtr& ph = tmhsFull[itkm];
544 if ( scm.evaluate(ph.get()) ) {
545 cout << myname <<
"Sticky code evaluation failed for channel " << icha
546 <<
" tickmod " << itkm <<
endl;
549 tmhsProc[itkm] = scm.getSharedHist();
550 if ( ptree !=
nullptr ) {
562 cout << myname <<
" Plot file count for channel " << icha
563 <<
": " << nplot <<
endl;
576 const string myname =
"AdcTickModViewer::processAccumulation: ";
578 if ( ncha == 0 )
return 0;
585 if (
m_LogLevel >= 2 ) cout << myname <<
"Creating tickmod tree." <<
endl;
586 TDirectory* psavdir = gDirectory;
588 pfile = TFile::Open(tfname.c_str(),
"RECREATE");
589 if ( pfile->IsOpen() ) {
590 ptree =
new TTree(
"tickmod",
"TickMod tree");
591 ptree->Branch(
"data", &(
state().treedata), 64000, 1);
599 if (
m_LogLevel >= 2 ) cout << myname <<
"Processing " << ncha <<
" channels" <<
endl;
600 for ( HistVectorMap::value_type icvm :
state().ChannelTickModFullHists ) {
603 cout << myname <<
"Processing channel " << icha <<
endl;
611 cout << myname <<
" Total plot file count: " << nplotTot <<
endl;
613 if ( pfile !=
nullptr ) {
615 cout << myname <<
"Tree size: " << ptree->GetEntries() <<
endl;
632 const string myname =
"AdcTickModViewer::makeTickModPlots: ";
641 if (
m_LogLevel >= 3 ) cout << myname <<
"Skipping channel not in PlotChannels: " << icha <<
endl;
657 Index itkmMin = 9999;
658 Index itkmMax = 9999;
660 double meanMin = tmhs[0]->GetMean();
661 double meanMax = meanMin;
662 for (
Index itkm=0; itkm<ntkm; ++itkm ) {
663 double mean = tmhs[itkm]->GetMean();
664 if ( mean > meanMax ) {
668 if ( mean < meanMin ) {
674 if (
m_LogLevel >= 3 ) cout << myname <<
"Processing channel " << icha <<
endl;
678 vector<IndexVector> showTickModVectors;
679 vector<Name> showPlotNames;
682 if (
m_LogLevel >= 3 ) cout << myname <<
"Add full vector of " 683 << ntkm <<
" tickmods." <<
endl;
684 showTickModVectors.emplace_back(ntkm);
685 for (
Index itkm=0; itkm<ntkm; ++itkm ) showTickModVectors.back()[itkm] = itkm;
693 int idel1 = 0.4*npad;
695 int idel2 = idel1 + npad;
700 if (
m_LogLevel >= 3 ) cout << myname <<
"Tick delta range: [" << idel1
701 <<
", " << idel2 <<
")" <<
endl;
702 for (
int idel=idel1; idel<idel2; ++idel ) {
703 Index itkm = (itkmMin + ntkm + idel) % ntkm;
704 tkmsMin.push_back(itkm);
705 itkm = (itkmMax + ntkm + idel) % ntkm;
706 tkmsMax.push_back(itkm);
709 if (
m_LogLevel >= 3 ) cout << myname <<
"Adding min vector of " << tkmsMin.size()
710 <<
" tickmods." <<
endl;
711 showTickModVectors.push_back(tkmsMin);
715 if (
m_LogLevel >= 3 ) cout << myname <<
"Adding max vector of " << tkmsMax.size()
716 <<
" tickmods." <<
endl;
717 showTickModVectors.push_back(tkmsMax);
723 for (
Index ihv=0; ihv<showTickModVectors.size(); ++ihv ) {
726 Name pfname = showPlotNames[ihv];
727 if (
m_LogLevel >= 3 ) cout << myname <<
"Plotting " << tkms.size() <<
" tickmods with name " 731 vector<TObject*> managedObjects;
732 for (
Index itkm : tkms ) {
734 if ( pmantop ==
nullptr ) {
737 if ( npad > 1 ) pmantop->
split(npadx, npady);
741 pman->
add(ph.get(),
"hist",
false);
745 TF1* pfun =
dynamic_cast<TF1*
>(ph->GetListOfFunctions()->At(0));
746 if ( pfun !=
nullptr ) {
749 ssout <<
"Mean: " << std::fixed << pfun->GetParameter(1);
750 TLatex* ptxt =
new TLatex(0.72, 0.86, ssout.str().c_str());
752 ptxt->SetTextFont(42);
754 managedObjects.push_back(ptxt);
756 ssout <<
"Sigma: " << std::fixed << pfun->GetParameter(2);
757 ptxt =
new TLatex(0.72, 0.80, ssout.str().c_str());
759 ptxt->SetTextFont(42);
761 managedObjects.push_back(ptxt);
768 if ( ++ipad == npad || icount == tkms.size() ) {
769 if (
m_LogLevel >= 2 ) cout << myname <<
"Saving plot " << plotFileName <<
endl;
770 pmantop->
print(plotFileName);
775 for ( TObject* pobj : managedObjects )
delete pobj;
776 managedObjects.
clear();
788 const string myname =
"AdcTickModViewer::makePhaseGraph: ";
795 if ( ntkm == 0 )
return 0;
799 cout << myname <<
"Building phase-peak graphs for " << ncan
802 for ( IndexVectorMap::value_type iich :
state().phaseChannels ) {
803 Index igrp = iich.first;
808 for (
Index icha : ichas ) {
810 for (
Index ivar=0; ivar<nvar; ++ivar ) {
813 out.insert(out.end(), in.begin(), in.end());
817 string hnam =
"hphtm";
822 string httl = vname +
" vs. tickmod peak for run %RUN% " +
m_PhaseGrouping 825 TGraph* pg =
new TGraph;
826 pg->SetName(hnam.c_str());
827 pg->SetTitle(httl.c_str());
828 pg->SetMarkerStyle(2);
829 pg->SetMarkerColor(602);
830 pg->GetXaxis()->SetTitle(
"Peak position [tick]");
831 pg->GetXaxis()->SetTitle(
"Peak position [tick]");
832 pg->GetXaxis()->SetTitle(
"Peak position [tick]");
833 if (
m_varPhase ) pg->GetYaxis()->SetTitle(
"Timing phase");
834 if (
m_varEvent ) pg->GetYaxis()->SetTitle(
"Event ID");
835 if (
m_varTick0 ) pg->GetYaxis()->SetTitle(
"Event time [Tick]");
836 if (
m_varNchan ) pg->GetYaxis()->SetTitle(
"Channel count");
842 double xmax = -1.e20;
843 double xminShift = 1.e20;
844 double xmaxShift = -1.e20;
845 float xhalf = 0.5*ntkm;
846 for (
Index ivar=0; ivar<nvar; ++ivar ) {
847 for (
float x : xpksByPhase[ivar] ) {
848 if (
x < xmin ) xmin =
x;
849 if (
x > xmax ) xmax =
x;
850 float xs =
x < xhalf ?
x + ntkm :
x;
851 if ( xs < xminShift ) xminShift = xs;
852 if ( xs > xmaxShift ) xmaxShift = xs;
855 bool doShift = (xmax - xmin) > xhalf;
856 doShift &= xmaxShift - xminShift < xmax - xmin;
862 for (
Index ivar=0; ivar<nvar; ++ivar ) {
868 if (
m_LogLevel >= 4 ) cout << myname <<
"Phase " << ivar <<
" peak count: " << xpks.size() <<
endl;
869 Index nxpk = xpks.size();
870 for (
Index ixpk=0; ixpk<nxpk; ++ixpk ) {
871 float x = xpks[ixpk];
872 if ( doShift && x < xhalf ) x += ntkm;
875 pg->SetPoint(pg->GetN(),
x,
y);
878 pg->GetXaxis()->SetRangeUser(xmin, xmax);
890 const string myname =
"AdcTickModViewer::plotPhaseGraphs: ";
892 if (
m_LogLevel >=3 ) cout << myname <<
"Making phase graph plots. Count: " 909 for ( GraphMap::value_type icgr :
state().phaseGraphs ) {
910 Index igrp = icgr.first;
912 TGraph* pg = icgr.second.get();
914 if ( pmantop ==
nullptr ) {
918 if ( npad > 1 ) pmantop->
split(npadx, npady);
924 double xmin =
int(pg->GetXaxis()->GetXmin());
925 double xmax =
int(pg->GetXaxis()->GetXmax() + 1.0);
926 while ( xmax - xmin < 10.0 ) {
931 pman->
add(pg->Clone(),
"P");
938 if ( ++ipad == npad || igrp == igrpLast ) {
939 if (
m_LogLevel >= 2 ) cout << myname <<
"Saving plot " << plotFileName <<
endl;
940 pmantop->
print(plotFileName);
ChannelInfoPtr getChannelInfoPtr() const
int setGridY(bool flag=true)
std::vector< AdcCount > AdcCountVector
void clearChannelIndex() const
HistVectorMap ChannelTickModProcHists
Name nameReplace(Name name, const AdcChannelData &acd, Index itkm) const
std::map< Index, HistVector > HistVectorMap
Index tickModHistogramRebuildCount
void fill(const StickyCodeMetrics &scm)
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
DataMap & setStatus(int stat)
HistVectorMap ChannelTickModFullHists
std::shared_ptr< TH1 > HistPtr
const TimeOffsetTool * m_tickOffsetTool
Coord add(Coord c1, Coord c2)
ChannelGroupService::Name Name
int replace(std::string substr, const T &xsub)
FloatVVectorMap MaxTickMods
Index getChannelIndex() const
int setCanvasSize(int wx, int wy)
int split(Index nx, Index ny)
IndexVector m_PlotChannels
EventInfoPtr getEventInfoPtr() const
int showOverflow(bool show=true)
Q_EXPORT QTSManip setprecision(int p)
AdcChannelData currentAcd
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
void setChannelData(const AdcChannelData &acd) const
void setChannelInfo(ChannelInfoPtr pchi)
void setHistVector(Name name, const HistVector &hsts, bool own=false)
int makePhaseGraphs() const
DataMap view(const AdcChannelData &acd) const override
bool hasMetadata(Name mname) const
Index fembChannel() const
int showUnderflow(bool show=true)
Index setChannel(Index igran) const
void setEventInfo(EventInfoPtr pevi)
int addAxis(bool flag=true)
float getMetadata(Name mname, float def=0.0) const
void setInt(Name name, int val)
static int max(int a, int b)
static constexpr double ps
TPadManipulator * man(unsigned int ipad=0)
std::vector< float > FloatVector
int addVerticalModLines(double xmod, double xoff=0.0, double lenfrac=1.0, int isty=3)
int plotPhaseGraphs() const
Q_EXPORT QTSManip setw(int w)
int addHistFun(unsigned int ifun=0)
DataMap viewMap(const AdcChannelDataMap &acds) const override
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
int processChannelTickMod(const AdcChannelData &acd, Index itkm0, Index itkm, float &sigMean) const
int makeTickModPlots(Index &nplot) const
std::vector< FloatVector > FloatVVector
int setRangeX(double x1, double x2)
int processAccumulation(Index &nplot) const
AdcTickModViewer(fhicl::ParameterSet const &ps)
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
const AdcChannelStringTool * m_adcStringBuilder
IndexVectorMap phaseChannels
auto const & get(AssnsNode< L, R, D > const &r)
Index tickModHistogramInitialCount
std::vector< Index > IndexVector
int setGridX(bool flag=true)
int processAccumulatedChannel(Index &nplot) const
int setRangeY(double y1, double y2)
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
std::string to_string(ModuleType const mt)
int print(std::string fname, std::string spat="{,}")
AdcLongIndex triggerClock() const
std::vector< HistPtr > HistVector
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
QTextStream & endl(QTextStream &s)