KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVPIDIntervalPainter.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Mon Jan 23 14:29:32 2017
2 //Author: Diego Gruyer
3 
4 #include "KVPIDIntervalPainter.h"
5 #include "TCanvas.h"
6 #include "TFrame.h"
7 #include "TVirtualPad.h"
8 #include "TVirtualX.h"
9 #include "TPoint.h"
10 #include "TROOT.h"
11 
13 
14 
15 
18 {
19  fMarker.Draw();
20  if (active_intervals) {
21  fLine1.Draw();
22  fLine2.Draw();
23  }
24 }
25 
26 
27 
29 
31 {
33  if (active_intervals) {
36  }
37 }
38 
39 
40 
45 
47 {
48  // updates the name & title from the interval's current Z & A
49  //
50  // updates the positions of the marker & lines from current values
51  SetName(Form("%d_%d", fInterval->GetZ(), fInterval->GetA()));
52  SetTitle(Form("%d_%d", fInterval->GetZ(), fInterval->GetA()));
53  fZ = fInterval->GetZ();
54  fA = fInterval->GetA();
58  if (!active_intervals) {
61  fCanvas->Modified();
62  fCanvas->Update();
63  }
64  else {
67  }
68 }
69 
70 
71 
78 
80  : TMarker(P->GetInterval()->GetPID(), P->GetHisto()->GetBinContent(P->GetHisto()->FindBin(P->GetInterval()->GetPID())), 23),
81  parent{P},
82  fLabel{GetX(), GetY(), Form(" (%d,%d)", P->GetInterval()->GetZ(), P->GetInterval()->GetA())},
83  def_color{itv_col},
84  pid{P->GetInterval()->GetPID()}
85 {
86  // Create marker for interval set.
87  //
88  // Marker coordinates are initialised from PID and contents of linearised histogram.
89  //
90  // Label is initialised with the (Z,A) of the interval
91  fLabel.SetTextAlign(12);
92  fLabel.SetTextFont(42);
93  fLabel.SetTextSize(0.0421941);
94 
97 }
98 
99 
100 
102 
104 {
105  if (pid < parent->GetHistoXAxisLowerLimit() || pid > parent->GetHistoXAxisUpperLimit()) {
106  // we only handle markers which are currently displayed in the visible part of the histogram
107  return;
108  }
109 
110  if (!gPad) return;
111 
112  TPoint p;
113  static Int_t pxold, pyold;
114  static Bool_t ndcsav;
115  Double_t dpx, dpy, xp1, yp1;
116  Bool_t opaque = gPad->OpaqueMoving();
117 
118  if (!gPad->IsEditable()) return;
119 
120  // force marker to stay on top of histogram bin
121  double fixed_Y = parent->GetHisto()->GetBinContent(parent->GetHisto()->FindBin(GetX()));
122 
123  switch (event) {
124 
125  case kButton1Down:
126  ndcsav = TestBit(kMarkerNDC);
127  if (!opaque) {
128  gVirtualX->SetTextColor(-1); // invalidate current text color (use xor mode)
129  TAttMarker::Modify(); //Change marker attributes only if necessary
130  }
131  // No break !!!
132 
133  case kMouseMotion:
134  pxold = px;
135  pyold = py;
136  gPad->SetCursor(kMove);
137  break;
138 
139  case kButton1Motion:
140  p.fX = pxold;
141  p.fY = pyold;
142  if (!opaque) gVirtualX->DrawPolyMarker(1, &p);
143  p.fX = px;
144  p.fY = py;
145  if (!opaque) gVirtualX->DrawPolyMarker(1, &p);
146  pxold = px;
147  pyold = py;
148  if (opaque) {
149  if (ndcsav) SetNDC(kFALSE);
150  auto x = gPad->PadtoX(gPad->AbsPixeltoX(px));
151  if (CheckPosition(x)) SetX(x);
152  SetY(fixed_Y);
153  gPad->ShowGuidelines(this, event, 'i', true);
154  gPad->Modified(kTRUE);
155  gPad->Update();
156  }
157  break;
158 
159  case kButton1Up:
160  if (opaque) {
161  if (ndcsav && !TestBit(kMarkerNDC)) {
162  auto x = (fX - gPad->GetX1()) / (gPad->GetX2() - gPad->GetX1());
163  if (CheckPosition(x)) SetX(x);
164  SetY(fixed_Y);
165  SetNDC();
166  }
167  gPad->ShowGuidelines(this, event);
168  }
169  else {
170  if (TestBit(kMarkerNDC)) {
171  dpx = gPad->GetX2() - gPad->GetX1();
172  dpy = gPad->GetY2() - gPad->GetY1();
173  xp1 = gPad->GetX1();
174  yp1 = gPad->GetY1();
175  auto x = (gPad->AbsPixeltoX(pxold) - xp1) / dpx;
176  if (CheckPosition(x)) SetX(x);
177  SetY(fixed_Y);
178  }
179  else {
180  auto x = gPad->PadtoX(gPad->AbsPixeltoX(px));
181  if (CheckPosition(x)) SetX(x);
182  SetY(fixed_Y);
183  }
184  gPad->Modified(kTRUE);
185  gPad->Update();
186  gVirtualX->SetTextColor(-1);
187  }
188  break;
189  }
190 
191  if (GetX() != pid) {
192  // marker has been moved
193  pid = GetX();
194  // update PID value in mass interval
195  parent->GetInterval()->SetPID(pid);
196  // signal that something has changed
197  parent->IntMod();
198  }
199 }
200 
201 
202 
207 
209 {
210  // overridden Paint() method, to display label next to marker
211  //
212  // when fDisplayLabel=true, we draw the label defined for the PID range just next to the marker
213 
214  TMarker::Paint(option);
215  if (fDrawLabel) {
216  fLabel.SetX(GetX());
217  fLabel.SetY(GetY());
218  fLabel.Paint(option);
219  }
220 }
221 
222 
223 
225 
227 {
228  fHighlight = hi;
229  if (hi) {
230  SetMarkerSize(1);
232  fLabel.SetTextColor(kBlack);
233  }
234  else {
235  SetMarkerSize(1);
236  SetMarkerColor(def_color);
237  fLabel.SetTextColor(def_color);
238  }
239 }
240 
241 
242 
245 
247 {
248  // update Z, A, and position of PID marker
249  double fixed_Y = parent->GetHisto()->GetBinContent(parent->GetHisto()->FindBin(pid));
250  SetX(pid);
251  SetY(fixed_Y);
252  fLabel.SetText(GetX(), GetY(), Form(" (%d,%d)", z, a));
253 }
254 
255 
256 
258 
260 {
261  if (pid < parent->GetHistoXAxisLowerLimit() || pid > parent->GetHistoXAxisUpperLimit())
262  return;
263 
264  if (!gPad) return;
265 
266  double fixed_Y1 = parent->GetCanvas()->GetFrame()->GetY1();
267  double fixed_Y2 = parent->GetCanvas()->GetFrame()->GetY2();
268  if (parent->GetCanvas()->GetLogy()) {
269  fixed_Y1 = TMath::Exp(fixed_Y1 * TMath::Log(10));
270  fixed_Y2 = TMath::Exp(fixed_Y2 * TMath::Log(10));
271  }
272 
273  Int_t kMaxDiff = 20;
274  static Int_t d1, d2, px1, px2, py1, py2;
275  static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
276  static Double_t oldX1, oldY1, oldX2, oldY2;
277  static Bool_t p1, p2, pL, ndcsav;
278  Double_t dpx, dpy, xp1, yp1;
279  Int_t dx, dy;
280 
281  Bool_t opaque = gPad->OpaqueMoving();
282 
283  if (!gPad->IsEditable()) return;
284 
285  switch (event) {
286 
287  case kArrowKeyPress:
288  case kButton1Down:
289  oldX1 = GetX1();
290  oldY1 = GetY1();
291  oldX2 = GetX2();
292  oldY2 = GetY2();
293  ndcsav = TestBit(kLineNDC);
294  if (!opaque) {
295  gVirtualX->SetLineColor(-1);
296  TAttLine::Modify(); //Change line attributes only if necessary
297  }
298 
299  // No break !!!
300 
301  case kMouseMotion:
302 
303  if (TestBit(kLineNDC)) {
304  px1 = gPad->UtoPixel(GetX1());
305  py1 = gPad->VtoPixel(GetY1());
306  px2 = gPad->UtoPixel(GetX2());
307  py2 = gPad->VtoPixel(GetY2());
308  }
309  else {
310  px1 = gPad->XtoAbsPixel(gPad->XtoPad(GetX1()));
311  py1 = gPad->YtoAbsPixel(gPad->YtoPad(GetY1()));
312  px2 = gPad->XtoAbsPixel(gPad->XtoPad(GetX2()));
313  py2 = gPad->YtoAbsPixel(gPad->YtoPad(GetY2()));
314  }
315  p1 = p2 = pL = kFALSE;
316 
317  d1 = abs(px1 - px) + abs(py1 - py); //simply take sum of pixels differences
318  if (d1 < kMaxDiff) { //*-*================>OK take point number 1
319  px1old = px1;
320  py1old = py1;
321  p1 = kTRUE;
322  gPad->SetCursor(kPointer);
323  return;
324  }
325  d2 = abs(px2 - px) + abs(py2 - py); //simply take sum of pixels differences
326  if (d2 < kMaxDiff) { //*-*================>OK take point number 2
327  px2old = px2;
328  py2old = py2;
329  p2 = kTRUE;
330  gPad->SetCursor(kPointer);
331  return;
332  }
333 
334  pL = kTRUE;
335  pxold = px;
336  pyold = py;
337  gPad->SetCursor(kMove);
338 
339  break;
340 
341  case kArrowKeyRelease:
342  case kButton1Motion:
343 
344  if (p1) {
345  if (!opaque) {
346  gVirtualX->DrawLine(px1old, py1old, px2, py2);
347  gVirtualX->DrawLine(px, py, px2, py2);
348  }
349  else {
350  if (ndcsav) {
351  SetNDC(kFALSE);
352  auto x = gPad->GetX1() + oldX2 * (gPad->GetX2() - gPad->GetX1());
353  if (CheckPosition(x)) SetX(x);
354  SetY2(fixed_Y2);
355  }
356  //SetX1(GetX2());
357  SetY1(fixed_Y1);
358  }
359  px1old = px;
360  py1old = py;
361  }
362  if (p2) {
363  if (!opaque) {
364  gVirtualX->DrawLine(px1, py1, px2old, py2old);
365  gVirtualX->DrawLine(px1, py1, px, py);
366  }
367  else {
368  if (ndcsav) {
369  SetNDC(kFALSE);
370  auto x = gPad->GetX1() + oldX1 * (gPad->GetX2() - gPad->GetX1());
371  if (CheckPosition(x)) SetX(x);
372  SetY1(fixed_Y1);
373  }
374  //SetX2(GetX1());
375  SetY2(fixed_Y2);
376  }
377  px2old = px;
378  py2old = py;
379  }
380  if (pL) {
381  if (!opaque) gVirtualX->DrawLine(px1, py1, px2, py2);
382  dx = px - pxold;
383  dy = py - pyold;
384  px1 += dx;
385  py1 += dy;
386  px2 += dx;
387  py2 += dy;
388  if (!opaque) gVirtualX->DrawLine(px1, py1, px2, py2);
389  pxold = px;
390  pyold = py;
391  if (opaque) {
392  if (ndcsav) SetNDC(kFALSE);
393  auto x = gPad->AbsPixeltoX(px1);
394  if (CheckPosition(x)) SetX(x);
395  SetY1(fixed_Y1);
396  //SetX2(GetX1());
397  SetY2(fixed_Y2);
398  }
399  }
400  if (opaque) {
401  if (p1) {
402  //check in which corner the BBox is edited
403  if (GetX1() > GetX2()) {
404  if (GetY1() > GetY2())
405  gPad->ShowGuidelines(this, event, '2', true);
406  else
407  gPad->ShowGuidelines(this, event, '3', true);
408  }
409  else {
410  if (GetY1() > GetY2())
411  gPad->ShowGuidelines(this, event, '1', true);
412  else
413  gPad->ShowGuidelines(this, event, '4', true);
414  }
415  }
416  if (p2) {
417  //check in which corner the BBox is edited
418  if (GetX1() > GetX2()) {
419  if (GetY1() > GetY2())
420  gPad->ShowGuidelines(this, event, '4', true);
421  else
422  gPad->ShowGuidelines(this, event, '1', true);
423  }
424  else {
425  if (GetY1() > GetY2())
426  gPad->ShowGuidelines(this, event, '3', true);
427  else
428  gPad->ShowGuidelines(this, event, '2', true);
429  }
430  }
431  if (pL) {
432  gPad->ShowGuidelines(this, event, 'i', true);
433  }
434  gPad->Modified(kTRUE);
435  gPad->Update();
436  }
437  break;
438 
439  case kButton1Up:
440 
441  if (gROOT->IsEscaped()) {
442  gROOT->SetEscape(kFALSE);
443  if (opaque) {
444  SetX(oldX1);
445  SetY1(fixed_Y1);
446  //SetX2(GetX1());
447  SetY2(fixed_Y2);
448  gPad->Modified(kTRUE);
449  gPad->Update();
450  }
451  break;
452  }
453  if (opaque) {
454  if (ndcsav && !TestBit(kLineNDC)) {
455  auto x = ((GetX1() - gPad->GetX1()) / (gPad->GetX2() - gPad->GetX1()));
456  if (CheckPosition(x)) SetX(x);
457  //SetX2(GetX1());
458  SetY1(fixed_Y1);
459  SetY2(fixed_Y2);
460  SetNDC();
461  }
462  gPad->ShowGuidelines(this, event);
463  }
464  else {
465  if (TestBit(kLineNDC)) {
466  dpx = gPad->GetX2() - gPad->GetX1();
467  dpy = gPad->GetY2() - gPad->GetY1();
468  xp1 = gPad->GetX1();
469  yp1 = gPad->GetY1();
470  if (p1) {
471  auto x = (gPad->AbsPixeltoX(px) - xp1) / dpx;
472  if (CheckPosition(x)) SetX(x);
473  //SetX2(GetX1());
474  SetY1(fixed_Y1);
475  }
476  if (p2) {
477  auto x = ((gPad->AbsPixeltoX(px) - xp1) / dpx);
478  if (CheckPosition(x)) SetX(x);
479  //SetX1(GetX2());
480  SetY2(fixed_Y2);
481  }
482  if (pL) {
483  auto x = ((gPad->AbsPixeltoX(px1) - xp1) / dpx);
484  if (CheckPosition(x)) SetX(x);
485  SetY1(fixed_Y1);
486  //SetX2(GetX1());
487  SetY2(fixed_Y2);
488  }
489  }
490  else {
491  if (p1) {
492  auto x = (gPad->PadtoX(gPad->AbsPixeltoX(px)));
493  if (CheckPosition(x)) SetX(x);
494  //SetX2(GetX1());
495  SetY1(fixed_Y1);
496  }
497  if (p2) {
498  auto x = (gPad->PadtoX(gPad->AbsPixeltoX(px)));
499  if (CheckPosition(x)) SetX(x);
500  //SetX1(GetX2());
501  SetY2(fixed_Y2);
502  }
503  if (pL) {
504  auto x = (gPad->PadtoX(gPad->AbsPixeltoX(px1)));
505  if (CheckPosition(x)) SetX(x);
506  SetY1(fixed_Y1);
507  //SetX2(GetX1());
508  SetY2(fixed_Y2);
509  }
510  }
511  if (TestBit(kVertical)) {
512  if (p1) SetX2(GetX1());
513  if (p2) SetX1(GetX2());
514  }
515  if (TestBit(kHorizontal)) {
516  if (p1) SetY2(fixed_Y1);
517  if (p2) SetY1(fixed_Y2);
518  }
519  gPad->Modified(kTRUE);
520  gPad->Update();
521  if (!opaque) gVirtualX->SetLineColor(-1);
522  }
523  break;
524 
525  case kButton1Locate:
526 
527  ExecuteEvent(kButton1Down, px, py);
528  while (1) {
529  px = py = 0;
530  event = gVirtualX->RequestLocator(1, 1, px, py);
531 
532  ExecuteEvent(kButton1Motion, px, py);
533 
534  if (event != -1) { // button is released
535  ExecuteEvent(kButton1Up, px, py);
536  return;
537  }
538  }
539  }
540 }
541 
542 
543 
545 
547 {
548  fHighlight = hi;
549  if (hi) {
550  SetLineWidth(3);
552  }
553  else {
554  SetLineWidth(2);
555  SetLineColor(def_color);
556  }
557 }
558 
559 
560 
562 
564 {
565  if (pid < parent->GetHistoXAxisLowerLimit() || pid > parent->GetHistoXAxisUpperLimit())
566  return;
567 
568  double fixed_Y1 = parent->GetCanvas()->GetFrame()->GetY1();
569  double fixed_Y2 = parent->GetCanvas()->GetFrame()->GetY2();
570  if (parent->GetCanvas()->GetLogy()) {
571  fixed_Y1 = TMath::Exp(fixed_Y1 * TMath::Log(10));
572  fixed_Y2 = TMath::Exp(fixed_Y2 * TMath::Log(10));
573  }
574  SetY1(fixed_Y1);
575  SetY2(fixed_Y2);
576  TLine::Paint(option);
577 }
578 
579 
580 
586 
588 {
589  // make sure that lower limit < PID marker < upper limit
590  //
591  // also, both limits must be > than the upper limit of the PID interval to our left (if it exists),
592  // and also < the lower limit of the PID interval to our right (if it exists)
593 
594  bool ok;
595  if (type == limit_t::lower) {
596  ok = (x < parent->GetPIDPosition()) && (x < parent->GetPIDIntervalUpperLimit());
597  }
598  else {
599  ok = (x > parent->GetPIDPosition()) && (x > parent->GetPIDIntervalLowerLimit());
600  }
601  if (!ok) return false;
602  bool ok_left = parent->get_left_interval() ?
603  x > parent->get_left_interval()->GetPIDIntervalUpperLimit() : true;
604  bool ok_right = parent->get_right_interval() ?
605  x < parent->get_right_interval()->GetPIDIntervalLowerLimit() : true;
606  return (ok && ok_left && ok_right);
607 }
608 
609 
kMouseMotion
kArrowKeyRelease
kButton1Motion
kButton1Up
kArrowKeyPress
kButton1Down
kButton1Locate
int Int_t
kMove
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
const Bool_t kFALSE
bool Bool_t
double Double_t
short Color_t
const Bool_t kTRUE
const char Option_t
kBlack
int type
float type_of_call hi(const int &, const int &)
#define gROOT
char * Form(const char *fmt,...)
#define gPad
#define gVirtualX
void ExecuteEvent(Int_t event, Int_t px, Int_t py)
void Update(int z, int a, double pid)
update Z, A, and position of PID marker
void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Graphical representation of a PID interval in the KVIDZAFromZGrid mass assignation GUI.
Double_t GetHistoXAxisLowerLimit() const
double GetPIDIntervalUpperLimit() const
void Draw(Option_t *option="")
pid_line fLine1
represents lower limit of PID for interval
pid_marker fMarker
represents position of PID for interval
void HighLight(bool hi=true)
pid_line fLine2
represents upper limit of PID for interval
virtual void Modify()
virtual void Modify()
virtual void SetMarkerColor(Color_t mcolor=1)
virtual void SetTextAlign(Short_t align=11)
virtual void SetTextColor(Color_t tcolor=1)
virtual void SetTextFont(Font_t tfont=62)
virtual void SetTextSize(Float_t tsize=1)
void Update() override
virtual void Paint(Option_t *option="")
TObject * Remove(const TObjLinkPtr_t &lnk)
virtual void Paint(Option_t *option="")
virtual void SetTitle(const char *title="")
virtual void SetName(const char *name)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
void Modified(Bool_t flag=1) override
TList * GetListOfPrimitives() const override
SCoord_t fY
SCoord_t fX
double GetPID()
double GetPIDmin()
double GetPIDmax()
Double_t x[n]
gr SetMarkerSize(1.3)
gr SetLineWidth(2)
kPointer
TH1 * GetHisto(const std::string file, const std::string path, const std::string obj)
Double_t Exp(Double_t x)
Double_t Log(Double_t x)
lv SetLineColor(kBlue)
m SetMarkerColor(kBlue)
auto * a