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))
62 std::cout << __PRETTY_FUNCTION__ <<
", fTotalGraph " <<
fTotalGraph << std::endl;
65 if(graph->GetN() == 0) {
66 std::cout << __PRETTY_FUNCTION__ <<
": graph \"" << graph->GetName() <<
"\", label \"" << label <<
"\" is empty, not adding it" << std::endl;
70 graph->GetListOfFunctions()->Clear();
79 double* rhsX = graph->GetX();
80 double* rhsY = graph->GetY();
81 double* rhsEX = graph->GetEX();
82 double* rhsEY = graph->GetEY();
86 std::vector<std::tuple<double, double, double, double, size_t, size_t>> data(
fTotalGraph->GetN() + graph->GetN());
91 for(
int i = 0; i < graph->GetN(); ++i) {
92 data[
fTotalGraph->GetN() + i] = std::make_tuple(rhsX[i], rhsY[i], rhsEX[i], rhsEY[i],
fGraphs.size(), i);
95 std::sort(data.begin(), data.end());
105 for(
size_t i = 0; i < data.size(); ++i) {
106 fTotalGraph->SetPoint(
static_cast<Int_t
>(i), std::get<0>(data[i]), std::get<1>(data[i]));
107 fTotalGraph->SetPointError(
static_cast<Int_t
>(i), std::get<2>(data[i]), std::get<3>(data[i]));
120 fGraphs.emplace_back(
this, graph);
124 fGraphs.back().SetLineColor(
static_cast<Color_t
>(
fGraphs.size()));
125 fGraphs.back().SetMarkerColor(
static_cast<Color_t
>(
fGraphs.size()));
126 fGraphs.back().SetMarkerStyle(
static_cast<Style_t
>(
fGraphs.size()));
132 std::cout <<
"done" << std::endl;
135 return static_cast<int>(
fGraphs.size() - 1);
142 if(calibration !=
nullptr && (!
fResidualSet || force)) {
144 std::cout <<
"calibration " << calibration <<
", fResidualSet " << (
fResidualSet ?
"true" :
"false") <<
", force " << (force ?
"true" :
"false") <<
", calibration: " << std::endl;
145 calibration->Print();
154 fTotalResidualGraph->SetPointError(i, TMath::Sqrt(TMath::Power(ey[i], 2) + TMath::Power(ex[i] * calibration->Derivative(x[i]), 2)), ey[i]);
157 std::cout <<
"Done calculating total residual graph with " <<
fTotalResidualGraph->GetN() <<
" points" << std::endl;
159 for(
size_t g = 0; g <
fGraphs.size(); ++g) {
165 for(
int i = 0; i <
fGraphs[g].GetN(); ++i) {
167 fResidualGraphs[g].SetPointError(i, TMath::Sqrt(TMath::Power(ey[i], 2) + TMath::Power(ex[i] * calibration->Derivative(x[i]), 2)), ey[i]);
171 std::cout <<
"Done calculating all " <<
fGraphs.size() <<
" individual residual graphs" << std::endl;
174 auto* mother = gPad->GetMother();
176 while(mother->GetPad(pad) !=
nullptr) {
177 if(
fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"pad " << pad <<
" = " << std::flush << mother->GetPad(pad) <<
" = " << std::flush << mother->GetPad(pad)->GetName() <<
": modifying, " << std::flush; }
178 mother->GetPad(pad)->Modified();
180 mother->GetPad(pad)->Update();
187 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; }
197 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;
205 TString options = opt;
207 if(options.Contains(
"same")) {
208 options.Remove(options.Index(
"same"), 4);
209 opt = options.Data();
213 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing total graph with option \"" << options.Data() <<
"\" on gPad " << gPad->GetName() << std::endl; }
217 fTotalGraph->GetHistogram()->GetXaxis()->CenterTitle();
219 fTotalGraph->GetHistogram()->GetYaxis()->CenterTitle();
223 for(
size_t i = 0; i <
fGraphs.size(); ++i) {
224 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; }
226 if(legend !=
nullptr) {
231 if(legend !=
nullptr) {
238 TString options = opt;
241 if(
fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
" drawing total residual graph with option \"" << options.Data() <<
"\" on gPad " << gPad->GetName() << std::endl; }
244 if(
hist !=
nullptr) {
245 hist->GetXaxis()->SetLabelSize(0.06);
247 std::cout <<
"Failed to get histogram for graph:" << std::endl;
252 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; }
254 if(legend !=
nullptr) {
258 if(legend !=
nullptr) {
268 std::cout << __PRETTY_FUNCTION__ <<
": point " << px <<
", " << py <<
"; gPad " << gPad->GetName() <<
": " << gPad->AbsPixeltoX(px) <<
", " << gPad->AbsPixeltoY(py) << std::endl;
279 std::cout << __PRETTY_FUNCTION__ <<
": point " << px <<
", " << py <<
"; gPad " << gPad->GetName() <<
": " << gPad->AbsPixeltoX(px) <<
", " << gPad->AbsPixeltoY(py) << std::endl;
295 double* x = graph->GetX();
296 double* y = graph->GetY();
297 for(i = 0; i < graph->GetN(); i++) {
298 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(x[i]));
299 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(y[i]));
301 if(dpx * dpx + dpy * dpy < 100) {
303 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;
309 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;
316 std::cout << __PRETTY_FUNCTION__ << std::endl;
332 std::cout << point <<
" removed residual point" << std::endl;
339 std::cout <<
"point " << point <<
" out of range?" << std::endl;
352 std::cout <<
fGraphIndex[p] <<
" != " << oldGraph <<
" || " <<
fPointIndex[p] <<
" < " << oldPoint <<
": decrementing index" << std::endl;
357 auto* mother = gPad->GetMother();
360 while(mother->GetPad(pad) !=
nullptr) {
361 mother->GetPad(pad)->Modified();
368 std::array<Longptr_t, 2> args = {
static_cast<int64_t
>(oldGraph),
static_cast<int64_t
>(oldPoint)};
370 Emit(
"RemovePoint(Int_t, Int_t)", args.data());
388 std::cout << point <<
" removed residual point" << std::endl;
395 std::cout <<
"point " << point <<
" out of range?" << std::endl;
408 std::cout <<
fGraphIndex[p] <<
" != " << oldGraph <<
" || " <<
fPointIndex[p] <<
" < " << oldPoint <<
": decrementing index" << std::endl;
413 auto* mother = gPad->GetMother();
416 while(mother->GetPad(pad) !=
nullptr) {
417 mother->GetPad(pad)->Modified();
424 std::array<Longptr_t, 2> args = {
static_cast<int64_t
>(oldGraph),
static_cast<int64_t
>(oldPoint)};
426 Emit(
"RemovePoint(Int_t, Int_t)", args.data());
436 graph.Sort(&TGraph::CompareY);
446 std::cout << __PRETTY_FUNCTION__ << std::endl;
450 for(
size_t g = 1; g <
fGraphs.size(); ++g) {
452 if(graph.GetN() == 0) {
453 std::cout <<
"No entries in " << g <<
". graph" << std::endl;
455 double* x = graph.GetX();
456 double* y = graph.GetY();
459 for(g2 = 0; (useAllPrevious ? g2 < g : g2 < 1); ++g2) {
460 double minRef =
fGraphs[g2].GetX()[0];
463 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;
465 if(maxRef < x[0] || x[graph.GetN() - 1] < minRef) {
467 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;
473 for(
int p = 0; p < graph.GetN(); ++p) {
474 if(minRef < x[p] && x[p] < maxRef) {
475 sum +=
fGraphs[g2].Eval(x[p]) / y[p];
486 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;
497 std::cerr <<
"No graphs added yet, makes no sense to reset total graph?" << std::endl;
503 newSize += graph.GetN();
507 std::vector<std::tuple<double, double, double, double, size_t, size_t>> data(newSize);
509 for(
size_t i = 0; i <
fGraphs.size(); ++i) {
513 double* eX =
fGraphs[i].GetEX();
514 double* eY =
fGraphs[i].GetEY();
515 for(
int p = 0; p <
fGraphs[i].GetN(); ++p, ++counter) {
517 data[counter] = std::make_tuple(x[p], y[p], eX[p], eY[p], i, p);
521 std::sort(data.begin(), data.end());
531 for(
size_t i = 0; i < data.size(); ++i) {
532 fTotalGraph->SetPoint(i, std::get<0>(data[i]), std::get<1>(data[i]));
533 fTotalGraph->SetPointError(i, std::get<2>(data[i]), std::get<3>(data[i]));
549 std::cout << __PRETTY_FUNCTION__ <<
", fTotalGraph " <<
fTotalGraph << std::endl;
552 std::cout <<
"TCalibrationGraphSet " <<
this <<
" - " << GetName() <<
": " <<
fGraphs.size() <<
" calibration graphs, " <<
fResidualGraphs.size() <<
" residual graphs, " <<
fLabel.size() <<
" labels, ";
554 std::cout <<
fTotalGraph->GetN() <<
" calibration points, and ";
556 std::cout <<
" no calibration points, and ";
561 std::cout <<
" no residual points" << std::endl;
563 TString options = opt;
564 bool errors = options.Contains(
"e", TString::ECaseCompare::kIgnoreCase);
566 double* x = g.GetX();
567 double* y = g.GetY();
568 double* ex = g.GetEX();
569 double* ey = g.GetEY();
570 for(
int p = 0; p < g.GetN(); ++p) {
572 std::cout << p <<
" - " << x[p] <<
"(" << ex[p] <<
"), " << y[p] <<
"(" << ey[p] <<
"); ";
574 std::cout << p <<
" - " << x[p] <<
", " << y[p] <<
"; ";
577 std::cout << std::endl;
579 std::cout <<
fGraphIndex.size() <<
" graph indices: ";
580 for(
const auto& i :
fGraphIndex) { std::cout << std::setw(3) << i <<
" "; }
581 std::cout << std::endl;
582 std::cout <<
fPointIndex.size() <<
" point indices: ";
583 for(
const auto& i :
fPointIndex) { std::cout << std::setw(3) << i <<
" "; }
584 std::cout << std::endl;
585 std::cout <<
"---- total graph ----" << std::endl;
589 std::cout << p <<
" - " << x[p] <<
", " << y[p] <<
"; ";
591 std::cout << std::endl;
592 std::cout <<
"---------------------" << std::endl;
607 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.
void Print(Option_t *opt="") const override
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.