15 Int_t px = gPad->GetEventX();
16 Int_t py = gPad->GetEventY();
22#if ROOT_VERSION_CODE < ROOT_VERSION(6, 26, 0)
23void TCalibrationGraph::Scale(
const double& scale)
26 Double_t* ey = GetEY();
28 for(
int i = 0; i < GetN(); ++i) {
38 : fTotalGraph(new TGraphErrors), fTotalResidualGraph(new TGraphErrors)
41 if(graph !=
nullptr) {
48 : fTotalGraph(new TGraphErrors), fTotalResidualGraph(new TGraphErrors), fXAxisLabel(std::move(xAxisLabel)), fYAxisLabel(std::move(yAxisLabel))
63 std::cout << __PRETTY_FUNCTION__ <<
", fTotalGraph " <<
fTotalGraph << std::endl;
66 if(graph->GetN() == 0) {
67 std::cout << __PRETTY_FUNCTION__ <<
": graph \"" << graph->GetName() <<
"\", label \"" << label <<
"\" is empty, not adding it" << std::endl;
71 graph->GetListOfFunctions()->Clear();
80 double* rhsX = graph->GetX();
81 double* rhsY = graph->GetY();
82 double* rhsEX = graph->GetEX();
83 double* rhsEY = graph->GetEY();
87 std::vector<std::tuple<double, double, double, double, size_t, size_t>> data(
fTotalGraph->GetN() + graph->GetN());
92 for(
int i = 0; i < graph->GetN(); ++i) {
93 data[
fTotalGraph->GetN() + i] = std::make_tuple(rhsX[i], rhsY[i], rhsEX[i], rhsEY[i],
fGraphs.size(), i);
96 std::sort(data.begin(), data.end());
106 for(
size_t i = 0; i < data.size(); ++i) {
107 fTotalGraph->SetPoint(
static_cast<Int_t
>(i), std::get<0>(data[i]), std::get<1>(data[i]));
108 fTotalGraph->SetPointError(
static_cast<Int_t
>(i), std::get<2>(data[i]), std::get<3>(data[i]));
121 fGraphs.emplace_back(
this, graph);
125 fGraphs.back().SetLineColor(
static_cast<Color_t
>(
fGraphs.size()));
126 fGraphs.back().SetMarkerColor(
static_cast<Color_t
>(
fGraphs.size()));
127 fGraphs.back().SetMarkerStyle(
static_cast<Style_t
>(
fGraphs.size()));
133 std::cout <<
"done" << std::endl;
136 return static_cast<int>(
fGraphs.size() - 1);
143 if(calibration !=
nullptr && (!
fResidualSet || force)) {
145 std::cout <<
"calibration " << calibration <<
", fResidualSet " << (
fResidualSet ?
"true" :
"false") <<
", force " << (force ?
"true" :
"false") <<
", calibration: " << std::endl;
146 calibration->Print();
155 fTotalResidualGraph->SetPointError(i, TMath::Sqrt(TMath::Power(ey[i], 2) + TMath::Power(ex[i] * calibration->Derivative(x[i]), 2)), ey[i]);
158 std::cout <<
"Done calculating total residual graph with " <<
fTotalResidualGraph->GetN() <<
" points" << std::endl;
160 for(
size_t g = 0; g <
fGraphs.size(); ++g) {
166 for(
int i = 0; i <
fGraphs[g].GetN(); ++i) {
168 fResidualGraphs[g].SetPointError(i, TMath::Sqrt(TMath::Power(ey[i], 2) + TMath::Power(ex[i] * calibration->Derivative(x[i]), 2)), ey[i]);
172 std::cout <<
"Done calculating all " <<
fGraphs.size() <<
" individual residual graphs" << std::endl;
175 auto* mother = gPad->GetMother();
177 while(mother->GetPad(pad) !=
nullptr) {
178 if(
fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"pad " << pad <<
" = " << std::flush << mother->GetPad(pad) <<
" = " << std::flush << mother->GetPad(pad)->GetName() <<
": modifying, " << std::flush; }
179 mother->GetPad(pad)->Modified();
181 mother->GetPad(pad)->Update();
188 if(
fVerboseLevel >
EVerbosity::kSubroutines) { std::cout << __PRETTY_FUNCTION__ <<
": didn't find calibration (" << calibration <<
"), or the residual was already set (" << (
fResidualSet ?
"true" :
"false") <<
") and we don't force it (" << (force ?
"true" :
"false") <<
")" << std::endl; }
198 std::cerr <<
"Trying to set axis title to \"" << title <<
"\" failed because no total graph is present for this title to be applied to!" << std::endl;
206 TString options = opt;
208 if(options.Contains(
"same")) {
209 options.Remove(options.Index(
"same"), 4);
210 opt = options.Data();
214 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing total graph with option \"" << options.Data() <<
"\" on gPad " << gPad->GetName() << std::endl; }
218 fTotalGraph->GetHistogram()->GetXaxis()->CenterTitle();
220 fTotalGraph->GetHistogram()->GetYaxis()->CenterTitle();
224 for(
size_t i = 0; i <
fGraphs.size(); ++i) {
225 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing " << i <<
". graph with option \"" << opt <<
"\", marker color " <<
fGraphs[i].GetMarkerColor() <<
" on gPad " << gPad->GetName() << std::endl; }
227 if(legend !=
nullptr) {
232 if(legend !=
nullptr) {
242 double minY =
hist->GetYaxis()->GetXmin();
243 double maxY =
hist->GetYaxis()->GetXmax();
247 std::cout << __PRETTY_FUNCTION__ <<
" changing line at zero to go from " << minY <<
" to " << maxY << std::endl;
253 TString options = opt;
256 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing total residual graph with option \"" << options.Data() <<
"\" on gPad " << gPad->GetName() << std::endl; }
259 if(
hist !=
nullptr) {
260 hist->GetXaxis()->SetLabelSize(0.06);
262 if(options.Contains(
"r0")) {
264 double minY =
hist->GetYaxis()->GetXmin();
265 double maxY =
hist->GetYaxis()->GetXmax();
267 std::cout << __PRETTY_FUNCTION__ <<
" drawing line at zero from " << minY <<
" to " << maxY <<
" as requested (\"" << options.Data() <<
"\") " << std::endl;
278 std::cout <<
"Failed to get histogram for graph:" << std::endl;
283 options.ReplaceAll(
"r0",
"");
285 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing " << i <<
". residual graph with option \"" << opt <<
"\", marker color " <<
fResidualGraphs[i].GetMarkerColor() <<
" on gPad " << gPad->GetName() << std::endl; }
287 if(legend !=
nullptr) {
291 if(legend !=
nullptr) {
301 std::cout << __PRETTY_FUNCTION__ <<
": point " << px <<
", " << py <<
"; gPad " << gPad->GetName() <<
": " << gPad->AbsPixeltoX(px) <<
", " << gPad->AbsPixeltoY(py) << std::endl;
312 std::cout << __PRETTY_FUNCTION__ <<
": point " << px <<
", " << py <<
"; gPad " << gPad->GetName() <<
": " << gPad->AbsPixeltoX(px) <<
", " << gPad->AbsPixeltoY(py) << std::endl;
328 double* x = graph->GetX();
329 double* y = graph->GetY();
330 for(i = 0; i < graph->GetN(); i++) {
331 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(x[i]));
332 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(y[i]));
334 if(dpx * dpx + dpy * dpy < 100) {
336 std::cout << i <<
": dpx = " << dpx <<
" = " << px <<
" - " << gPad->XtoAbsPixel(gPad->XtoPad(x[i])) <<
", dpy = " << dpy <<
" = " << py <<
" - " << gPad->YtoAbsPixel(gPad->YtoPad(y[i])) <<
" this is the point we're looking for at " << x[i] <<
", " << y[i] << std::endl;
342 std::cout << i <<
": dpx = " << dpx <<
" = " << px <<
" - " << gPad->XtoAbsPixel(gPad->XtoPad(x[i])) <<
", dpy = " << dpy <<
" = " << py <<
" - " << gPad->YtoAbsPixel(gPad->YtoPad(y[i])) <<
" not the point we're looking for" << std::endl;
349 std::cout << __PRETTY_FUNCTION__ << std::endl;
365 std::cout << point <<
" removed residual point" << std::endl;
372 std::cout <<
"point " << point <<
" out of range?" << std::endl;
385 std::cout <<
fGraphIndex[p] <<
" != " << oldGraph <<
" || " <<
fPointIndex[p] <<
" < " << oldPoint <<
": decrementing index" << std::endl;
390 auto* mother = gPad->GetMother();
393 while(mother->GetPad(pad) !=
nullptr) {
394 mother->GetPad(pad)->Modified();
401 std::array<Longptr_t, 2> args = {
static_cast<int64_t
>(oldGraph),
static_cast<int64_t
>(oldPoint)};
403 Emit(
"RemovePoint(Int_t, Int_t)", args.data());
421 std::cout << point <<
" removed residual point" << std::endl;
428 std::cout <<
"point " << point <<
" out of range?" << std::endl;
441 std::cout <<
fGraphIndex[p] <<
" != " << oldGraph <<
" || " <<
fPointIndex[p] <<
" < " << oldPoint <<
": decrementing index" << std::endl;
446 auto* mother = gPad->GetMother();
449 while(mother->GetPad(pad) !=
nullptr) {
450 mother->GetPad(pad)->Modified();
457 std::array<Longptr_t, 2> args = {
static_cast<int64_t
>(oldGraph),
static_cast<int64_t
>(oldPoint)};
459 Emit(
"RemovePoint(Int_t, Int_t)", args.data());
469 graph.Sort(&TGraph::CompareY);
479 std::cout << __PRETTY_FUNCTION__ << std::endl;
483 for(
size_t g = 1; g <
fGraphs.size(); ++g) {
485 if(graph.GetN() == 0) {
486 std::cout <<
"No entries in " << g <<
". graph" << std::endl;
488 double* x = graph.GetX();
489 double* y = graph.GetY();
492 for(g2 = 0; (useAllPrevious ? g2 < g : g2 < 1); ++g2) {
493 double minRef =
fGraphs[g2].GetX()[0];
496 std::cout <<
"Checking overlap between " << g2 <<
". graph (" <<
fGraphs[g2].GetN() <<
": " << minRef <<
" - " << maxRef <<
") and " << g <<
". graph (" << graph.GetN() << std::flush <<
": " << x[0] <<
" - " << x[graph.GetN() - 1] <<
")" << std::endl;
498 if(maxRef < x[0] || x[graph.GetN() - 1] < minRef) {
500 std::cout <<
"No overlap between " << g2 <<
". graph (" <<
fGraphs[g2].GetN() <<
": " << minRef <<
" - " << maxRef <<
") and " << g <<
". graph (" << graph.GetN() <<
": " << x[0] <<
" - " << x[graph.GetN() - 1] <<
")" << std::endl;
506 for(
int p = 0; p < graph.GetN(); ++p) {
507 if(minRef < x[p] && x[p] < maxRef) {
508 sum +=
fGraphs[g2].Eval(x[p]) / y[p];
519 std::cout <<
"No overlap(s) between 0. to " << g2 - 1 <<
". graph and " << g <<
". graph (" << graph.GetN() <<
": " << x[0] <<
" - " << x[graph.GetN() - 1] <<
"), not scaling this one!" << std::endl;
530 std::cerr <<
"No graphs added yet, makes no sense to reset total graph?" << std::endl;
536 newSize += graph.GetN();
540 std::vector<std::tuple<double, double, double, double, size_t, size_t>> data(newSize);
542 for(
size_t i = 0; i <
fGraphs.size(); ++i) {
546 double* eX =
fGraphs[i].GetEX();
547 double* eY =
fGraphs[i].GetEY();
548 for(
int p = 0; p <
fGraphs[i].GetN(); ++p, ++counter) {
550 data[counter] = std::make_tuple(x[p], y[p], eX[p], eY[p], i, p);
554 std::sort(data.begin(), data.end());
564 for(
size_t i = 0; i < data.size(); ++i) {
565 fTotalGraph->SetPoint(i, std::get<0>(data[i]), std::get<1>(data[i]));
566 fTotalGraph->SetPointError(i, std::get<2>(data[i]), std::get<3>(data[i]));
582 std::cout << __PRETTY_FUNCTION__ <<
", fTotalGraph " <<
fTotalGraph << std::endl;
585 std::cout <<
"TCalibrationGraphSet " <<
this <<
" - " << GetName() <<
": " <<
fGraphs.size() <<
" calibration graphs, " <<
fResidualGraphs.size() <<
" residual graphs, " <<
fLabel.size() <<
" labels, ";
587 std::cout <<
fTotalGraph->GetN() <<
" calibration points, and ";
589 std::cout <<
" no calibration points, and ";
594 std::cout <<
" no residual points" << std::endl;
596 TString options = opt;
597 bool errors = options.Contains(
"e", TString::ECaseCompare::kIgnoreCase);
599 double* x = g.GetX();
600 double* y = g.GetY();
601 double* ex = g.GetEX();
602 double* ey = g.GetEY();
603 for(
int p = 0; p < g.GetN(); ++p) {
605 std::cout << p <<
" - " << x[p] <<
"(" << ex[p] <<
"), " << y[p] <<
"(" << ey[p] <<
"); ";
607 std::cout << p <<
" - " << x[p] <<
", " << y[p] <<
"; ";
610 std::cout << std::endl;
612 std::cout <<
fGraphIndex.size() <<
" graph indices: ";
613 for(
const auto& i :
fGraphIndex) { std::cout << std::setw(3) << i <<
" "; }
614 std::cout << std::endl;
615 std::cout <<
fPointIndex.size() <<
" point indices: ";
616 for(
const auto& i :
fPointIndex) { std::cout << std::setw(3) << i <<
" "; }
617 std::cout << std::endl;
618 std::cout <<
"---- total graph ----" << std::endl;
622 std::cout << p <<
" - " << x[p] <<
", " << y[p] <<
"; ";
624 std::cout << std::endl;
625 std::cout <<
"---------------------" << std::endl;
640 TNamed::Clear(option);
TCalibrationGraphSet * fParent
pointer to the set this graph belongs to
bool fIsResidual
flag to indicate that this graph is for residuals
Int_t RemovePoint() override
void ResetTotalGraph()
reset the total graph and add the individual ones again (used e.g. after scaling of individual graphs...
void DrawResidual(Option_t *opt="", TLegend *legend=nullptr)
std::vector< size_t > fGraphIndex
Index of the graph this point belongs to.
int GetN()
Returns GetN(), i.e. number of points of the total graph.
std::vector< size_t > fPointIndex
Index of the point within the graph this point corresponds to.
bool SetResidual(const bool &force=false)
TCalibrationGraphSet(TGraphErrors *graph=nullptr, const std::string &label="")
std::string fYAxisLabel
The label of the y-axis.
static EVerbosity fVerboseLevel
Changes verbosity.
std::vector< TCalibrationGraph > fResidualGraphs
These are the graphs used for plotting the residuals per source.
TGraphErrors * fTotalGraph
The sum of the other graphs, used for fitting.
double fMaximumX
Maximum x-value.
double fMinimumY
Minimum y-value.
TLine * fZeroResidual
! The line denoting zero residual
void Print(Option_t *opt="") const override
void RefreshResidualLine()
double fMaximumY
Maximum y-value.
std::string fXAxisLabel
The label of the x-axis.
void Scale(bool useAllPrevious=true)
int Add(TGraphErrors *, const std::string &label)
Add new graph to set, using the label when creating legends during plotting.
void DrawCalibration(Option_t *opt="", TLegend *legend=nullptr)
TGraphErrors * fTotalResidualGraph
The sum of the residuals. Not really used apart from plotting (but overlayed with the individual grap...
bool fResidualSet
Flag to indicate if the residual has been set correctly.
void Clear(Option_t *option="") override
double fMinimumX
Minimum x-value.
Int_t RemovePoint(const Int_t &px, const Int_t &py)
void SetAxisTitle(const char *title)
Set axis title for the graph (form "x-axis title;y-axis title")
std::vector< TCalibrationGraph > fGraphs
These are the graphs used for plotting the calibration points per source.
TF1 * FitFunction()
Gets the calibration from the total graph (might be nullptr!).
Int_t RemoveResidualPoint(const Int_t &px, const Int_t &py)
static EVerbosity VerboseLevel()
std::vector< std::string > fLabel
The labels for the different graphs.