20 using std::istringstream;
21 using std::ostringstream;
40 VarInfo(
string aname,
const IndexRange&
cr,
string clockUnit);
41 bool isValid()
const {
return vname.size(); }
45 VarInfo::VarInfo(
string aname,
const IndexRange&
cr,
string clockUnit) :
name(aname) {
46 if (
name.
find(
"nfemb") != string::npos ) {
49 }
else if (
name.
find(
"event") != string::npos ) {
52 }
else if (
name.
find(
"clock") != string::npos ) {
54 label =
"Timing clock";
56 }
else if (
name.
find(
"time") != string::npos ) {
60 }
else if (
name.
find(
"rmPedPower") != string::npos ) {
62 label =
"Pedestal noise RMS";
64 }
else if (
name.
find(
"meanPed") != string::npos ) {
66 label =
"Pedestal mean";
71 string formatValue(
float val,
string styp) {
74 string sval = ssval.str();
75 if ( styp ==
"event" ) {
76 while ( sval.size() < 8 ) sval =
"0" + sval;
88 const string myname =
"AdcEventViewer::State::runString: ";
89 if ( eventInfo.isValid() )
return eventInfo.runString();
90 if ( runSet.size() == 0 )
return "<no-runs>";
91 if ( runSet.size() > 1 ) {
92 cout << myname <<
"WARNING: Multiple runs have been processed:";
94 for (
Index irun : runSet ) {
95 if ( first ) first =
false;
100 return "<multiple-runs>";
103 evi.
run = *runSet.begin();
112 : m_LogLevel(ps.
get<
int>(
"LogLevel")),
116 m_ChannelRangeLabel(ps.
get<
Name>(
"ChannelRangeLabel")),
117 m_ClockUnit(ps.
get<
Name>(
"ClockUnit")),
118 m_ClockRate(ps.
get<double>(
"ClockRate")),
120 const string myname =
"AdcEventViewer::ctor: ";
122 bool toolNotFound =
false;
126 if ( crn.size() == 0 || crn ==
"all" ) {
127 m_crs.emplace_back(
"all", 0, 0,
"All");
129 if ( pcrt ==
nullptr && !toolNotFound ) {
131 if ( pcrt ==
nullptr ) {
132 cout << myname <<
"ERROR: IndexRangeTool not found: channelRanges" <<
endl;
135 if ( pcrt !=
nullptr ) {
138 m_crs.push_back(ran);
140 cout << myname <<
"WARNING: Channel range not found: " << crn <<
endl;
148 cout << myname <<
" EventHists: [" <<
endl;
152 cout << myname <<
" " <<
"]" <<
endl;
153 cout << myname <<
" EventGraphs: [" <<
endl;
157 cout << myname <<
" " <<
"]" <<
endl;
158 cout << myname <<
" ChannelRanges: [";
161 if ( ! first ) cout <<
", ";
168 cout << myname <<
" ClockRate: " <<
m_ClockRate <<
" tick/sec" <<
endl;
172 const string::size_type& npos = string::npos;
178 cout << myname <<
"WARNING: invalid clock unit changed to tick" <<
endl;
186 cout << myname <<
"WARNING: Skipping duplicate CR name: " << crn <<
endl;
197 string::size_type ipos = 0;
198 string::size_type jpos = 0;
200 jpos = hspec.find(
":");
201 if ( jpos != npos ) {
202 basename = hspec.substr(ipos, jpos-ipos);
204 jpos = hspec.find(
":", ipos);
205 if ( jpos != npos && jpos > ipos ) {
206 istringstream ssnbin(hspec.substr(ipos, jpos-ipos));
209 jpos = hspec.find(
":", ipos);
210 if ( jpos != npos && jpos > ipos ) {
211 istringstream ssxmin(hspec.substr(ipos, jpos-ipos));
215 istringstream ssxmax(hspec.substr(ipos, jpos-ipos));
222 cout <<
"WARNING: Invalid histogram configuration string: " << hspec <<
endl;
226 if ( crn !=
"all " ) hname +=
"_" + crn;
228 if ( basename.find(
"nfemb") != string::npos ) {
230 }
else if ( basename.find(
"rmPedPower") != string::npos ) {
231 vname =
"rmPedPower";
232 }
else if ( basename.find(
"meanPed") != string::npos ) {
235 cout << myname <<
"ERROR: No variable for histogram name " << hname <<
endl;
239 string sttl = vinfo.label;
240 sttl +=
";" + vinfo.label;
241 Name unit = vinfo.unit;
242 if ( unit.size() ) sttl +=
" [" + unit +
"]";
245 cout << myname <<
"Creating in histogram " << hname <<
", nbin=" << nbin
246 <<
", range=(" << xmin <<
", " << xmax <<
")" <<
endl;
248 TH1* ph =
new TH1F(hname.c_str(), sttl.c_str(), nbin, xmin, xmax);
249 ph->SetDirectory(
nullptr);
252 crstate.
hists.push_back(ph);
253 if (
m_LogLevel>= 1 ) cout << myname <<
"Created histogram " << hname <<
endl;
256 if (
m_LogLevel >= 2 ) cout << myname <<
"Building graph info" <<
endl;
265 string::size_type ipos = 0;
266 string::size_type jpos = 0;
268 jpos = gspec.find(
":");
270 if ( jpos != npos ) {
271 xname = gspec.substr(ipos, jpos-ipos);
273 jpos = gspec.find(
":", ipos);
274 if (
m_LogLevel >= 2 ) cout << myname <<
" xname: " << xname <<
endl;
277 if ( jpos != npos && jpos > ipos ) {
279 if ( isalpha(gspec[ipos]) ) {
280 if (
m_LogLevel >= 2 ) cout << myname <<
" Taking x range from tool." <<
endl;
281 istringstream ssnran(gspec.substr(ipos, jpos-ipos));
282 Name ranName = gspec.substr(ipos, jpos-ipos);
284 if ( pcrt ==
nullptr ) {
285 cout << myname <<
"ERROR: Unable to find index range tool jobRanges" <<
endl;
292 cout << myname <<
"ERROR: Unable to find job range " << ranName <<
endl;
296 jpos = gspec.find(
":", ipos);
297 if ( jpos != npos && jpos > ipos ) {
298 istringstream ssxoff(gspec.substr(ipos, jpos-ipos));
303 if (
m_LogLevel >= 2 ) cout << myname <<
" Using explicit x range." <<
endl;
304 istringstream ssxmin(gspec.substr(ipos, jpos-ipos));
307 jpos = gspec.find(
":", ipos);
308 if ( jpos != npos && jpos > ipos ) {
309 istringstream ssxmax(gspec.substr(ipos, jpos-ipos));
315 jpos = gspec.find(
":", ipos);
317 if ( jpos != npos && jpos > ipos ) {
318 yname = gspec.substr(ipos, jpos-ipos);
320 jpos = gspec.find(
":", ipos);
321 if (
m_LogLevel >= 2 ) cout << myname <<
" yname: " << yname <<
endl;
324 if ( jpos != npos && jpos > ipos ) {
326 if ( isalpha(gspec[ipos]) ) {
327 if (
m_LogLevel >= 2 ) cout << myname <<
" Taking y range from tool." <<
endl;
328 istringstream ssnran(gspec.substr(ipos, jpos-ipos));
329 Name ranName = gspec.substr(ipos, jpos-ipos);
330 cout << myname <<
"Taking y-range from job range " << ranName <<
endl;
332 if ( pcrt ==
nullptr ) {
333 cout << myname <<
"ERROR: Unable to find index range tool jobRanges" <<
endl;
340 cout << myname <<
"ERROR: Unable to fund job range " << ranName <<
endl;
344 jpos = gspec.find(
":", ipos);
345 if ( jpos != npos && jpos > ipos ) {
346 istringstream ssyoff(gspec.substr(ipos, jpos-ipos));
351 if (
m_LogLevel >= 2 ) cout << myname <<
" Using explicit y range." <<
endl;
352 istringstream ssymin(gspec.substr(ipos, jpos-ipos));
355 jpos = gspec.find(
":", ipos);
357 istringstream ssymax(gspec.substr(ipos, jpos-ipos));
364 bool ok = xvin.isValid() && yvin.isValid();
366 cout << myname <<
"WARNING: Invalid graph configuration string: " << gspec <<
endl;
369 string sttl = yvin.label +
" vs. " + xvin.label;
371 cout << myname <<
"Creating graph of " << yname;
372 if ( ymax > ymin ) cout <<
" range=(" << ymin - yoff <<
", " << ymax + yoff <<
")";
373 else if ( ymax >= 0.0 ) cout <<
" range from data with border " << yoff <<
endl;
374 cout <<
" vs. " << xname;
375 if ( xmax > xmin ) cout <<
" range=(" << xmin <<
", " << xmax <<
")";
376 else if ( xmax >= 0.0 ) cout <<
" range from data with border " << xoff <<
endl;
379 crstate.
graphs.emplace_back(xname, xvin.label, xvin.unit, xmin, xmax, xoff,
380 yname, yvin.label, yvin.unit, ymin, ymax, yoff );
381 if (
m_LogLevel>= 1 ) cout << myname <<
"Created graph info for " << yname <<
" vs. " << xname <<
endl;
389 const string myname =
"AdcEventViewer::dtor: ";
392 cout << myname <<
"Unique event count: " <<
state().
events.size() <<
endl;
395 cout << myname <<
"Exiting." <<
endl;
401 const string myname =
"AdcEventViewer::beginEvent: ";
404 cout << myname <<
"Begin processing event " << devt.
event <<
" for run " << devt.
run;
408 if (
state().haveEvent() ) {
409 cout << myname <<
"WARNING: Begin called wth event " << devt.
event 411 <<
". Ending current event." <<
endl;
422 const string myname =
"AdcEventViewer::endEvent: ";
424 cout << myname <<
"End processing event " << devt.
event <<
" for run " << devt.
run;
436 const string myname =
"AdcEventViewer::view: ";
439 <<
" (FEMB " << acd.
fembID() <<
")" 440 <<
" in run " << acd.
run() <<
" event " << acd.
event() <<
endl;
443 cout << myname <<
"ERROR: Run:event from data " << acd.
run() <<
":" << acd.
event()
444 <<
" does not match that from beginEvent " 451 if (
cr.name !=
"all" && !
cr.contains(acd.
channel()) )
continue;
457 crstate.
pedPower += pedNoise*pedNoise;
465 const string myname =
"AdcEventViewer::viewMap: ";
467 Index ncha = acds.size();
468 cout << myname <<
"Processing " << ncha <<
" channel" << (ncha == 1 ?
"" :
"s");
471 cout <<
" in run " << acd.
run() <<
" event " << acd.
event();
476 if (
state().beginEventCount == 0 ) {
477 if ( acds.size() == 0 ) {
478 if (
m_LogLevel >=2 ) cout << myname <<
"Skipping group with no data" <<
endl;
485 for (
const AdcChannelDataMap::value_type& iacd : acds )
view(iacd.second);
492 const string myname =
"AdcEventViewer::crstate: ";
494 if ( icrs ==
state().crstates.end() ) {
495 cout << myname <<
"ERROR: There is no substate for channel range " << crn <<
endl;
505 const string myname =
"AdcEventViewer::beginEventState: ";
506 if (
state().haveEvent() ) {
507 cout <<
"WARNING: Begin called during event processing. Ending current event." <<
endl;
513 cout << myname <<
"ERROR: change in run number is not (yet) supported." <<
endl;
539 const string myname =
"AdcEventViewer::endEventState: ";
541 cout << myname <<
"ERROR: End called without an active event." <<
endl;
545 cout << myname <<
"ERROR: End called without incorrect event info." <<
endl;
558 if ( clkunit ==
"ktick" ) xclk *= 0.001;
559 else if ( clkunit ==
"Mtick" ) xclk *= 0.000001;
560 else if ( clkunit ==
"Gtick" ) xclk *= 0.000000001;
565 cout << myname <<
" # duplicate events: " <<
setw(w) << ndup <<
endl;
567 cout << myname <<
" clock: " <<
setw(w+3) << fixed <<
setprecision(2) << xclk <<
" " << clkunit <<
endl;
575 float meanPed = nchn > 0 ? crstate.
pedSum/nchn : 0.0;
576 float meanPedPower = nchn > 0 ? crstate.
pedPower/nchn : 0.0;
577 float rmPedPower = sqrt(meanPedPower);
578 double chanPerFemb = nfmb > 0 ? double(nchn)/nfmb : 0.0;
580 cout << myname <<
"----- Channel range " <<
cr.label() <<
":" <<
endl;
581 cout << myname <<
" # FEMBs: " <<
setw(w) << nfmb <<
endl;
582 cout << myname <<
" # channels: " <<
setw(w) << nchn <<
endl;
583 cout << myname <<
" # channels/FEMB: " <<
setw(w+5) << fixed <<
setprecision(4) << chanPerFemb <<
endl;
584 cout << myname <<
" Mean pedestal: " <<
setw(w+3) << fixed <<
setprecision(2) << meanPed <<
endl;
585 cout << myname <<
" RM pedestal power: " <<
setw(w+3) << fixed <<
setprecision(2) << rmPedPower <<
endl;
587 for ( TH1* ph : crstate.
hists ) {
588 string name = ph->GetName();
589 if ( name.find(
"nfemb") != string::npos ) ph->Fill(nfmb);
590 else if ( name.find(
"rmPedPower") != string::npos ) ph->Fill(rmPedPower);
591 else if ( name.find(
"meanPed") != string::npos ) ph->Fill(meanPed);
593 cout << myname <<
"ERROR: No variable for histogram name " << name <<
endl;
598 gin.
add(
"clock", xclk);
599 gin.
add(
"time", time);
600 gin.
add(
"nfemb", nfmb);
601 gin.
add(
"rmPedPower", rmPedPower);
602 gin.
add(
"meanPed", meanPed);
611 const string myname =
"AdcEventViewer::displayHists: ";
614 if ( nevt == 0 ) sttlSuf +=
" with no events.";
615 else if ( nevt == 1 ) sttlSuf +=
" event " +
to_string(*
state().eventSet.begin());
619 evstring +=
"_event" + formatValue(*
state().eventSet.cbegin(),
"event");
621 evstring +=
"-" + formatValue(*
state().eventSet.crbegin(),
"event");
627 if (
m_LogLevel >= 1 ) cout << myname <<
"Creating " << nplt <<
" plot" 628 << (nplt == 1 ?
"" :
"s") << sttlSuf
629 << (nplt > 0 ?
":" :
"") <<
endl;
630 for ( TH1* ph : crstate.
hists ) {
633 string sttl = ph->GetTitle() + sttlSuf;
638 smlab.
replace(
"%CRLABEL1%",
cr.label(1));
639 smlab.
replace(
"%CRLABEL2%",
cr.label(2));
640 if ( crlab.size() ) sttl +=
" " + crlab;
644 + evstring +
"_" +
cr.name +
".{png,tpad}";
657 const string myname =
"AdcEventViewer::displayGraphs: ";
663 string sttlSuf = sttlSufBase;
664 if ( nevt == 0 ) sttlSuf +=
" with no events.";
665 else if ( nevt == 1 ) sttlSuf +=
" event " +
to_string(*
state().eventSet.begin());
667 if (
m_LogLevel >= 1 ) cout << myname <<
"Creating " << nplt <<
" graph" 668 << (nplt == 1 ?
"" :
"s") << sttlSuf
669 << (nplt > 0 ?
":" :
"") <<
endl;
674 smlab.
replace(
"%CRLABEL1%",
cr.label(1));
675 smlab.
replace(
"%CRLABEL2%",
cr.label(2));
676 if ( crlab.size() ) sttlSuf +=
" " + crlab;
681 cout << myname <<
"Skipping graph with no entries." <<
endl;
684 if ( gin.
yvals.size() != npt ) {
685 cout << myname <<
"Skipping graph with inconsistent entries." <<
endl;
688 TGraph* pg =
new TGraph(npt, &gin.
xvals[0], &gin.
yvals[0]);
689 pg->GetXaxis()->SetTitle(gin.
xAxisLabel().c_str());
690 pg->GetYaxis()->SetTitle(gin.
yAxisLabel().c_str());
691 pg->SetMarkerStyle(2);
692 double xmin = gin.
xmin;
693 double xmax = gin.
xmax;
694 double xoff = gin.
xoff;
695 double ymin = gin.
ymin;
696 double ymax = gin.
ymax;
697 double yoff = gin.
yoff;
698 bool setXLimitsFromData = pg->GetN() && xmax == xmin && xmax >= 0.0;
699 bool setYLimitsFromData = pg->GetN() && ymax == ymin && ymax >= 0.0;
700 if ( setXLimitsFromData || setYLimitsFromData ) {
706 for (
int ipt=0; ipt<pg->GetN(); ++ipt ) {
707 pg->GetPoint(ipt, xpt, ypt);
714 if ( xpt < xdmin ) xdmin = xpt;
715 if ( xpt > xdmax ) xdmax = xpt;
716 if ( ypt < ydmin ) ydmin = ypt;
717 if ( ypt > ydmax ) ydmax = ypt;
720 if ( setXLimitsFromData ) {
725 cout << myname <<
" Setting graph X range from data (" << xdmin <<
", " << xdmax <<
") to (" 726 << xmin-xoff <<
", " << xmax+xoff <<
")" <<
endl;
729 if ( setYLimitsFromData ) {
734 cout << myname <<
" Setting graph Y range from data (" << ydmin <<
", " << ydmax <<
") to (" 735 << ymin-yoff <<
", " << ymax+yoff <<
")" <<
endl;
739 if ( xmax > xmin ) pg->GetXaxis()->SetRangeUser(xmin-xoff, xmax+xoff);
740 if ( ymax > ymin ) pg->GetYaxis()->SetRangeUser(ymin-yoff, ymax+yoff);
743 string sttl = gin.
ylab +
" vs. " + gin.
xlab + sttlSuf;
750 if ( xmax > xmin ) man.
setRangeX(xmin-xoff, xmax+xoff);
751 if ( ymax > ymin ) man.
setRangeY(ymin-yoff, ymax+yoff);
752 ostringstream ssfname;
753 ssfname <<
"eviewg_" << gin.
varx;
754 if ( gin.
xmax > gin.
xmin ) ssfname <<
"-" << formatValue(gin.
xmin, gin.
varx)
755 <<
"-" << formatValue(gin.
xmax, gin.
varx);
756 ssfname <<
"_" << gin.
vary;
757 if ( gin.
ymax > gin.
ymin ) ssfname <<
"-" << formatValue(gin.
ymin, gin.
vary)
758 <<
"-" << formatValue(gin.
ymax, gin.
vary);
760 ssfname <<
"_" <<
cr.name;
761 ssfname <<
".{png,tpad}";
int setGridY(bool flag=true)
const DuneEventInfo & getEventInfo() const
void add(Name var, float val)
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
DataMap & setStatus(int stat)
DataMap endEvent(const DuneEventInfo &devt) const override
int replace(std::string substr, const T &xsub)
int find(char c, int index=0, bool cs=TRUE) const
DataMap view(const AdcChannelData &acd) const override
int showOverflow(bool show=true)
Q_EXPORT QTSManip setprecision(int p)
void displayGraphs() const
DataMap beginEvent(const DuneEventInfo &devt) const override
int setTitle(std::string sttl, float height=-1.0)
AdcEventViewer(fhicl::ParameterSet const &ps)
ChannelRangeStates crstates
int showUnderflow(bool show=true)
std::string runString() const
int addAxis(bool flag=true)
static constexpr double ps
std::string runString(Index opt=2) const
Q_EXPORT QTSManip setw(int w)
void beginEventState(const DuneEventInfo &devt) const
ChannelRangeState & crstate(Name crn) const
NameVector m_ChannelRanges
void displayHists() const
int setRangeX(double x1, double x2)
void endEventState(const DuneEventInfo &devt) const
~AdcEventViewer() override
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
auto const & get(AssnsNode< L, R, D > const &r)
int setGridX(bool flag=true)
DataMap viewMap(const AdcChannelDataMap &acds) const override
int setRangeY(double y1, double y2)
std::string to_string(ModuleType const mt)
int print(std::string fname, std::string spat="{,}")
QTextStream & endl(QTextStream &s)
std::vector< Name > NameVector