Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
xRooNode_interactive.cxx
Go to the documentation of this file.
1/*
2 * Project: xRooFit
3 * Author:
4 * Will Buttinger, RAL 2022
5 *
6 * Copyright (c) 2022, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13// Interactive methods of xRooNode
14
15#include "xRooFit/xRooNode.h"
16
17#include "RooArgList.h"
18#include "RooArgSet.h"
19
20#include "TCanvas.h"
21#include "TVirtualX.h"
22#include "TH1F.h"
23#include "TStyle.h"
24#include "TGraphAsymmErrors.h"
25#include "TMultiGraph.h"
26#include "TSystem.h"
27
29
30void xRooNode::Interactive_Pull()
31{
32 static bool doRestore = false;
33 auto select = dynamic_cast<TGraph *>(gPad->GetSelected());
34 // if (!select) return;
35 int event = gPad->GetEvent();
36 if (event == 1) {
37 doRestore = false;
38 // if this is one of the 'black' points, color it temporarily
39 } else if (event == 11 || doRestore) {
40 if (!select || doRestore) {
41 // now need to assemble a snapshot corresponding to the current variation
42 auto _h = static_cast<TGraph *>(gPad->GetPrimitive("nominal"))->GetHistogram();
43 for (int i = 1; i <= _h->GetNbinsX(); i++) {
44 std::string parName = _h->GetXaxis()->GetBinLabel(i);
45 // ensure point is back .. sometimes editing mode allows point to drift
46 auto _gr = static_cast<TGraph *>(static_cast<TMultiGraph *>(gPad->GetPrimitive("editables"))
47 ->GetListOfGraphs()
48 ->FindObject(parName.c_str()));
49 _gr->SetPoint(0, i - 1, static_cast<TGraph *>(gPad->GetPrimitive("nominal"))->GetPointY(i - 1));
50 }
51 gPad->GetMother()->GetMother()->cd();
52 doRestore = false;
53 return;
54 }
55 doRestore = true;
56 // mouse up event, if this was an original point it needs snapping back
57 // double _y = select->GetPointY(0);
58 TString _name = select->GetName();
59 TString _varyName = "";
60 if (_name.Contains(";")) {
61 _varyName = TString(_name(_name.Index(";") + 1, _name.Length()));
62 _name = _name(0, _name.Index(";"));
63 }
64 auto _h = static_cast<TH1 *>(gPad->GetPrimitive("nominal")->FindObject("scales"));
65 if (!_h)
66 return;
67 for (int i = 1; i <= _h->GetNbinsX(); i++) {
68 if (_name == _h->GetXaxis()->GetBinLabel(i)) {
69 auto _gr = static_cast<TGraph *>(gPad->GetPrimitive("nominal"));
70 if (_varyName == "") {
71 int vNum = 1;
72 TGraphAsymmErrors *newPoint = dynamic_cast<TGraphAsymmErrors *>(
73 gPad->GetPrimitive(TString::Format("%s;variation %d", select->GetName(), vNum)));
74 while (newPoint && newPoint->GetN() > 0) {
75 vNum++;
76 newPoint = static_cast<TGraphAsymmErrors *>(
77 gPad->GetPrimitive(TString::Format("%s;variation %d", select->GetName(), vNum)));
78 }
79 _varyName = TString::Format("variation %d", vNum);
80 if (!newPoint)
81 newPoint = static_cast<TGraphAsymmErrors *>(
82 select->Clone(TString::Format("%s;%s", select->GetName(), _varyName.Data())));
83 newPoint->SetPointX(0, _gr->GetPointX(i - 1));
84 newPoint->SetMarkerColor(860 + (vNum - 1) * 20);
85 newPoint->SetLineColor(newPoint->GetMarkerColor());
86 newPoint->SetPointEYlow(0, 0);
87 newPoint->SetPointEYhigh(0, 0); // remove errors because currently meaningless!
88 newPoint->Draw("z0p");
89 select->SetPoint(0, _gr->GetPointX(i - 1), _gr->GetPointY(i - 1));
90 select = newPoint;
91 } else {
92 select->SetPointX(0, _gr->GetPointX(i - 1));
93 }
94 static_cast<TGraph *>(
95 static_cast<TMultiGraph *>(gPad->GetPrimitive("editables"))->GetListOfGraphs()->FindObject(_name))
96 ->SetPoint(0, i - 1, _gr->GetPointY(i - 1));
97 break;
98 }
99 }
100
101 // then do an overlay update
102 auto _node = dynamic_cast<xRooNode *>(gPad->GetPrimitive("node"));
103 if (!_node)
104 return;
105 RooArgSet _pars(_node->pars().argList());
106 std::unique_ptr<RooArgSet> snap(_pars.snapshot());
107
108 // now need to assemble a snapshot corresponding to the current variation
109 for (int i = 1; i <= _h->GetNbinsX(); i++) {
110 std::string parName = _h->GetXaxis()->GetBinLabel(i);
111 // ensure point is back .. sometimes editing mode allows point to drift
112 // dynamic_cast<TGraph*>(gPad->GetPrimitive(parName.c_str()))->SetPoint(0,i-1,dynamic_cast<TGraph*>(gPad->GetPrimitive("nominal"))->GetPointY(i-1));
113 if (auto g =
114 dynamic_cast<TGraph *>(gPad->GetPrimitive(TString::Format("%s;%s", parName.c_str(), _varyName.Data())));
115 g && g->GetN() > 0) {
116 double _val =
117 g->GetPointY(0) * _h->GetBinError(i) + _h->GetBinContent(i); // error is scale, content is offset
118 _pars.setRealValue(parName.c_str(), _val);
119 g->SetTitle(TString::Format("%s=%g", parName.c_str(), _val));
120 } else {
121 _pars.setRealValue(parName.c_str(), static_cast<TGraph *>(gPad->GetPrimitive("nominal"))->GetPointY(i - 1) *
122 _h->GetBinError(i) +
123 _h->GetBinContent(i));
124 }
125 }
126 TAttLine bak = *gStyle;
127 TAttFill bak2 = *gStyle;
130 gStyle->SetLineColor(select->GetMarkerColor());
131 auto _tmpPad = gPad;
132 gPad->GetMother()->GetMother()->cd(1);
133 _node->Draw(TString::Format("same overlay%s", _varyName.Data()));
134 // TODO: find the drawn variation and set its title equal to a _pars value string
135 static_cast<TAttLine &>(*gStyle) = bak;
136 static_cast<TAttFill &>(*gStyle) = bak2;
137 _pars = *snap;
138 _tmpPad->GetCanvas()->cd();
139 gPad->GetCanvas()->Paint();
140 gPad->GetCanvas()->Update();
141 }
142}
143
144void xRooNode::Interactive_PLLPlot()
145{
146
147 // TObject *select = gPad->GetSelected();
148 // if(!select) return;
149 // if (!select->InheritsFrom(TGraph::Class())) {gPad->SetUniqueID(0); return;}
150 // gPad->GetCanvas()->FeedbackMode(true);
151
152 auto _pull_pad = gPad->GetPad(1);
153 auto _hidden_pad = gPad->GetPad(2);
154
155 if (!_pull_pad || strcmp(_pull_pad->GetName(), "pulls") != 0)
156 return;
157 if (!_hidden_pad)
158 return;
159
160 // erase old position and draw a line at current position
161 // int pxold = gPad->GetUniqueID();
162 int px = gPad->GetEventX();
163 // int py = gPad->GetEventY();
164 // int pymin = gPad->YtoAbsPixel(gPad->GetUymin());
165 // int pymax = gPad->YtoAbsPixel(gPad->GetUymax());
166 // if(pxold) gVirtualX->DrawLine(pxold,pymin,pxold,pymax);
167 // gVirtualX->DrawLine(px,pymin,px,pymax);
168 gPad->SetUniqueID(px);
169 float upx = gPad->AbsPixeltoX(px);
170 float x = gPad->PadtoX(upx);
171
172 // find which graph in the hidden pad best reflects current x value
173 TObject *foundGraph = nullptr;
174 for (auto g : *_hidden_pad->GetListOfPrimitives()) {
175 double midpoint = TString(g->GetName()).Atof();
176 if (!foundGraph)
177 foundGraph = g;
178 else {
179 midpoint = (midpoint + TString(foundGraph->GetName()).Atof()) / 2.;
180 }
181 if (midpoint >= x)
182 break;
183 foundGraph = g;
184 }
185 if (foundGraph) {
186 auto _x = TString(foundGraph->GetName()).Atof();
187 if (auto line = dynamic_cast<TGraph *>(gPad->GetListOfPrimitives()->FindObject("markerLine")); line) {
188 line->SetPointX(0, _x);
189 line->SetPointX(1, _x);
190 } else {
191 line = new TGraph;
192 line->SetLineStyle(2);
193 line->SetName("markerLine");
195 line->SetPoint(0, _x, -100);
196 line->SetPoint(1, _x, 100);
197 line->Draw("Lsame");
198 }
199 gPad->Modified();
200 gPad->Update();
201 for (auto o : *_pull_pad->GetListOfPrimitives()) {
202 if (!o->InheritsFrom("TGraph"))
203 continue;
204 if (_hidden_pad->GetListOfPrimitives()->FindObject(o) || TString(o->GetName()).EndsWith("_pull")) {
205 // todo: might need to delete the "_pull" plot if removing for first time
206 _pull_pad->GetListOfPrimitives()->Remove(o);
207 break;
208 }
209 }
210 auto tmp = gPad;
211 _pull_pad->cd();
212 foundGraph->Draw("pz0 same");
213 tmp->cd();
214 _pull_pad->Modified();
215 _pull_pad->Update();
216 }
217}
218
219void xRooNode::InteractiveObject::Interactive_PLLPlot(TVirtualPad *pad, TObject *obj, Int_t x, Int_t /*y*/)
220{
221
222 if (auto g = dynamic_cast<TGraph *>(obj); g && pad && pad->GetMother() && pad->GetNumber() == 1) {
223 auto frPad = pad->GetMother()->GetPad(2);
224 if (frPad) {
225 if (!g->IsHighlight())
226 x = -1;
227 else if (x >= 0)
228 x += 1;
229 // x is the point index
230 TVirtualPad *_pad = frPad->GetPad(x);
231 auto selPad = dynamic_cast<TVirtualPad *>(frPad->GetPrimitive("selected"));
232 if (_pad && selPad) {
233 auto prim = selPad->GetListOfPrimitives();
234 prim->Remove(prim->At(0));
235 prim->Add(_pad);
236
237 // for (auto p: *pad->GetListOfPrimitives()) {
238 // if (auto _p = dynamic_cast<TPad *>(p)) {
239 // _p->Modified();
240 // }
241 // }
242 // pad->Modified();
243 // pad->Update();
244 selPad->Modified();
245 selPad->Update();
247 }
248 }
249 }
250}
251
#define g(i)
Definition RSha256.hxx:105
@ kCanDelete
Definition TObject.h:367
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
#define gPad
The xRooNode class is designed to wrap over a TObject and provide functionality to aid with interacti...
Definition xRooNode.h:51
bool setRealValue(const char *name, double newVal=0.0, bool verbose=false)
Set value of a RooAbsRealLValue stored in set with given name to newVal No error messages are printed...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:178
Fill Area Attributes class.
Definition TAttFill.h:19
Line Attributes class.
Definition TAttLine.h:18
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:31
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition TAxis.cxx:440
TGraph with asymmetric error bars.
virtual void SetPointEYlow(Int_t i, Double_t eyl)
Set EYlow for point i.
virtual void SetPointEYhigh(Int_t i, Double_t eyh)
Set EYhigh for point i.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2315
Int_t GetN() const
Definition TGraph.h:130
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
Definition TGraph.cxx:809
TAxis * GetXaxis() const
Get x axis of the graph.
Definition TGraph.cxx:1540
virtual void SetPointX(Int_t i, Double_t x)
Set x value for point i.
Definition TGraph.cxx:2339
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:34
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:274
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition TObject.cxx:607
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2222
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2032
const char * Data() const
Definition TString.h:380
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:403
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual TList * GetListOfPrimitives() const =0
virtual TVirtualPad * GetMother() const =0
virtual TVirtualPad * GetPad(Int_t subpadnumber) const =0
virtual Int_t GetNumber() const =0
TLine * line
Double_t x[n]
Definition legend1.C:17
BEGIN_XROOFIT_NAMESPACE