14 #include "TDirectory.h" 23 using std::ostringstream;
36 : m_LogLevel(ps.
get<
int>(
"LogLevel")),
40 m_RootFileName(ps.
get<
string>(
"RootFileName")),
41 m_PlotFileName(ps.
get<
string>(
"PlotFileName")),
42 m_PlotSamMin(ps.
get<
Index>(
"PlotSamMin")),
43 m_PlotSamMax(ps.
get<
Index>(
"PlotSamMax")),
44 m_PlotSigOpt(ps.
get<
string>(
"PlotSigOpt")),
45 m_PlotSigMin(ps.
get<
float>(
"PlotSigMin")),
46 m_PlotSigMax(ps.
get<
float>(
"PlotSigMax")),
47 m_PlotDistMin(ps.
get<
float>(
"PlotDistMin")),
48 m_PlotDistMax(ps.
get<
float>(
"PlotDistMax")),
49 m_ColorBad(ps.
get<
Index>(
"ColorBad")),
50 m_ColorNoisy(ps.
get<
Index>(
"ColorNoisy")),
51 m_LabelSize(ps.
get<
float>(
"LabelSize")),
53 const string myname =
"AdcChannelPlotter::ctor: ";
55 cout << myname <<
"WARNING: No histogram types are specified." <<
endl;
59 string stringBuilder =
"adcStringBuilder";
62 cout << myname <<
"WARNING: AdcChannelStringTool not found: " << stringBuilder <<
endl;
65 if (
m_LogLevel >= 1 ) cout << myname <<
"Fetching channel status service." <<
endl;
68 cout << myname <<
"WARNING: Channel status provider not found." <<
endl;
76 cout << myname <<
" HistTypes: [";
79 if ( ! first ) cout <<
", ";
98 cout << myname <<
" SkipFlags: [";
100 for (
Index flg : m_SkipFlags ) {
101 if ( first ) first =
false;
117 const string myname =
"AdcChannelPlotter::view: ";
121 cout << myname <<
"WARNING: No histogram types are specified." <<
endl;
125 if ( hnameBase ==
"" ) hnameBase =
"%TYPE%";
127 if ( htitlBase ==
"" ) htitlBase =
"%TYPE%";
128 TDirectory* polddir = gDirectory;
129 TFile* pfile =
nullptr;
132 pfile = TFile::Open(fname.c_str(),
"UPDATE");
135 bool resManage =
true;
140 bool isRawDist =
type ==
"rawdist" ||
type ==
"rawdistlog";
141 if (
type ==
"raw" ) {
144 cout << myname <<
"WARNING: Raw data is empty." <<
endl;
147 htitl +=
"; Tick; ADC count";
148 ph =
new TH1F(hname.c_str(), htitl.c_str(), nsam, 0, nsam);
150 float sigMin = acd.
raw[0];
151 float sigMax = sigMin;
152 for (
Index isam=0; isam<nsam; ++isam ) {
153 float sig = acd.
raw[isam];
154 ph->SetBinContent(isam+1, sig);
156 if ( sig < sigMin ) sigMin = sig;
157 if ( sig > sigMax ) sigMax = sig;
162 }
else if ( isRawDist ) {
165 cout << myname <<
"WARNING: Raw data is empty." <<
endl;
171 for (
Index isam=0; isam<nsam; ++isam ) {
172 if ( isam >= acd.
flags.size() ) {
173 if (
m_LogLevel >= 2 ) cout << myname <<
"WARNING: flags are missing." <<
endl;
181 if (
m_LogLevel >= 2 ) cout << myname <<
"WARNING: No raw data is selected." <<
endl;
185 bool useExistingHist =
m_HistName.find(
"%EVENT%") == string::npos;
186 if ( useExistingHist ) {
188 if ( ihst !=
getState().hists.end() ) ph = ihst->second;
191 if ( ph ==
nullptr ) {
192 htitl +=
"; ADC count; # samples";
193 unsigned int nadc = 4096;
194 ph =
new TH1F(hname.c_str(), htitl.c_str(), nadc, 0, nadc);
195 if ( ! useExistingHist ) hists.push_back(ph);
198 float sigMin = acd.
raw[0];
199 float sigMax = sigMin;
200 for (
Index isam=0; isam<nsam; ++isam ) {
201 float sig = acd.
raw[isam];
202 if ( keep[isam] ) ph->Fill(sig);
204 if ( sig < sigMin ) sigMin = sig;
205 if ( sig > sigMax ) sigMax = sig;
210 }
else if (
type ==
"prepared" ) {
213 cout << myname <<
"WARNING: Prepared data is empty." <<
endl;
216 htitl +=
"; Tick; Signal";
220 ph =
new TH1F(hname.c_str(), htitl.c_str(), nsam, 0, nsam);
223 float sigMax = sigMin;
224 for (
Index isam=0; isam<nsam; ++isam ) {
226 ph->SetBinContent(isam+1, sig);
228 if ( sig < sigMin ) sigMin = sig;
229 if ( sig > sigMax ) sigMax = sig;
235 cout << myname <<
"WARNING: Unknown type: " <<
type <<
endl;
237 if ( ph ==
nullptr )
continue;
248 if ( pfile !=
nullptr ) {
249 if (
m_LogLevel >= 2 ) cout << myname <<
"Writing to " << pfile->GetName() <<
endl;
250 for ( TH1* ph : hists ) ph->Write();
252 cout << myname <<
"File listing: " <<
endl;
257 gDirectory = polddir;
265 const string myname =
"AdcChannelPlotter::viewMap: ";
273 Index ndplt = ndx*ndy;
274 using ManMap = std::map<string, TPadManipulator>;
275 using NameMap = std::map<string, string>;
276 using IndexMap = std::map<string, Index>;
281 std::vector<TLatex*> labs;
282 bool useViewPort =
true;
283 for (
const AdcChannelDataMap::value_type& iacd : acds ) {
284 Index icha = iacd.first;
286 TLatex* ptxt =
new TLatex(0.98, 0.025, schan.c_str());
288 ptxt->SetTextFont(42);
289 ptxt->SetTextAlign(31);
290 labs.push_back(ptxt);
295 bool isRaw =
type ==
"raw";
296 bool isRawDist =
type ==
"rawdist" ||
type ==
"rawdistlog";
297 bool isLogY =
type ==
"rawdistlog";
298 float marginTop = 0.0;
299 float marginBottom = isRawDist ? 0.12 : 0.09;
300 float marginLeft = isRawDist ? 0.12 : 0.05;
301 float marginRight = isRawDist ? 0.02 : 0.01;
302 float xlab = isRawDist ? 0.95 : 0.98;
303 float ylab = 0.05 + marginBottom;
304 float hlab = isRawDist ? 0.08 : 0.16;
307 ptxt->SetTextSize(hlab);
308 if ( mans.find(
type) == mans.end() ) {
309 if (
m_LogLevel >= 3 ) cout <<
"Creating new top-level plot of type " <<
type <<
"." <<
endl;
314 float yview1 = isRawDist ? 0.0 : 0.00;
316 float yview2 = isRawDist ? 0.96 : 0.96;
317 if ( topman.
addPad(xview1, yview1, xview2, yview2) ) {
318 cout << myname <<
"ERROR: Unable to add subpad." <<
endl;
323 if ( isRaw ||
type ==
"prepared" ) {
325 for (
Index ipad=0; ipad<nplt; ++ipad ) {
331 }
else if ( isRawDist ) {
333 for (
Index ipad=0; ipad<ndplt; ++ipad ) {
341 nplts[
type] = ndx*ndy;
350 for (
Index ipsm=0; ipsm<man.
npad(); ++ipsm ) {
361 if (
m_LogLevel >= 3 ) cout << myname <<
" Adding subplot " << iplt <<
" for type " <<
type <<
"." <<
endl;
363 string sttl = ph->GetTitle();
364 Index ipos = sttl.find(
" channel");
365 sttl = sttl.substr(0, ipos);
368 man.
add(ph,
"hist",
false);
370 if (
type ==
"raw" ||
type ==
"prepared" ) {
374 if (
type ==
"raw" ) {
378 cout << myname <<
"Invalid raw PlotSigOpt = " <<
m_PlotSigOpt <<
". Using fixed." <<
endl;
383 int gSigMax = res.
getFloat(
"plotSigMax_" +
type) + 0.999;
384 if ( gSigMax - gSigMin < dSigMin ) {
385 while ( gSigMax - gSigMin < dSigMin ) {
386 if ( gSigMin > 0 ) --gSigMin;
387 if ( gSigMax - gSigMin < dSigMin ) ++gSigMax;
393 cout << myname <<
"Invalid " <<
type <<
" PlotSigOpt = " <<
m_PlotSigOpt <<
". Using fixed." <<
endl;
402 if (
type ==
"prepared" ) {
406 }
else if ( isRawDist ) {
416 cout << myname <<
"Invalid rawdist PlotSigOpt = " <<
m_PlotSigOpt <<
". Using full." <<
endl;
425 if ( ++iplt >= nplt ) {
427 for (
string type : m_HistTypes ) mans[
type].print(pfnames[
type]);
435 for ( ManMap::value_type& iman : mans ) iman.second.print(pfnames[iman.first]);
436 for ( TLatex* ptxt : labs )
delete ptxt;
445 string nameout =
name;
447 if ( type.size() ) sman.
replace(
"%TYPE%", type);
448 if ( pnbl ==
nullptr )
return nameout;
450 return pnbl->
build(acd, dm, nameout);
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
const AdcChannelStringTool * m_adcStringBuilder
int setLabelSizeX(double siz)
DataMap view(const AdcChannelData &acd) const override
const lariov::ChannelStatusProvider * m_pChannelStatusProvider
void setFloat(Name name, float val)
int add(unsigned int ipad, TObject *pobj, std::string sopt="", bool replace=false)
Name nameReplace(Name name, const AdcChannelData &acd, Name type) const
void setMarginLeft(double xmar)
DataMap & setStatus(int stat)
int addPad(double x1, double y1, double x2, double y2, int icol=-1)
virtual bool IsNoisy(raw::ChannelID_t channel) const =0
Returns whether the specified channel is noisy in the current run.
DataMap viewMap(const AdcChannelDataMap &acds) const override
int replace(std::string substr, const T &xsub)
int setLabelSizeY(double siz)
int setCanvasSize(int wx, int wy)
void setHist(Name name, TH1 *ph, bool own=false)
int split(Index nx, Index ny)
int showOverflow(bool show=true)
Q_EXPORT QTSManip setprecision(int p)
int setTitle(std::string sttl, float height=-1.0)
std::vector< Index > IndexVector
int addHorizontalLine(double yoff=0.0, double lenfrac=1.0, int isty=1)
int setLogY(bool flag=true)
int showUnderflow(bool show=true)
int addAxis(bool flag=true)
unsigned int npad() const
static constexpr double ps
TPadManipulator * man(unsigned int ipad=0)
int addVerticalModLines(double xmod, double xoff=0.0, double lenfrac=1.0, int isty=3)
Q_EXPORT QTSManip setw(int w)
Float getFloat(Name name, Float def=0.0) const
void setMarginTop(double xmar)
int setLogRangeY(double y1, double y2)
int setRangeX(double x1, double x2)
Interface for experiment-specific channel quality info provider.
std::vector< Name > NameVector
void setMarginBottom(double xmar)
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
TH1 * getHist(Name name, TH1 *def=nullptr) const
auto const & get(AssnsNode< L, R, D > const &r)
Interface for experiment-specific service for channel quality info.
int addHorizontalModLines(double ymod, double yoff=0.0, double lenfrac=1.0, int isty=3)
AdcChannelPlotter(fhicl::ParameterSet const &ps)
int setRangeY(double y1, double y2)
std::string to_string(ModuleType const mt)
void setMarginRight(double xmar)
QTextStream & endl(QTextStream &s)