247 gStyle->SetLineStyleString(2,
"[12 12]");
248 gStyle->SetFrameBorderMode(0);
249 gStyle->SetFrameFillColor(0);
250 gStyle->SetCanvasBorderMode(0);
251 gStyle->SetCanvasColor(0);
252 gStyle->SetPadBorderMode(0);
253 gStyle->SetPadColor(0);
254 gStyle->SetStatColor(0);
255 gStyle->SetPaperSize(20, 26);
285 pad->
GetPad()->SetTicks();
288 TAxis *Xaxis =
nullptr;
289 TAxis *Yaxis =
nullptr;
290 TAxis *Zaxis =
nullptr;
292 bool is_for_hstack =
false;
294 std::shared_ptr<FigureElement> firstelement = pad->
GetLinkElement(0);
296 if (firstelement->IsType(
"FigureHist1D"))
298 Xaxis = (std::dynamic_pointer_cast<FigureHist1D>(firstelement))->GetHist()->GetXaxis();
299 Yaxis = (std::dynamic_pointer_cast<FigureHist1D>(firstelement))->GetHist()->GetYaxis();
301 else if (firstelement->IsType(
"FigureHStack"))
303 Xaxis = (std::dynamic_pointer_cast<FigureHStack>(firstelement))->empty_hist->GetXaxis();
304 Yaxis = (std::dynamic_pointer_cast<FigureHStack>(firstelement))->empty_hist->GetYaxis();
305 is_for_hstack =
true;
307 else if (firstelement->IsType(
"FigureGraph1D"))
309 Xaxis = (std::dynamic_pointer_cast<FigureGraph1D>(firstelement))->GetGraph()->GetXaxis();
310 Yaxis = (std::dynamic_pointer_cast<FigureGraph1D>(firstelement))->GetGraph()->GetYaxis();
312 else if (firstelement->IsType(
"FigureFunc1D"))
314 Xaxis = (std::dynamic_pointer_cast<FigureFunc1D>(firstelement))->GetFunc()->GetXaxis();
315 Yaxis = (std::dynamic_pointer_cast<FigureFunc1D>(firstelement))->GetFunc()->GetYaxis();
317 else if (firstelement->IsType(
"FigureHist2D"))
319 Xaxis = (std::dynamic_pointer_cast<FigureHist2D>(firstelement))->GetHist()->GetXaxis();
320 Yaxis = (std::dynamic_pointer_cast<FigureHist2D>(firstelement))->GetHist()->GetYaxis();
321 Zaxis = (std::dynamic_pointer_cast<FigureHist2D>(firstelement))->GetHist()->GetZaxis();
327 pad->
GetPad()->SetBottomMargin(((
double)n_bottom) / (padrange.
RT_Y - padrange.
LB_Y));
330 pad->
GetPad()->SetBottomMargin(0);
336 pad->
GetPad()->SetLeftMargin(((
double)n_left) / (padrange.
RT_X - padrange.
LB_X));
339 pad->
GetPad()->SetLeftMargin(0);
344 if (padrange.
RT_Y > canvasrange.
RT_Y - n_top)
346 pad->
GetPad()->SetTopMargin(((
double)padrange.
RT_Y - canvasrange.
RT_Y + n_top) / (padrange.
RT_Y - padrange.
LB_Y));
347 n_top = padrange.
RT_Y - canvasrange.
RT_Y + n_top;
351 pad->
GetPad()->SetTopMargin(0);
357 if (padrange.
RT_X > canvasrange.
RT_X - n_right_blank)
358 n_right_blank = padrange.
RT_X - canvasrange.
RT_X + n_right_blank;
363 if (n_right < n_right_blank)
364 n_right = n_right_blank;
365 pad->
GetPad()->SetRightMargin(((
double)n_right) / (padrange.
RT_X - padrange.
LB_X));
374 if (2 < div_n1_x < 5)
376 if (2 < div_n1_y < 5)
378 if (2 < div_n1_z < 5)
391 Xaxis->SetTickLength(((
double)n_axis) / (padrange.
RT_Y - padrange.
LB_Y));
392 Xaxis->SetNdivisions(div_n_x);
394 Xaxis->SetLabelSize(n_label);
396 Xaxis->SetTitleSize(n_label);
397 Xaxis->SetMaxDigits(4);
401 double offset = -0.1 + 6.13 * ((double)n_bottom) / (padrange.
RT_Y - padrange.
LB_Y);
404 Xaxis->SetTitleOffset(offset);
411 Xaxis->SetTitle(pad->
GetXTitle().TString::Data());
419 Yaxis->SetTickLength(((
double)n_axis) / (padrange.
RT_X - padrange.
LB_X));
420 Yaxis->SetNdivisions(div_n_y);
423 Yaxis->SetLabelSize(n_label);
425 Yaxis->SetTitleSize(n_label);
426 Yaxis->SetMaxDigits(3);
430 double offset = -0.25 + 12.666 * ((double)n_left) / (padrange.
RT_X - padrange.
LB_X);
433 Yaxis->SetTitleOffset(offset);
441 Yaxis->SetTitle(pad->
GetYTitle().TString::Data());
449 Zaxis->SetTickLength(((
double)n_axis) / (padrange.
RT_X - padrange.
LB_X));
450 Zaxis->SetNdivisions(div_n_z);
452 Zaxis->SetLabelSize(n_label);
454 Zaxis->SetTitleSize(n_label);
455 Zaxis->SetMaxDigits(4);
459 double offset = -0.25 + 12.666 * ((double)n_left) / (padrange.
RT_X - padrange.
LB_X);
462 Zaxis->SetTitleOffset(offset);
470 Zaxis->SetTitle(pad->
GetZTitle().TString::Data());
502 double max_yaxis_adjust = 0;
503 double min_yaxis_adjust = 0;
508 if (elem->IsType(
"FigureHist1D"))
509 std::tie(ymin, ymax) = (std::dynamic_pointer_cast<FigureHist1D>(elem))->GetMinAndMax(pad->
min_xaxis, pad->
max_xaxis);
510 if (elem->IsType(
"FigureHStack"))
511 std::tie(ymin, ymax) = (std::dynamic_pointer_cast<FigureHStack>(elem))->GetMinAndMax(pad->
min_xaxis, pad->
max_xaxis);
512 if (elem->IsType(
"FigureGraph1D"))
513 std::tie(ymin, ymax) = (std::dynamic_pointer_cast<FigureGraph1D>(elem))->GetMinAndMax(pad->
min_xaxis, pad->
max_xaxis);
514 if (elem->IsType(
"FigureFunc1D"))
515 std::tie(ymin, ymax) = (std::dynamic_pointer_cast<FigureFunc1D>(elem))->GetMinAndMax(pad->
min_xaxis, pad->
max_xaxis);
519 min_yaxis_adjust = ymin;
520 max_yaxis_adjust = ymax;
524 if (ymin < min_yaxis_adjust)
525 min_yaxis_adjust = ymin;
526 if (ymax > max_yaxis_adjust)
527 max_yaxis_adjust = ymax;
532 min_yaxis_adjust = 0;
542 length_pad = (max_yaxis_adjust - min_yaxis_adjust) / ((1 - (1 + nrows) *
LeftPercentage - 0.04));
544 length_pad = (max_yaxis_adjust - min_yaxis_adjust) / 0.5;
546 max_yaxis_adjust += (0.04 + (1 + nrows) *
LeftPercentage) * length_pad * 1.2;
550 min_yaxis_adjust = 0;
555 double length_pad = (max_yaxis_adjust - min_yaxis_adjust) / (1 - top_percentage);
557 max_yaxis_adjust += top_percentage * length_pad * 1.2;
561 min_yaxis_adjust = 0;
564 Yaxis->SetRangeUser(min_yaxis_adjust, max_yaxis_adjust);
570 pad->
legend->SetFillColor(0);
571 pad->
legend->SetFillStyle(0);
572 pad->
legend->SetLineColor(0);
573 pad->
legend->SetLineWidth(0);
588 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureStyleHelper::SetPadStyle");
589 MSGUser()->MSG_WARNING(
"pad y axis range set but legend position not set, user should manually set the position of legend");
600 pad->
legend->SetX2(1 - pad->
GetPad()->GetRightMargin() - 0.04);
601 pad->
legend->SetY1(1 - pad->
GetPad()->GetTopMargin() - percentage);
602 pad->
legend->SetY2(1 - pad->
GetPad()->GetTopMargin() - 0.04);
638 Color_t mypalette[12] = {kRed, kBlue, kGreen, kPink, kAzure, kOrange, kMagenta, kCyan, kYellow, kViolet, kTeal, kSpring + 1};
639 Color_t ncolor = mypalette[index] + round;
641 hist->
GetHist()->SetLineColor(ncolor);
642 hist->
GetHist()->SetMarkerColor(ncolor);
643 hist->
GetHist()->SetLineWidth(2);
644 hist->
GetHist()->SetMarkerSize(0);
645 hist->
GetHist()->SetFillStyle(0);
648 hist->
GetHist()->SetFillStyle(1001);
649 hist->
GetHist()->SetFillColor(ncolor);
650 hist->
GetHist()->SetLineWidth(0);
663 Color_t mypalette[12] = {kRed, kBlue, kGreen, kPink, kAzure, kOrange, kMagenta, kCyan, kYellow, kViolet, kTeal, kSpring + 1};
664 Color_t ncolor = mypalette[index] + round;
666 int Marker_Style[6] = {20, 21, 22, 23, 29, 33};
669 graph->
GetGraph()->SetLineColor(ncolor);
675 graph->
GetGraph()->SetMarkerSize(0.002 * (canvasrange.
RT_Y - canvasrange.
LB_Y));
676 graph->
GetGraph()->SetMarkerColor(ncolor);
688 Color_t mypalette[12] = {kRed, kBlue, kGreen, kPink, kAzure, kOrange, kMagenta, kCyan, kYellow, kViolet, kTeal, kSpring + 1};
689 Color_t ncolor = mypalette[index] + round;
691 int Marker_Style[6] = {20, 21, 22, 23, 29, 33};
693 hist->
mygraph->SetLineWidth(2);
694 hist->
mygraph->SetLineColor(ncolor);
695 hist->
mygraph->SetLineStyle(1);
700 hist->
mygraph->SetMarkerSize(0.002 * (canvasrange.
RT_Y - canvasrange.
LB_Y));
701 hist->
mygraph->SetMarkerColor(ncolor);
703 hist->
mygraph->SetFillStyle(0);
712 Color_t mypalette[12] = {kRed, kBlue, kGreen, kPink, kAzure, kOrange, kMagenta, kCyan, kYellow, kViolet, kTeal, kSpring + 1};
713 Color_t ncolor = mypalette[index] + round;
715 func->
GetFunc()->SetLineWidth(2);
716 func->
GetFunc()->SetLineColor(ncolor);
717 func->
GetFunc()->SetFillColor(ncolor);
718 func->
GetFunc()->SetMarkerColor(ncolor);
719 func->
GetFunc()->SetFillStyle(0);
729 Color_t mypalette[12] = {kRed, kBlue, kGreen, kPink, kAzure, kOrange, kMagenta, kCyan, kYellow, kViolet, kTeal, kSpring + 1};
730 Color_t ncolor = mypalette[index] + round;
732 hist->
GetHist()->SetLineColor(ncolor);
733 hist->
GetHist()->SetFillColor(ncolor);
759 MSGUser()->MSG_ERROR(
"Function FigureElement::DrawElement Should be override!!!");
785 bool contain =
false;
786 for (
int i = 0; i <
Range_vec.size(); i++)
788 for (
int j = 0; j < subelement->Range_vec.size(); j++)
816 if (foundelement !=
nullptr)
833 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureElement::CheckDuplicate");
834 MSGUser()->MSG_ERROR(
"can not book element with same name ", elementname);
858 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureElement::GetLinkIndex");
860 return findresult->second;
863 MSGUser()->MSG_ERROR(
"does not find element ",
name,
" return -1");
870 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureElement::GetLinkElement");
873 MSGUser()->MSG_ERROR(
"index out of range, return nullptr");
882FigureHist1D::FigureHist1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname,
const TString &linkinfo,
const TString &option,
FigureElement *mother, std::function<
void(TH1D *)> optionfunc)
883 :
FigureElement(MSG, shelper, elementname,
"FigureHist1D", mother)
891FigureHist1D::FigureHist1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname, TH1D *hist,
const TString &option,
FigureElement *mother, std::function<
void(TH1D *)> optionfunc)
892 :
FigureElement(MSG, shelper, elementname,
"FigureHist1D", mother)
894 myhist = (TH1D *)hist->Clone(TString::Format(
"Temp_%s", elementname.TString::Data()).TString::Data());
902FigureHist1D::FigureHist1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname, TH1D *hist,
const TString &option,
FigureElement *mother, std::function<
void(TGraph *)> optionfunc)
903 :
FigureElement(MSG, shelper, elementname,
"FigureHist1D", mother)
905 myhist = (TH1D *)hist->Clone(TString::Format(
"Temp_%s", elementname.TString::Data()).TString::Data());
913FigureHist1D::FigureHist1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname,
const TString &linkinfo,
const TString &option,
FigureElement *mother, std::function<
void(TGraph *)> optionfunc)
914 :
FigureElement(MSG, shelper, elementname,
"FigureHist1D", mother)
938 mygraph->GetXaxis()->SetRangeUser(
myhist->GetXaxis()->GetXmin(),
myhist->GetXaxis()->GetXmax());
941 for (
int i = 0; i <
mygraph->GetN(); i++)
971 if (
LinkInfo.TString::BeginsWith(
"RATIO"))
973 if (
LinkInfo.TString::BeginsWith(
"PULL"))
975 if (
LinkInfo.TString::BeginsWith(
"DELTA"))
977 if (
LinkInfo.TString::BeginsWith(
"CHI2"))
984 std::vector<TString> LinkObjectName;
987 for (
int i = 0; i <
LinkInfo.Length(); i++)
989 if (
LinkInfo(i) ==
'/' && start ==
true)
991 LinkObjectName.push_back(
name);
995 if (start ==
true &&
LinkInfo(i) !=
'/')
998 if (
LinkInfo(i) ==
'/' && start ==
false)
1005 return LinkObjectName;
1011 if (LinkMode.TString::EqualTo(
"UNKNOWN"))
1013 MSGUser()->MSG_ERROR(
"FigureHist1D ",
GetName().TString::Data(),
" cannot be generated from ", LinkMode.TString::Data());
1018 std::vector<std::shared_ptr<FigureElement>> LinkObject;
1019 for (
int i = 0; i < LinkObjectName.size(); i++)
1023 LinkObject.push_back(obj);
1025 MSGUser()->MSG_ERROR(
"can not find linked element ", LinkObjectName[i]);
1028 std::vector<TH1D *> LinkHists;
1030 auto CheckLinkObjectType = [&](
int num) ->
bool
1032 for (
int i = 0; i < num; i++)
1034 if (LinkObject[i]->
IsType(
"FigureHist1D"))
1036 if ((std::dynamic_pointer_cast<FigureHist1D>(LinkObject[i]))->GetHist() ==
nullptr)
1039 LinkHists.emplace_back(std::dynamic_pointer_cast<FigureHist1D>(LinkObject[i])->GetHist());
1041 else if (LinkObject[i]->
IsType(
"FigureHStack"))
1043 LinkHists.emplace_back(std::dynamic_pointer_cast<FigureHStack>(LinkObject[i])->GetTotalHist());
1047 MSGUser()->MSG_ERROR(
"Link Object must be FigureHist1D or FigureHStack");
1055 if (LinkMode.TString::EqualTo(
"RATIO"))
1058 if (LinkObject.size() != 2)
1060 MSGUser()->MSG_ERROR(
"RATIO Link Needs two objects!!! FigureHist1D:",
GetName().TString::Data(),
" has ", LinkObject.size());
1064 if (!CheckLinkObjectType(2))
1067 std::shared_ptr<HistTool> histtool = std::make_shared<HistTool>(
MSGUser());
1068 TH1D *hist0 =
nullptr;
1069 TH1D *hist1 =
nullptr;
1070 hist0 = (TH1D *)(LinkHists[0]->Clone(
"TempRatio0_" +
GetName()));
1071 if (LinkObject[0] == LinkObject[1])
1074 hist1 = (TH1D *)(LinkHists[1]->Clone(
"TempRatio1_" +
GetName()));
1077 histtool->Ratio(hist0, hist1,
myhist);
1079 if (
LinkInfo.TString::EndsWith(
"/") ==
false)
1082 if (specialterm.Contains(
"VAL") ==
false && specialterm.Contains(
"ERR") ==
false)
1083 specialterm =
"VALERR";
1085 if (specialterm.Contains(
"VAL") ==
false)
1087 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1088 myhist->SetBinContent(i + 1, 1);
1091 if (specialterm.Contains(
"ERR") ==
false)
1093 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1094 myhist->SetBinError(i + 1, 0);
1097 if (specialterm.Contains(
"TOPERR"))
1099 for (
int i = 0; i < hist1->GetXaxis()->GetNbins(); i++)
1100 hist1->SetBinError(i + 1, 0);
1101 histtool->Ratio(hist0, hist1,
myhist);
1104 if (specialterm.Contains(
"BOTTOMERR"))
1106 for (
int i = 0; i < hist0->GetXaxis()->GetNbins(); i++)
1107 hist0->SetBinError(i + 1, 0);
1108 histtool->Ratio(hist0, hist1,
myhist);
1117 if (LinkMode.TString::EqualTo(
"PULL"))
1120 if (LinkObject.size() != 2)
1122 MSGUser()->MSG_ERROR(
"PULL Link Needs two objects!!! FigureHist1D:",
GetName().TString::Data(),
" has ", LinkObject.size());
1126 if (!CheckLinkObjectType(2))
1129 std::shared_ptr<HistTool> histtool = std::make_shared<HistTool>(
MSGUser());
1130 auto hist0 = (TH1D *)(LinkHists[0]->Clone(
"TempPull0_" +
GetName()));
1131 auto hist1 = (TH1D *)(LinkHists[1]->Clone(
"TempPull1_" +
GetName()));
1133 histtool->Pull(hist0, hist1,
myhist);
1135 if (
LinkInfo.TString::EndsWith(
"/") ==
false)
1138 if (specialterm.Contains(
"VAL") ==
false && specialterm.Contains(
"ERR") ==
false)
1139 specialterm =
"VALERR";
1141 if (specialterm.Contains(
"VAL") ==
false)
1143 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1144 myhist->SetBinContent(i + 1, 1);
1147 if (specialterm.Contains(
"ERR") ==
false)
1149 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1150 myhist->SetBinError(i + 1, 0);
1153 if (specialterm.Contains(
"TOPERR"))
1155 for (
int i = 0; i < hist1->GetXaxis()->GetNbins(); i++)
1156 hist1->SetBinError(i + 1, 0);
1157 histtool->Pull(hist0, hist1,
myhist);
1160 if (specialterm.Contains(
"BOTTOMERR"))
1162 for (
int i = 0; i < hist0->GetXaxis()->GetNbins(); i++)
1163 hist0->SetBinError(i + 1, 0);
1164 histtool->Pull(hist0, hist1,
myhist);
1172 if (LinkMode.TString::EqualTo(
"DELTA"))
1175 if (LinkObject.size() != 2)
1177 MSGUser()->MSG_ERROR(
"DELTA Link Needs two objects!!! FigureHist1D:",
GetName().TString::Data(),
" has ", LinkObject.size());
1181 if (!CheckLinkObjectType(2))
1184 std::shared_ptr<HistTool> histtool = std::make_shared<HistTool>(
MSGUser());
1185 auto hist0 = (TH1D *)(LinkHists[0]->Clone(
"TempDelta0_" +
GetName()));
1186 auto hist1 = (TH1D *)(LinkHists[1]->Clone(
"TempDelta1_" +
GetName()));
1188 histtool->Delta(hist0, hist1,
myhist);
1190 if (
LinkInfo.TString::EndsWith(
"/") ==
false)
1193 if (specialterm.Contains(
"VAL") ==
false && specialterm.Contains(
"ERR") ==
false)
1194 specialterm =
"VALERR";
1196 if (specialterm.Contains(
"VAL") ==
false)
1198 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1199 myhist->SetBinContent(i + 1, 1);
1202 if (specialterm.Contains(
"ERR") ==
false)
1204 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1205 myhist->SetBinError(i + 1, 0);
1208 if (specialterm.Contains(
"TOPERR"))
1210 for (
int i = 0; i < hist1->GetXaxis()->GetNbins(); i++)
1211 hist1->SetBinError(i + 1, 0);
1212 histtool->Delta(hist0, hist1,
myhist);
1215 if (specialterm.Contains(
"BOTTOMERR"))
1217 for (
int i = 0; i < hist0->GetXaxis()->GetNbins(); i++)
1218 hist0->SetBinError(i + 1, 0);
1219 histtool->Delta(hist0, hist1,
myhist);
1227 if (LinkMode.TString::EqualTo(
"CHI2"))
1230 if (LinkObject.size() != 2)
1232 MSGUser()->MSG_ERROR(
"CHI2 Link Needs two objects!!! FigureHist1D:",
GetName().TString::Data(),
" has ", LinkObject.size());
1236 if (!CheckLinkObjectType(2))
1239 std::shared_ptr<HistTool> histtool = std::make_shared<HistTool>(
MSGUser());
1240 auto hist0 = (TH1D *)(LinkHists[0]->Clone(
"TempChi20_" +
GetName()));
1241 auto hist1 = (TH1D *)(LinkHists[1]->Clone(
"TempChi21_" +
GetName()));
1243 histtool->Chi2(hist0, hist1,
myhist);
1245 if (
LinkInfo.TString::EndsWith(
"/") ==
false)
1248 if (specialterm.Contains(
"VAL") ==
false && specialterm.Contains(
"ERR") ==
false)
1249 specialterm =
"VALERR";
1251 if (specialterm.Contains(
"VAL") ==
false)
1253 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1254 myhist->SetBinContent(i + 1, 1);
1257 if (specialterm.Contains(
"ERR") ==
false)
1259 for (
int i = 0; i <
myhist->GetXaxis()->GetNbins(); i++)
1260 myhist->SetBinError(i + 1, 0);
1263 if (specialterm.Contains(
"TOPERR"))
1265 for (
int i = 0; i < hist1->GetXaxis()->GetNbins(); i++)
1266 hist1->SetBinError(i + 1, 0);
1267 histtool->Chi2(hist0, hist1,
myhist);
1270 if (specialterm.Contains(
"BOTTOMERR"))
1272 for (
int i = 0; i < hist0->GetXaxis()->GetNbins(); i++)
1273 hist0->SetBinError(i + 1, 0);
1274 histtool->Chi2(hist0, hist1,
myhist);
1291 for (
int i = 1; i <=
myhist->GetNbinsX(); i++)
1293 if (
myhist->GetBinLowEdge(i) < xmin)
1295 if (
myhist->GetBinLowEdge(i) +
myhist->GetBinWidth(i) > xmax)
1300 ymin =
myhist->GetBinContent(i) -
myhist->GetBinError(i);
1301 ymax =
myhist->GetBinContent(i) +
myhist->GetBinError(i);
1305 if (ymin >
myhist->GetBinContent(i) -
myhist->GetBinError(i))
1306 ymin =
myhist->GetBinContent(i) -
myhist->GetBinError(i);
1307 if (ymax < myhist->GetBinContent(i) +
myhist->GetBinError(i))
1308 ymax =
myhist->GetBinContent(i) +
myhist->GetBinError(i);
1314 return std::pair<double, double>(ymin, ymax);
1334FigureHStack::FigureHStack(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname,
const std::vector<TString> &linkhists,
const TString &option,
FigureElement *mother)
1335 :
FigureElement(MSG, shelper, elementname,
"FigureHStack", mother)
1339 myhstack =
new THStack(elementname,
"");
1341 if (linkhists.size() == 0)
1342 MSGUser()->MSG_ERROR(
"you should link at least one hist to hstack");
1347 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureHStack::SetStyle");
1354 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not exist, will be ignored");
1358 if (obj->GetTypeName() !=
"FigureHist1D")
1360 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not belong to FigureHist1D, will be ignored");
1364 std::shared_ptr<FigureHist1D> hist = std::dynamic_pointer_cast<FigureHist1D>(obj);
1365 if (hist->FromHistLink ==
true && hist->myhist ==
nullptr)
1366 hist->CreateHistFromHistLink();
1369 hist->ForHStack =
true;
1375 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureHStack::DrawElement");
1382 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not exist, will be ignored");
1386 if (obj->GetTypeName() !=
"FigureHist1D")
1388 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not belong to FigureHist1D, will be ignored");
1392 std::shared_ptr<FigureHist1D> hist = std::dynamic_pointer_cast<FigureHist1D>(obj);
1393 if (hist->FromHistLink ==
true && hist->myhist ==
nullptr)
1394 hist->CreateHistFromHistLink();
1398 empty_hist = (TH1D *)(hist->GetHist()->Clone(
"empty_hist"));
1449 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not exist, will be ignored");
1453 if (obj->GetTypeName() !=
"FigureHist1D")
1455 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not belong to FigureHist1D, will be ignored");
1459 std::shared_ptr<FigureHist1D> hist = std::dynamic_pointer_cast<FigureHist1D>(obj);
1460 if (hist->FromHistLink ==
true && hist->myhist ==
nullptr)
1461 hist->CreateHistFromHistLink();
1465 total_hist = (TH1D *)(hist->GetHist()->Clone(
"total_hist"));
1484 for (
int i = 1; i <=
total_hist->GetNbinsX(); i++)
1500 if (ymax < total_hist->GetBinContent(i) +
total_hist->GetBinError(i))
1507 return std::pair<double, double>(ymin, ymax);
1512 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureHStack::Scale");
1518 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not exist, will be ignored");
1522 if (obj->GetTypeName() !=
"FigureHist1D")
1524 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not belong to FigureHist1D, will be ignored");
1528 std::shared_ptr<FigureHist1D> hist = std::dynamic_pointer_cast<FigureHist1D>(obj);
1529 hist->Scale(factor);
1538 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigureHStack::Rebin");
1544 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not exist, will be ignored");
1548 if (obj->GetTypeName() !=
"FigureHist1D")
1550 MSGUser()->MSG_WARNING(
"input element ",
name,
" does not belong to FigureHist1D, will be ignored");
1554 std::shared_ptr<FigureHist1D> hist = std::dynamic_pointer_cast<FigureHist1D>(obj);
1574FigureGraph1D::FigureGraph1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname, TGraph *graph,
const TString &option,
FigureElement *mother, std::function<
void(TGraph *)> optionfunc)
1575 :
FigureElement(MSG, shelper, elementname,
"FigureGraph1D", mother)
1577 mygraph = (TGraph *)graph->Clone(TString::Format(
"Temp_%s", elementname.Data()));
1598 for (
int i = 0; i <
mygraph->GetN(); i++)
1600 auto xvalue =
mygraph->GetPointX(i);
1601 auto xerrorup =
mygraph->GetErrorXhigh(i);
1602 auto xerrordown =
mygraph->GetErrorXlow(i);
1604 auto yvalue =
mygraph->GetPointY(i);
1605 auto yerrorup =
mygraph->GetErrorYhigh(i);
1606 auto yerrordown =
mygraph->GetErrorYlow(i);
1617 if (xvalue - xerrordown < xmin || xvalue + xerrorup > xmax)
1622 ymin = yvalue - yerrordown;
1623 ymax = yvalue + yerrorup;
1627 if (ymin > yvalue - yerrordown)
1628 ymin = yvalue - yerrordown;
1629 if (ymax < yvalue + yerrorup)
1630 ymax = yvalue + yerrorup;
1636 return std::pair<double, double>(ymin, ymax);
1646FigureFunc1D::FigureFunc1D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname, TF1 *func,
const TString &option,
FigureElement *mother, std::function<
void(TF1 *)> optionfunc)
1647 :
FigureElement(MSG, shelper, elementname,
"FigureFunc1D", mother)
1649 myfunc = (TF1 *)func->Clone(TString::Format(
"Temp_%s", elementname.Data()));
1667 return std::pair<double, double>(
myfunc->GetMinimum(xmin, xmax),
myfunc->GetMaximum(xmin, xmax));
1676FigureHist2D::FigureHist2D(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname, TH2D *hist,
const TString &option,
FigureElement *mother, std::function<
void(TH2D *)> optionfunc)
1677 :
FigureElement(MSG, shelper, elementname,
"FigureHist2D", mother)
1679 myhist = (TH2D *)hist->Clone(TString::Format(
"Temp_%s", elementname.Data()));
1691 myhist->RebinX(rebinnumx);
1692 myhist->RebinY(rebinnumy);
1714 const TString &content,
double posx,
double poxy, Color_t color,
FigureElement *mother, std::function<
void(TLatex *)> optionfunc)
1715 :
FigureElement(MSG, shelper, content,
"FigureLatex", mother)
1717 mylatex =
new TLatex(posx, poxy, content.TString::Data());
1741FigurePad::FigurePad(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname,
int lbx,
int lby,
int rtx,
int rty,
FigureElement *mother, std::function<
void(TPad *)> optionfunc)
1742 :
FigureElement(MSG, shelper, elementname,
"FigurePad", mother)
1744 mypad =
new TPad(elementname.TString::Data(), elementname.TString::Data(),
1775 std::deque<std::shared_ptr<FigureElement>> v_legend_elements;
1779 legend_options = std::vector<TString>(v_legend_elements.size(),
"lpfe");
1787 if (elem->GetName() == entry)
1788 v_legend_elements.emplace_back(elem);
1792 if (i != v_legend_elements.size())
1793 MSGUser()->MSG_WARNING(
"Given legend entry ", entry,
" does not exist in the linked objects");
1797 for (
int i = 0; i < v_legend_elements.size(); ++i)
1799 auto elem = v_legend_elements.at(i);
1801 if (elem->IsType(
"FigureHist1D"))
1803 auto hist = std::dynamic_pointer_cast<FigureHist1D>(elem);
1804 if (!hist->DrawAsTGraph)
1805 legend->AddEntry(hist->GetHist(), elem->GetName(), elem_option);
1807 legend->AddEntry(hist->mygraph, elem->GetName(), elem_option);
1809 if (elem->IsType(
"FigureGraph1D"))
1810 legend->AddEntry((std::dynamic_pointer_cast<FigureGraph1D>(elem))->GetGraph(), elem->GetName(), elem_option);
1811 if (elem->IsType(
"FigureFunc1D"))
1812 legend->AddEntry((std::dynamic_pointer_cast<FigureFunc1D>(elem))->GetFunc(), elem->GetName(), elem_option);
1813 if (elem->IsType(
"FigureHist2D"))
1814 legend->AddEntry((std::dynamic_pointer_cast<FigureHist2D>(elem))->GetHist(), elem->GetName(), elem_option);
1815 if (elem->IsType(
"FigureHStack"))
1817 auto hstack = std::dynamic_pointer_cast<FigureHStack>(elem);
1818 if (hstack->draw_total_hist)
1819 legend->AddEntry((std::dynamic_pointer_cast<FigureHStack>(elem))->GetTotalHist(), elem->GetName(), elem_option);
1826 TLatex *atlas_text =
new TLatex(
legend->GetX1(),
legend->GetY2() - 0.03,
"ATLAS");
1827 atlas_text->SetNDC();
1828 atlas_text->SetTextFont(72);
1829 atlas_text->SetTextSize(
StyleUser()->LEGEND_TEXT_SIZE_PERCENT);
1830 atlas_text->SetTextColor(1);
1831 atlas_text->AppendPad();
1836 rest_text.SetTextFont(42);
1837 rest_text.SetTextSize(
StyleUser()->LEGEND_TEXT_SIZE_PERCENT);
1838 rest_text.SetTextColor(1);
1839 rest_text.DrawLatex(
legend->GetX1() + 1.6 *
StyleUser()->LEGEND_TEXT_SIZE_PERCENT * 696 *
GetPad()->GetWh() / (472 *
GetPad()->GetWw()),
legend->GetY2() - 0.03, rest_info.Data());
1841 legend->SetHeader(
"",
"");
1853 mypad->RedrawAxis();
1874std::shared_ptr<FigurePad>
FigurePad::BookPad(
const TString &padname,
int lbx,
int lby,
int rtx,
int rty, std::function<
void(TPad *)> optionfunc)
1879 auto newpad = std::shared_ptr<FigurePad>(
new FigurePad(
MSGUser(),
StyleUser(), padname, lbx, lby, rtx, rty,
this, optionfunc));
1881 MSGUser()->MSG_ERROR(
"New Pad ", padname.TString::Data(),
" is not within the Canvas ",
GetName().TString::Data());
1893std::shared_ptr<FigureHist1D>
FigurePad::SetInputHist1D(
const TString &elementname, TH1D *hist,
const TString &option, std::function<
void(TH1D *)> optionfunc)
1898 TString newoption = option;
1900 newoption = option +
" same";
1901 auto newhist = std::shared_ptr<FigureHist1D>(
new FigureHist1D(
MSGUser(),
StyleUser(), elementname, hist, newoption,
this, optionfunc));
1920std::shared_ptr<FigureHist1D>
FigurePad::SetInputHist1D(
const TString &elementname,
const TString &linkinfo,
const TString &option, std::function<
void(TH1D *)> optionfunc)
1925 TString newoption = option;
1927 newoption = option +
" same";
1928 auto newhist = std::shared_ptr<FigureHist1D>(
new FigureHist1D(
MSGUser(),
StyleUser(), elementname, linkinfo, newoption,
this, optionfunc));
1949 TString newoption = option;
1951 newoption = option +
" same";
1952 auto newhist = std::shared_ptr<FigureHist1D>(
new FigureHist1D(
MSGUser(),
StyleUser(), elementname, hist, newoption,
this, optionfunc));
1971std::shared_ptr<FigureHist1D>
FigurePad::SetInputHist1DGraph(
const TString &elementname,
const TString &linkinfo,
const TString &option, std::function<
void(TGraph *)> optionfunc)
1976 TString newoption = option;
1978 newoption = option +
" same";
1979 auto newhist = std::shared_ptr<FigureHist1D>(
new FigureHist1D(
MSGUser(),
StyleUser(), elementname, linkinfo, newoption,
this, optionfunc));
1994std::shared_ptr<FigureHStack>
FigurePad::SetHStack(
const TString &elementname,
const std::vector<TString> &linkinfo,
const TString &option)
1999 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigurePad::SetHStack");
2002 MSGUser()->MSG_WARNING(
"THStack for this pad has already existed");
2023std::shared_ptr<FigureGraph1D>
FigurePad::SetInputGraph1D(
const TString &elementname, TGraph *graph,
const TString &option, std::function<
void(TGraph *)> optionfunc)
2028 TString newoption = option;
2030 newoption = option +
" same";
2048std::shared_ptr<FigureFunc1D>
FigurePad::SetInputFunc1D(
const TString &elementname, TF1 *func,
const TString &option, std::function<
void(TF1 *)> optionfunc)
2053 TString newoption = option;
2055 newoption = option +
" same";
2056 auto newfunc = std::shared_ptr<FigureFunc1D>(
new FigureFunc1D(
MSGUser(),
StyleUser(), elementname, func, newoption,
this, optionfunc));
2073std::shared_ptr<FigureHist2D>
FigurePad::SetInputHist2D(
const TString &elementname, TH2D *hist,
const TString &option, std::function<
void(TH2D *)> optionfunc)
2078 TString newoption = option;
2080 newoption = option +
" same";
2081 auto newhist = std::shared_ptr<FigureHist2D>(
new FigureHist2D(
MSGUser(),
StyleUser(), elementname, hist, newoption,
this, optionfunc));
2097void FigurePad::SetLatex(
const TString &content,
double posx,
double poxy, Color_t color, std::function<
void(TLatex *)> optionfunc)
2102 auto newlatex = std::shared_ptr<FigureLatex>(
new FigureLatex(
MSGUser(),
StyleUser(), content, posx, poxy, color,
this, optionfunc));
2115 SetLatex(
"ATLAS", posx, posy, color, [](TLatex *latex)
2116 { latex->SetTextFont(72); });
2121 SetLatex(content, posx + space, posy, color);
2129void FigurePad::Norm(
const TString &elemname1,
const TString &elemname2,
double xmin,
double xmax)
2138 if (elem1->IsType(
"FigureHist1D") && elem2->IsType(
"FigureHist1D"))
2140 h1 = (std::dynamic_pointer_cast<FigureHist1D>(elem1))->GetHist();
2141 h2 = (std::dynamic_pointer_cast<FigureHist1D>(elem2))->GetHist();
2143 else if (elem1->IsType(
"FigureHStack") && elem2->IsType(
"FigureHist1D"))
2145 h1 = (std::dynamic_pointer_cast<FigureHStack>(elem1))->GetTotalHist();
2146 h2 = (std::dynamic_pointer_cast<FigureHist1D>(elem2))->GetHist();
2148 else if (elem1->IsType(
"FigureHist1D") && elem2->IsType(
"FigureHStack"))
2150 h1 = (std::dynamic_pointer_cast<FigureHist1D>(elem1))->GetHist();
2151 h2 = (std::dynamic_pointer_cast<FigureHStack>(elem2))->GetTotalHist();
2155 auto titleguard =
MSGUser()->StartTitleWithGuard(
"FigurePad::Norm");
2156 MSGUser()->MSG_WARNING(
"can only norm element with type FigureHist1D or FigureHStack");
2161 if (xmin == xmax && xmin == 0)
2163 factor = h2->Integral() / h1->Integral();
2167 int bin1 = h1->FindBin(xmin);
2168 int bin2 = h1->FindBin(xmax);
2170 factor = h2->Integral(bin1, bin2) / h1->Integral(bin1, bin2);
2173 if (elem1->IsType(
"FigureHist1D"))
2174 std::dynamic_pointer_cast<FigureHist1D>(elem1)->Scale(factor);
2175 if (elem1->IsType(
"FigureHStack"))
2176 std::dynamic_pointer_cast<FigureHStack>(elem1)->Scale(factor);
2197void FigurePad::SetLegend(
const TString &header,
const TString &option,
double xmin,
double ymin,
double xmax,
double ymax)
2222 if (entries.size() != options.size())
2224 MSGUser()->MSG_WARNING(
"entries and options must have the same size");
2252 mypad->SetLogx(value);
2258 mypad->SetLogy(value);
2264 mypad->SetLogz(value);
2299FigureCanvas::FigureCanvas(std::shared_ptr<MSGTool> MSG, std::shared_ptr<FigureStyleHelper> shelper,
const TString &elementname,
int npx,
int npy)
2300 :
FigureElement(MSG, shelper, elementname,
"FigureCanvas", nullptr)
2302 mycanvas =
new TCanvas(elementname.TString::Data(), elementname.TString::Data(), npx, npy);
2337std::shared_ptr<FigurePad>
FigureCanvas::BookPad(
const TString &padname,
int lbx,
int lby,
int rtx,
int rty, std::function<
void(TPad *)> optionfunc)
2342 auto newpad = std::shared_ptr<FigurePad>(
new FigurePad(
MSGUser(),
StyleUser(), padname, lbx, lby, rtx, rty,
this, optionfunc));
2344 MSGUser()->MSG_ERROR(
"New Pad ", padname.TString::Data(),
" is not within the Canvas ",
GetName().TString::Data());
2358std::shared_ptr<FigurePad>
FigureCanvas::BookPadNDC(
const TString &padname,
double lbx,
double lby,
double rtx,
double rty, std::function<
void(TPad *)> optionfunc)
2368 auto newpad = std::shared_ptr<FigurePad>(
new FigurePad(
MSGUser(),
StyleUser(), padname, newlbx, newlby, newrtx, newrty,
this, optionfunc));
2370 MSGUser()->MSG_ERROR(
"New Pad ", padname.TString::Data(),
" is not within the Canvas ",
GetName().TString::Data());
2382 stylehelper = std::make_shared<FigureStyleHelper>(MSG);
2426 MSGUser()->MSG_INFO(
"Draw ", iter.first.TString::Data());
2427 iter.second->Draw();
2428 iter.second->SaveAs(TString::Format(
"%s/%s",
figuredir.TString::Data(), iter.first.TString::Data()));