33#include "TGraphAsymmErrors.h"
45void myText( Double_t
x, Double_t
y, Color_t
color,
const std::string& text, Double_t tsize);
54void Norm( TH1*
h,
double scale=1 );
59bool contains(
const std::string& s,
const std::string& p);
60bool contains(
const std::string& s,
char p)
noexcept;
63bool fcontains(
const std::string& s,
const std::string& p);
66bool exists(
const std::string& filename );
69std::string
tail( std::string s,
const std::string& pattern );
72std::string
head( std::string s,
const std::string& pattern );
75std::string
globbed(
const std::string& s );
77void contents( std::vector<std::string>& keys,
79 const std::string& directory=
"",
80 const std::string& pattern=
"",
81 const std::string& path=
"" );
83void contents( std::vector<std::string>& keys,
85 const std::string& directory=
"",
86 const std::vector<std::string>&
patterns=std::vector<std::string>(),
87 const std::string& path=
"" );
90double realmax( TH1*
h,
bool include_error=
true,
double lo=0,
double hi=0 );
91double realmin( TH1*
h,
bool include_error=
true,
double lo=0,
double hi=0 );
93std::string
findcell( std::string name,
const std::string& regex,
const std::string& splitex=
"/" );
103 virtual const char*
what()
const throw() {
return "data don't match"; }
109std::ostream&
operator<<( std::ostream& s, std::vector<T>& v) {
110 for (
unsigned i=0 ; i<v.size() ; i++ ) s <<
"\t" << v[i];
116std::vector<int>
findxrange(TH1*
h,
bool symmetric=
false );
124void xrange(TH1*
h,
bool symmetric=
true );
170 std::vector<std::string> keys =
split( s,
":" );
174 if ( keys.size()>0 )
m_tag = keys[0];
179 for (
size_t i=1 ; i<keys.size() ; i++ ) {
181 if ( keys[i]==
"lin" )
m_log =
false;
182 else if ( keys[i]==
"log" )
m_log =
true;
184 else if ( keys[i]==
"norm" )
m_norm =
true;
185 else if ( keys[i]==
"refn" )
m_refnorm =
true;
186 else if ( keys[i]==
"width" )
m_binwidth =
true;
187 else if ( keys[i]==
"auto" )
m_autoset =
true;
188 else if ( keys[i]==
"trim" )
m_trim =
true;
190 else if ( keys[i].
find(
"offset")==0 ) {
192 std::cout <<
"offset:" << std::endl;
193 std::cout <<
"\tkey: " << keys[i] << std::endl;
194 std::cout <<
"\tpos: " << keys[i].find(
"offset") << std::endl;
196 std::string
offset = keys[i];
199 std::cout <<
"m_offset: " <<
m_offset << std::endl;
201 else if ( keys[i]==
"auton" ) {
205 else if ( keys[i]==
"autow" ) {
209 else if ( keys[i]==
"autown" || keys[i]==
"autonw" ) {
214 else if ( keys[i]==
"autosym" ) {
218 else if ( keys[i]==
"normw" || keys[i]==
"widthn" ) {
222 else if ( !minset ) {
225 if ( i<keys.size() )
m_hi = std::atof(keys[i].
c_str());
227 std::cerr <<
"not enough values for the axis range: " << s << std::endl;
237 std::cout <<
"AxisInfo::info" <<
m_info <<
"\n";
238 std::cout <<
"\tlog " <<
m_log <<
"\n";
239 std::cout <<
"\tauto " <<
m_autoset <<
"\n";
278 static std::vector<std::string>
split(
const std::string& s,
const std::string& t=
":" ) {
281 size_t pos =
sc.find(t);
283 std::vector<std::string>
tags;
285 while ( pos!=std::string::npos ) {
290 tags.push_back(std::move(
sc));
323 s <<
"[ " <<
a.tag() << (
a.log() ?
" : log" :
"" ) <<
" ";
324 if (
a.autoset() ) s <<
" : auto";
325 else if (
a.rangeset() ) s <<
" : range " <<
a.lo() <<
" - " <<
a.hi();
348 Legend(
double x1,
double x2,
double y1,
double y2):
m_leg(nullptr) {
378 void AddEntry( TObject* tobj,
const std::string& s,
const std::string&
type=
"p" ) {
379 m_obj.push_back( tobj );
401 m_leg->SetBorderSize(0);
402 m_leg->SetTextFont(42);
403 m_leg->SetTextSize(0.04);
404 m_leg->SetFillStyle(3000);
405 m_leg->SetFillColor(0);
406 m_leg->SetLineColor(0);
408 for (
size_t i=0 ; i<
m_entries.size() ; i++ ) {
437 tg->SetLineColor(
h->GetLineColor() );
438 tg->SetMarkerColor(
h->GetMarkerColor() );
439 tg->SetMarkerStyle(
h->GetMarkerStyle() );
440 tg->SetMarkerSize(
h->GetMarkerSize() );
441 tg->SetLineWidth(
h->GetLineWidth() );
442 tg->SetLineStyle(
h->GetLineStyle() );
448 for (
int i=1 ; i<=
h->GetNbinsX() ; i++ )
h->SetBinError( i, 1e-100 );
497 void Draw(
int i,
Legend* lleg,
bool mean=
false,
bool first=
true,
bool drawlegend=
false ) {
500 gStyle->SetOptStat(0);
503 href()->SetLineStyle(2);
504 href()->SetMarkerStyle(0);
509 htest()->SetLineStyle(1);
520 std::cout << std::endl;
526 htest()->GetXaxis()->SetMoreLogLabels(
true);
536 htest()->GetXaxis()->SetMoreLogLabels(
true);
550 else href()->Draw(
"hist same");
565 if (
htest()->GetMarkerStyle()>23 ) {
566 TH1D* hnull = (TH1D*)
htest()->Clone(
"duff"); hnull->SetDirectory(0);
568 hnull->SetLineColor(kWhite);
569 hnull->SetMarkerStyle(
htest()->GetMarkerStyle()-4 );
571 hnull->SetMarkerColor(kWhite);
572 hnull->SetMarkerSize(
htest()->GetMarkerSize()*0.75 );
574 hnull->DrawCopy(
"l same");
579 htest()->Draw(
"ep same");
587 static TH1D* hnull =
new TH1D(
"hnull",
"", 1, 0, 1);
588 hnull->SetMarkerColor(kWhite);
589 hnull->SetLineColor(kWhite);
590 hnull->SetMarkerStyle(0);
591 hnull->SetLineStyle(0);
592 hnull->SetLineWidth(0);
593 hnull->SetMarkerSize(0);
603 bool displayref =
false;
607 std::sprintf( meanrefc,
" <t> = %3.2f #pm %3.2f ms (ref)", muref.
mean(), muref.
error() );
610 std::sprintf( meanrefc,
"%s",
"" );
615 std::sprintf( meanc,
" <t> = %3.2f #pm %3.2f ms", mutest.
mean(), mutest.
error() );
617 std::string dkey = std::move(key);
619 std::string remove[7] = {
"TIME_",
"Time_",
"All_",
"Algorithm_",
"Class_",
"HLT_",
"Chain_HLT_" };
621 if ( dkey.find(
"Chain")!=std::string::npos ) {
622 if ( dkey.find(
"__")!=std::string::npos ) dkey.erase( 0, dkey.find(
"__")+2 );
626 for (
int ir=0 ;
ir<7 ;
ir++ ) {
627 if ( dkey.find( remove[
ir] )!=std::string::npos ) dkey.erase( dkey.find( remove[
ir]), remove[
ir].size() );
630 std::string rkey = dkey;
634 dkey += std::string(
" : ");
636 if ( (dkey+meanc).size()>58 ) {
637 leg.AddEntry(
htest(), dkey,
"p" );
638 leg.AddEntry( hnull, meanc,
"p" );
641 leg.AddEntry(
htest(), (dkey+meanc).c_str(),
"p" );
645 rkey += std::string(
" : ");
649 if ( (rkey+meanrefc).size()>58 ) {
650 leg.AddEntry(
href(), rkey,
"l" );
651 leg.AddEntry( hnull, meanrefc,
"l" );
654 leg.AddEntry(
href(), (rkey+meanrefc).c_str(),
"l" );
666 if ( drawlegend ) leg.Draw();
677 gStyle->SetOptStat(0);
680 href()->SetLineStyle(2);
681 href()->SetMarkerStyle(0);
685 htest()->SetLineStyle(1);
690 std::cout << std::endl;
696 htest()->GetXaxis()->SetMoreLogLabels(
true);
706 htest()->GetXaxis()->SetMoreLogLabels(
true);
722 else href()->Draw(
"hist same");
739 if (
htest()->GetMarkerStyle()>23 ) {
740 TH1D* hnull = (TH1D*)
htest()->Clone(
"duff"); hnull->SetDirectory(0);
742 hnull->SetLineColor(kWhite);
743 hnull->SetMarkerStyle(
htest()->GetMarkerStyle()-4 );
745 hnull->SetMarkerColor(kWhite);
746 hnull->SetMarkerSize(
htest()->GetMarkerSize()*0.75 );
748 hnull->DrawCopy(
"l same");
761 static TH1D* hnull =
new TH1D(
"hnull",
"", 1, 0, 1);
762 hnull->SetMarkerColor(kWhite);
763 hnull->SetLineColor(kWhite);
764 hnull->SetMarkerStyle(0);
765 hnull->SetLineStyle(0);
766 hnull->SetLineWidth(0);
767 hnull->SetMarkerSize(0);
773 bool displayref =
false;
777 std::sprintf( meanrefc,
" <t> = %3.2f #pm %3.2f ms (ref)", muref.
mean(), muref.
error() );
780 std::sprintf( meanrefc,
"%s",
"" );
786 std::sprintf( meanc,
" <t> = %3.2f #pm %3.2f ms", mutest.
mean(), mutest.
error() );
788 std::string dkey = key;
790 std::string remove[7] = {
"TIME_",
"Time_",
"All_",
"Algorithm_",
"Class_",
"HLT_",
"Chain_HLT_" };
792 if ( dkey.find(
"Chain")!=std::string::npos ) {
793 if ( dkey.find(
"__")!=std::string::npos ) dkey.erase( 0, dkey.find(
"__")+2 );
797 for (
int ir=0 ;
ir<7 ;
ir++ ) {
798 if ( dkey.find( remove[
ir] )!=std::string::npos ) dkey.erase( dkey.find( remove[
ir]), remove[
ir].size() );
801 std::string rkey = dkey;
805 dkey += std::string(
" : ");
807 if ( (dkey+meanc).size()>58 ) {
808 leg.AddEntry(
htest(), dkey,
"p" );
809 leg.AddEntry( hnull, meanc,
"p" );
812 leg.AddEntry(
htest(), (dkey+meanc).c_str(),
"p" );
816 rkey += std::string(
" : ");
819 if ( (rkey+meanrefc).size()>58 ) {
820 leg.AddEntry(
href(), rkey,
"l" );
821 leg.AddEntry( hnull, meanrefc,
"l" );
824 leg.AddEntry(
href(), (rkey+meanrefc).c_str(),
"l" );
836 if ( drawlegend ) leg.Draw();
844 void Print(
const std::string& s=
"") {
845 if ( s!=
"" ) gPad->Print(s.c_str());
904 std::cout << __FUNCTION__ << std::endl;
905 for (
int i=1 ; i<=
h->GetNbinsX() ; i++ ) {
906 double duff =
h->GetBinContent(i);
908 std::cout<<
"\t\t" << __FUNCTION__ <<
" " <<
h->GetName() <<
" " << i <<
" " <<
h->GetBinContent(i) <<
" " << (duff*1e6) << std::endl;
912 gPad->Print( (std::string(
"duff-")+
h->GetName()+
".pdf").c_str() );
917class Plots :
public std::vector<Plotter> {
921 Plots(
const std::string& s=
"",
bool errors=
false ) :
934 for (
unsigned i=0 ; i<size() ; i++ ) {
936 if ( rmtest!=0 && ( first ||
min>rmtest ) )
min = rmtest;
937 if ( rmtest!=0 ) first =
false;
945 for (
unsigned i=0 ; i<size() ; i++ ) {
948 if ( rmtest!=0 && ( first ||
max<rmtest ) )
max = rmtest;
949 if ( rmtest!=0 ) first =
false;
958 if ( size()<1 )
return;
967 for (
unsigned i=0 ; i<size() ; i++ ) {
968 if ( at(i).href() ) at(i).href()->SetMaximum(scale*tmax);
969 at(i).htest()->SetMaximum(scale*tmax);
977 if ( size()<1 )
return;
980 for (
unsigned i=0 ; i<size() ; i++ ) {
981 if ( at(i).href() ) at(i).href()->SetMinimum(0);
982 at(i).htest()->SetMinimum(0);
995 for (
unsigned i=0 ; i<size() ; i++ ) {
996 if ( at(i).href() ) at(i).href()->SetMinimum(scale*tmin);
997 at(i).htest()->SetMinimum(scale*tmin);
1004 for (
unsigned i=0 ; i<size() ; i++ ) {
1005 if ( at(i).href() ) at(i).href()->SetMinimum(scale);
1006 at(i).htest()->SetMinimum(scale);
1008 if ( at(i).href() )
if ( at(i).href()->GetMinimum()<=0 ) at(i).href()->GetMinimum(1e-4);
1009 if ( at(i).htest()->GetMinimum()<=0 ) at(i).htest()->GetMinimum(1e-4);
1017 for (
unsigned i=0 ; i<size() ; i++ ) {
1018 if ( at(i).href() ) at(i).href()->SetMaximum(scale);
1019 at(i).htest()->SetMaximum(scale);
1028 std::vector<double> v(2,0);
1030 TH1F* hf = at(0).htest();
1035 if ( hf->GetBinLowEdge(1)<vlo ) vlo = hf->GetBinLowEdge(1);
1036 if ( hf->GetBinLowEdge(hf->GetNbinsX()+1)>vhi ) vhi = hf->GetBinLowEdge( hf->GetNbinsX()+1 );
1042 for (
unsigned i=1 ; i<size() ; i++ ) {
1046 if (
::empty( hf ) )
continue;
1048 if ( hf->GetBinLowEdge(1)<vlo ) vlo = hf->GetBinLowEdge(1);
1049 if ( hf->GetBinLowEdge(hf->GetNbinsX()+1)>vhi ) vhi = hf->GetBinLowEdge( hf->GetNbinsX()+1 );
1062 if ( v[0]>
lo ) v[0] =
lo;
1063 if ( v[1]<
hi ) v[1] =
hi;
1069 double upper = ( v[1]-v[0] )*1.1 + v[0];
1070 double lower = v[0] - ( v[1]-v[0] )*0.1;
1073 double dx = std::log10(v[1])-std::log10(v[0]);
1074 upper = std::pow(10,dx*1.1 + std::log10(v[0]));
1075 lower = std::pow(10,std::log10(v[0]) - dx*0.1);
1078 if ( lower<vlo ) lower = vlo;
1096 if ( xinfo.
autoset() && size() > 0 ) {
1107 else if (size() == 0)
1109 std::cout<<
"Warning in computils.h::sortx() size=0. Setting m_lo/m_hi to 0/1. You will probably have empty figures."<<std::endl;
1129 for (
unsigned i=0 ; i<size() ; i++ ) {
1130 if ( at(i).href() )
::xrange( at(i).href(), symmetric );
1131 ::xrange( at(i).htest(), symmetric );
1139 for (
unsigned i=0 ; i<size() ; i++ ) {
1140 if ( at(i).href() ) at(i).href()->GetXaxis()->SetRangeUser(
m_lo,
m_hi );
1141 at(i).htest()->GetXaxis()->SetRangeUser(
m_lo,
m_hi );
1150 std::cout <<
"\tlimits \t" <<
m_name <<
"\tmin " << rmin <<
"\tmax " << rmax << std::endl;
1170 for (
unsigned i=0 ; i<size() ; i++, first=false ) {
1171 double ymax = at(i).htest()->GetMaximum();
1172 double ymin = at(i).htest()->GetMinimum();
1173 at(i).htest()->GetYaxis()->SetMoreLogLabels(
true);
1174 if (
ymax/
ymin>1e6 ) at(i).htest()->GetYaxis()->SetMoreLogLabels(
false);
1179 for (
unsigned i=0 ; i<size() ; i++ ) at(i).trim_errors(
m_trim_errors );
1186 for (
unsigned i=size() ; i-- ; first=false ) at(i).Draw( i, &leg, means, first, i==0 );
1198 if ( size()>0 )
return at(0).htest()->GetXaxis()->GetTitle();
1203 if ( size()>0 )
return at(0).htest()->GetYaxis()->GetTitle();
1208 if ( size()>0 ) at(0).htest()->GetXaxis()->SetTitle(s.c_str());
1212 if ( size()>0 ) at(0).htest()->GetYaxis()->SetTitle(s.c_str());
1219 std::vector<Plotter>::push_back( val );
1264 if ( v.size() < 6 )
throw std::exception();
1266 for (
size_t i=0 ; i<6 ; i++ )
m_details.push_back(v[i]);
1272 for (
size_t i=0 ; i<6 ; i++ )
m_details.push_back(vp[i]);
1315 return s <<
"[ " <<
h.name() <<
" \tx: \"" <<
h.xtitle() <<
"\" " <<
h.xaxis() <<
"\t\ty: \"" <<
h.ytitle() <<
"\" " <<
h.yaxis() <<
" ]";
1334 Panel(
const std::string& s,
int nr,
int nc ) :
1374 s <<
"Panel: " << p.name();
1375 if ( p.size() == 1 ) s <<
"\t" << p[0];
1376 else for (
size_t i=0 ; i<p.size() ; i++ ) s <<
"\n\t" << p[i];
static const Attributes_t empty
Header file for AthHistogramAlgorithm.
class to store information about axes, limits, whether it is log or linear scale etc
AxisInfo(const std::string &s)
static std::vector< std::string > split(const std::string &s, const std::string &t=":")
const std::string & c_str() const
const std::string & tag() const
accessors
details of the histogram axes etc
const AxisInfo & xaxis() const
std::string ytitle() const
std::vector< std::string > m_details
std::string xtitle() const
HistDetails(const std::vector< std::string > &v)
const std::string & detail() const
HistDetails(const std::string *vp)
const AxisInfo & yaxis() const
slightly more convenient legend class
std::vector< TObject * > m_obj
std::vector< std::string > m_entries
Legend(double x1, double x2, double y1, double y2)
void AddEntry(TObject *tobj, const std::string &s, const std::string &type="p")
Legend(const Legend &legend)
std::vector< std::string > m_type
void push_back(const HistDetails &h)
Panel(const std::string &s, int nc)
don't know how many rows or total hists yet, but do know number of columns
std::vector< HistDetails > m_hist
const std::string & name() const
HistDetails & operator[](int i)
const HistDetails & operator[](int i) const
Panel(const std::string &s, int nr, int nc)
know number of rows and columns
const HistDetails & back() const
void sortx(const AxisInfo &xinfo)
void xrange(bool symmetric=false)
double realmax(double lo=0, double hi=0)
void Draw_i(Legend &leg, bool means=false)
void SetXaxisTitle(const std::string &s)
void MaxScale(double scale=1.1, double lo=0, double hi=0)
std::vector< double > findxrange(bool symmetric=false)
bool m_maxset
yaxis range setting
void push_back(const Plotter &val)
this is so that we can update the stats as we go along, but no updating isn't done at the moment
Plots(const std::string &s="", bool errors=false)
double realmin(double lo=0, double hi=0)
void Draw(Legend &leg, bool means=false)
std::string GetYaxisTitle()
bool m_logx
canvas log setting
void MinScale(double scale, double lo=0, double hi=0)
bool m_rangeset
xaxis range setting
void SetLogy(bool b=true)
void SetLogx(bool b=true)
void SetYaxisTitle(const std::string &s)
std::string GetXaxisTitle()
void SetRangeUser(double lo, double hi)
static void setwatermark(bool b)
virtual const char * what() const
data_mismatch(const std::string &s)
generic plotter class - better to have one of these - make sure it can be configured however you like...
tPlotter(T *htest=0, T *href=0, const std::string &s="", TGraphAsymmErrors *tgtest=0, TGraphAsymmErrors *tgref=0)
~tPlotter()
sadly, root manages all the histograms (does it really?
const std::string & plotfilename() const
void Draw(int i, Legend *lleg, bool mean=false, bool first=true, bool drawlegend=false)
tPlotter(const tPlotter &p)
void DrawLegend(int i, Legend &leg, bool mean=false, bool first=true, bool drawlegend=false)
TGraphAsymmErrors * tgref()
std::string m_plotfilename
static bool s_meanplotref
void Print(const std::string &s="")
print the output
TGraphAsymmErrors * m_tgtest
static void setplotref(bool b)
static void setmeanplotref(bool b)
TGraphAsymmErrors * tgtest()
TGraphAsymmErrors * m_tgref
void xrange(TH1 *h, bool symmetric=true)
std::ostream & operator<<(std::ostream &s, std::vector< T > &v)
bool contains(const std::string &s, const std::string &p)
does a string contain the substring
double realmin(TH1 *h, bool include_error=true, double lo=0, double hi=0)
void Norm(TH1 *h, double scale=1)
void copyReleaseInfo(TFile *finput, TFile *foutdir)
copy the TTree of release info from one directory to another
std::string stime()
return the current data and time
std::string globbed(const std::string &s)
match a file name
std::string findcell(std::string name, const std::string ®ex, const std::string &splitex="/")
std::string findrun(TFile *f)
void ATLASFORAPP_LABEL(double x, double y, int color, double size=0.06)
bool exists(const std::string &filename)
does a file exist
std::string tail(std::string s, const std::string &pattern)
tail of a string
void contents(std::vector< std::string > &keys, TDirectory *td, const std::string &directory="", const std::string &pattern="", const std::string &path="")
static std::string release
std::vector< int > findxrange(TH1 *h, bool symmetric=false)
automatically set the xrange on a histogram
double realmax(TH1 *h, bool include_error=true, double lo=0, double hi=0)
void trim_tgraph(TH1 *h, TGraphAsymmErrors *t)
void setParameters(T *h, TGraphAsymmErrors *tg)
void myText(Double_t x, Double_t y, Color_t color, const std::string &text, Double_t tsize)
std::string head(std::string s, const std::string &pattern)
head of a string
bool fcontains(const std::string &s, const std::string &p)
does a string contain the substring at the beginning of the string
std::vector< double > findxrangeuser(TH1 *h, bool symmetric=false)
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
int ir
counter of the current depth
std::vector< std::string > tags
std::string find(const std::string &s)
return a remapped string
std::string chop(std::string &s1, const std::string &s2)
std::vector< std::string > patterns