23 using std::ostringstream;
40 if ( find(chans.begin(), iven, *iven) == iven ) ++ncha;
48 ichas.insert(pacd->channel());
61 m_Variable(ps.
get<
Name>(
"Variable")),
62 m_ChannelStatusFlag(ps.
get<
Index>(
"ChannelStatusFlag")),
63 m_ChannelSelection(ps.
get<
Name>(
"ChannelSelection")),
64 m_SampleFreq(ps.
get<
float>(
"SampleFreq")),
69 m_HistName(ps.
get<
Name>(
"HistName")),
70 m_HistTitle(ps.
get<
Name>(
"HistTitle")),
73 const string myname =
"AdcChannelDftPlotter::ctor: ";
79 if ( doPwr || doPwt ) {
92 string snameBuilder =
"adcStringBuilder";
96 cout << myname <<
"WARNING: AdcChannelStringTool not found: " << snameBuilder <<
endl;
107 cout << myname <<
"Configuration: " <<
endl;
111 if (
m_skipNoisy ) cout <<
" (skip bad and noisy)";
112 else cout <<
" (skip bad)";
117 if ( doMag || doPwr || doPwt ) cout << myname <<
" NBinX: " <<
m_NBinX <<
endl;
118 if ( doPwr || doPwt ) {
119 cout << myname <<
" XMin: " <<
m_XMin <<
endl;
120 cout << myname <<
" XMax: " <<
m_XMax <<
endl;
121 cout << myname <<
" YMax: " <<
m_YMax <<
endl;
126 cout << myname <<
" HistSummaryTitles: [";
129 if ( first ) first =
false;
140 const string myname =
"AdcChannelDftPlotter::dtor: ";
142 cout << myname <<
"Closing." <<
endl;
144 cout << myname <<
"Channel ranges" <<
endl;
145 cout << myname <<
" CR name count nch/evt" <<
endl;
149 cout << myname <<
setw(15) << crn <<
":" 153 cout << myname <<
"No channel ranges specified." <<
endl;
157 cout << myname <<
"Channel group " << cgn <<
endl;
158 cout << myname <<
" CR name count nch/evt" <<
endl;
164 cout << myname <<
setw(15) << crn <<
":" 169 cout << myname <<
"No channel groups specified." <<
endl;
179 const string myname =
"AdcChannelDftPlotter::viewMapChannels: ";
182 bool doFill = acds.size();
190 if ( doPwr || doPwt ) {
191 TH1* ph = chret.
getHist(
"dftHist");
192 if ( ph !=
nullptr ) {
194 if ( phjob ==
nullptr ) {
195 if ( jobCount == 1 ) {
196 phjob =
dynamic_cast<TH1*
>(ph->Clone());
197 phjob->SetDirectory(
nullptr);
200 cout << myname <<
"ERROR: Hist missing for job count " << jobCount <<
endl;
203 if ( jobCount > 1 ) phjob->Add(ph);
204 else cout << myname <<
"ERROR: Hist existing for job count " << jobCount <<
endl;
207 if ( phevt ==
nullptr ) {
208 if ( evtCount == 1 ) {
209 phevt =
dynamic_cast<TH1*
>(ph->Clone());
210 phevt->SetDirectory(
nullptr);
213 cout << myname <<
"ERROR: Hist missing for event count " << evtCount <<
endl;
216 if ( evtCount > 1 ) phevt->Add(ph);
217 else cout << myname <<
"ERROR: Hist existing for event count " << evtCount <<
endl;
220 Index nven = allchans.size();
221 Index ncha = channelCount(allchans);
232 chret.
setInt(
"dftCRCount", 1);
233 chret.
setInt(
"dftCRIndex", icr);
234 if ( doFill )
fillPad(chret, man);
242 const string myname =
"AdcChannelDftPlotter::viewMapSummary: ";
244 cout << myname <<
"Processing " << cgn <<
"/" << crn <<
" (" << icr <<
"/" << ncr <<
")" <<
endl;
247 cout << myname <<
"ERROR: Invalid level: " << ilev <<
endl;
251 cout << myname <<
"ERROR: Too many plots: " << icr <<
" >= " << ncr <<
endl;
257 float nchanEvt = count > 0 ? double(nchanTot)/count : 0.0;
259 float nvenEvt = count > 0 ? double(nvenTot)/count : 0.0;
261 TH1* phin = levState.
hist(crn);
263 if ( phin !=
nullptr ) {
264 if ( count == 0 )
return 12;
265 ph = (phin ==
nullptr) ?
nullptr : dynamic_cast<TH1*>(phin->Clone());
266 if ( ph ==
nullptr )
return 13;
267 ph->SetDirectory(
nullptr);
274 if ( cglab.size() == 0 ) cglab = cgn;
275 smanTitl.
replace(
"%CGNAME%", cgn);
276 smanTitl.
replace(
"%CGLABEL%", cglab);
277 smanTitl.
replace(
"%CRNAME%", crn);
281 ph->SetTitle(htitl.c_str());
283 double fac = 1.0/
count;
288 dm.
setHist(
"dftHist", ph,
true);
289 dm.
setInt(
"dftEventCount", count);
290 dm.
setFloat(
"dftChanPerEventCount", nchanEvt);
291 dm.
setFloat(
"dftViewEntryPerEventCount", nvenEvt);
294 dm.
setInt(
"dftCRCount", ncr);
295 dm.
setInt(
"dftCRIndex", icr);
296 if ( doFill )
fillPad(dm, man);
305 const string myname =
"AdcChannelDftPlotter::view: ";
312 if (
getLogLevel() >= 3 ) cout << myname <<
"Printing " << pname <<
endl;
339 const string myname =
"AdcChannelDftPlotter::viewLocal: ";
341 cout << myname <<
"Filling CR " << crn <<
" with ADC channel data size " << acds.size() <<
endl;
344 if ( acds.size() == 0 )
return ret;
353 if (
getState().setEventChannelRange(evt, crn) ) {
354 cout << myname <<
"WARNING: Duplicate view of channel range " << crn
355 <<
" in event " << evt <<
endl;
357 if ( pacd ==
nullptr ) {
358 cout << myname <<
"ERROR: First channel has no data." <<
endl;
367 if ( ! doMag && !doPha && !doPwr && !doPwt ) {
368 cout << myname <<
"ERROR: Invalid plot variable: " <<
m_Variable <<
endl;
373 Index nsam = nmag + npha - 1;
375 cout << myname <<
"ERROR: DFT is not present." <<
endl;
378 if ( npha > nmag || nmag - npha > 1 ) {
379 cout << myname <<
"ERROR: DFT is not valid." <<
endl;
383 Index nDataMissing = 0;
384 Index nBadMagCount = 0;
385 Index nBadPhaCount = 0;
387 if ( pacde ==
nullptr ) {
390 if ( pacde->dftmags.size() != nmag ) ++nBadMagCount;
391 if ( pacde->dftphases.size() != npha ) ++nBadPhaCount;
394 if ( nDataMissing ) cout << myname <<
"ERROR: Missing data channel count is " << nDataMissing <<
endl;
395 if ( nBadMagCount ) cout << myname <<
"ERROR: Inconsistent mag size channel count is " << nBadMagCount <<
endl;
396 if ( nBadPhaCount ) cout << myname <<
"ERROR: Inconsistent pha size channel count is " << nBadPhaCount <<
endl;
397 if ( nDataMissing || nBadMagCount || nBadPhaCount )
return ret.
setStatus(4);
401 smanName.
replace(
"%CRNAME%", crn);
404 smanTitl.
replace(
"%CRNAME%", crn);
411 float pi = acos(-1.0);
415 string xtitl = haveFreq ?
"Frequency [kHz]" :
"Frequency index";
416 if ( doMag || doPha ) {
417 if ( acds.size() != 1 ) {
418 cout << myname <<
"ERROR: " << (doMag ?
"Magnitude" :
"Phase")
419 <<
" may only be filled for a single channel." << endl;
422 string ytitl =
"Phase";
426 TGraph* pg =
new TGraph;
427 pg->SetName(hname.c_str());
428 pg->SetTitle(htitl.c_str());
429 pg->SetMarkerStyle(2);
430 pg->SetMarkerColor(602);
434 string xtitl = haveFreq ?
"Frequency [kHz]" :
"Frequency index";
435 pg->GetXaxis()->SetTitle(xtitl.c_str());
436 pg->GetYaxis()->SetTitle(ytitl.c_str());
437 for (
Index ipha=0; ipha<nmag; ++ipha ) {
439 float pha = ipha < npha ? acd.
dftphases[ipha] : 0.0;
441 pha += ( pha > 0 ? -pi :
pi);
445 float y = doPha ? pha : mag;
446 if ( y > yValMax ) yValMax =
y;
447 pg->SetPoint(ipha, x, y);
451 }
else if ( doPwr || doPwt ) {
461 dftChannels.push_back(pacd->
channel());
462 keepAcds.push_back(pacd);
466 Index ncha = channelCount(acds);
467 Index nchaKeep = channelCount(keepAcds);
468 cout << myname <<
" Retaining " << keepAcds.size() <<
" of " << acds.size() <<
" entries in " 469 << nchaKeep <<
" of " << ncha <<
" channels." <<
endl;
471 string ytitl = doPwr ?
"Power" :
"Power/tick";
481 if ( xmin >= xmax ) {
483 xmax = (nmag-1)*xFac;
485 double delx = 0.01*xFac;
491 nbin = (xmax - xmin)/xFac + 0.1;
493 TH1* ph =
new TH1F(hname.c_str(), htitl.c_str(), nbin, xmin, xmax);
494 ph->SetDirectory(
nullptr);
496 ph->GetXaxis()->SetTitle(xtitl.c_str());
497 ph->GetYaxis()->SetTitle(ytitl.c_str());
498 float pwrFac = 1.0/keepAcds.size();
499 if ( ! doPwr ) pwrFac /= nsam;
500 for (
Index imag=0; imag<nmag; ++imag ) {
504 float mag = pacde->dftmags[imag];
506 cout << myname <<
" Channel " << pacde->channel() <<
" sqrt(pwr[" << imag <<
"]): " << mag <<
endl;
512 if ( ph->GetBinContent(nbin+1) && xmax > (nmag-1)*xFac ) {
513 cout << myname <<
"ERROR: Full range histogram has overflow." <<
endl;
515 for (
Index ibin=0; ibin<nbin; ++ibin ) {
516 double y = ph->GetBinContent(ibin);
517 if ( y > yValMax ) yValMax =
y;
520 ret.
setHist(
"dftHist", ph,
true);
523 ret.
setFloat(
"dftYValMax", yValMax);
530 const string myname =
"AdcChannelDftPlotter::fillPad: ";
531 const bool dbg =
false;
532 TGraph* pg = dm.
getGraph(
"dftGraph");
533 TH1* ph = dm.
getHist(
"dftHist");
534 float yValMax = dm.
getFloat(
"dftYValMax");
549 else if ( m_YMax < 0 && -m_YMax > yValMax ) ymax = -
m_YMax;
550 else ymax = yValMax*1.02;
560 bool manyCR = ncr > 1;
563 icr = dm.
getInt(
"dftCRIndex");
564 lastCR = icr + 1 == ncr;
566 if ( pg !=
nullptr ) {
567 xmax = pg->GetXaxis()->GetXmax();
572 pg->SetMarkerColor(icol);
575 }
else if ( ph !=
nullptr ) {
577 if ( icr > 0 ) dopt +=
" same";
579 ph->SetLineColor(icol);
580 if ( dbg ) cout << myname <<
"DEBUG: Color[" << icr <<
"] = " << icol <<
", dopt = " << dopt <<
endl;
584 cout << myname <<
"ERROR: Neither hist or graph is defined." <<
endl;
587 if ( dbg ) cout << myname <<
"DEBUG: CR " << icr <<
"/" << ncr <<
endl;
590 if ( dm.
haveInt(
"dftEventCount") ) {
592 ssout <<
"N_{ev} = " << dm.
getInt(
"dftEventCount");
598 ostringstream ssoutch;
599 ostringstream ssoutve;
600 ssoutch.precision(1);
601 ssoutve.precision(1);
602 if ( dm.
haveFloat(
"dftChanPerEventCount") ) {
603 ssoutch <<
"N_{ch} = " << fixed << dm.
getFloat(
"dftChanPerEventCount");
604 ssoutve <<
"N_{ve} = " << fixed << dm.
getFloat(
"dftViewEntryPerEventCount");
608 Index nven = allchans.size();
611 if ( find(allchans.begin(), iven, *iven) == iven ) ++ncha;
613 ssoutch <<
"N_{ch} = " << ncha;
614 ssoutve <<
"N_{ve} = " << nven;
618 if ( nven != ncha ) {
619 cout <<
"ERROR: View entry count differs from channel count: " 620 << nven <<
" != " << ncha <<
"." <<
endl;
627 sncha = ssoutch.str();
628 snven = ssoutve.str();
633 double sum = ph->Integral(0, ph->GetNbinsX()+1);
635 ssout <<
"#sqrt{#Sigma} = " << fixed <<
setw(2) << sqrt(sum);
640 if ( dbg ) cout << myname <<
"DEBUG: Closing plot." <<
endl;
642 if ( xmax > xmin ) man.
setRangeX(xmin, xmax);
643 if ( ymax > ymin ) man.
setRangeY(ymin, ymax);
647 double textSize = 0.04;
652 double dylab = 1.2*textSize;
654 TLatex* ptxt =
new TLatex(xlab, ylab, spow.c_str());
656 ptxt->SetTextFont(textFont);
657 ptxt->SetTextSize(textSize);
661 if ( sncha.size() ) {
662 TLatex* ptxt =
new TLatex(xlab, ylab, sncha.c_str());
664 ptxt->SetTextFont(textFont);
665 ptxt->SetTextSize(textSize);
669 if ( snven.size() ) {
670 TLatex* ptxt =
new TLatex(xlab, ylab, snven.c_str());
672 ptxt->SetTextFont(textFont);
673 ptxt->SetTextSize(textSize);
677 if ( snevt.size() ) {
678 TLatex* ptxt =
new TLatex(xlab, ylab, snevt.c_str());
680 ptxt->SetTextFont(textFont);
681 ptxt->SetTextSize(textSize);
688 if ( snevt.size() ) {
689 TLatex* ptxt =
new TLatex(xlab, ylab, snevt.c_str());
691 ptxt->SetTextFont(textFont);
692 ptxt->SetTextSize(textSize);
699 TObject* pobj = man.
object();
700 Name lopt = pg ==
nullptr ?
"l" :
"p";
705 double ylmin = ylmax - 0.05*(ncr+0.5);
706 if ( ylmin < 0.40 ) ylmin = 0.40;
707 man.
addLegend(xlmin, ylmin, xlmax, ylmax);
713 if ( pleg !=
nullptr ) {
714 pleg->SetMargin(0.1);
715 if ( spow.size() ) slab +=
" " + spow;
716 if ( sncha.size() ) slab +=
" " + sncha;
717 pleg->AddEntry(pobj, slab.c_str(), lopt.c_str());
726 const string myname =
"AdcChannelDftPlotter::skipChannel: ";
730 for (
Index ipar=0; ipar<npar; ++ipar ) {
731 string spar =
m_ptfsel->GetParName(ipar);
733 cout << myname <<
"WARNING: Skipping run/event/channel " << acd.
run() <<
"/" << acd.
event()
734 <<
"/" << acd.
channel() <<
" because of missing attribute " << spar <<
endl;
Index getLogLevel() const
int setGridY(bool flag=true)
SubState & getSubState(Index ilev) const
std::vector< Name > NameVector
void setFloat(Name name, float val)
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
TLegend * addLegend(double x1, double y1, double x2, double y2)
DataMap beginEvent(const DuneEventInfo &) const override
DataMap & setStatus(int stat)
BaseState & getBaseState() const
Name label(Index ilab=0) const
DataMap endEvent(const DuneEventInfo &) const override
bool skipChannel(const AdcChannelData &acd) const
int replace(std::string substr, const T &xsub)
SubState & getJobState() const
bool haveInt(Name name) const
const IntVector & getIntVector(Name name) const
SubState & getEventState() const
TGraph * getGraph(Name name) const
void setHist(Name name, TH1 *ph, bool own=false)
DataMap viewLocal(Name crn, const AcdVector &acds) const
static ColorType color(Index icolin, Index ncol=size())
const NameVector & getChannelRangeNames() const
Index & nviewentry(Name crn)
float getAttribute(Name mname, float def=0.0) const
std::vector< int > IntVector
void viewSummary(Index ilev) const
void setIntVector(Name name, const IntVector &val)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
String getString(Name name, String def="") const
int viewMapSummary(Index ilev, Name cgn, Name crn, TPadManipulator &man, Index ncr, Index icr) const override
TLegend * getLegend() const
const IndexRangeGroup & getChannelGroup(Name cgn) const
void setString(Name name, String val)
int viewMapChannels(Name crn, const AcdVector &acds, TPadManipulator &man, Index ncr, Index icr) const override
std::unique_ptr< TFormula > m_ptfsel
int setLogY(bool flag=true)
T get(std::string const &key) const
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
void setInt(Name name, int val)
~AdcChannelDftPlotter() override
AdcSignalVector dftphases
static constexpr double ps
NameVector m_HistSummaryTitles
bool hasAttribute(Name mname, float def=0.0) const
AdcChannelDftPlotter(fhicl::ParameterSet const &ps)
Q_EXPORT QTSManip setw(int w)
Float getFloat(Name name, Float def=0.0) const
std::vector< int > IntVector
Index channelStatus() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
int getInt(Name name, int def=0) const
Index m_ChannelStatusFlag
bool haveFloat(Name name) const
const NameVector & getChannelGroupNames() const
int setRangeX(double x1, double x2)
DataMap view(const AdcChannelData &acd) const override
const AdcChannelStringTool * m_adcStringBuilder
void setGraph(Name name, TGraph *pg)
TH1 * getHist(Name name, TH1 *def=nullptr) const
int fillPad(DataMap &dm, TPadManipulator &man) const
auto const & get(AssnsNode< L, R, D > const &r)
int setRangeY(double y1, double y2)
int print(std::string fname, std::string spat="{,}")
std::vector< const AdcChannelData * > AcdVector
QTextStream & endl(QTextStream &s)
Event finding and building.